|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r69569 - in trunk/boost/geometry: algorithms algorithms/detail/overlay extensions/gis/io/wkt multi/algorithms
From: barend.gehrels_at_[hidden]
Date: 2011-03-04 16:39:34
Author: barendgehrels
Date: 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
New Revision: 69569
URL: http://svn.boost.org/trac/boost/changeset/69569
Log:
Implemented/fixed behaviour for empty polygons in intersections
Simplified reversal
Implemented transform for segment,multi_point,multi_linestring
Implemented wkt for segment
Removed:
trunk/boost/geometry/algorithms/detail/overlay/add_to_containment.hpp
trunk/boost/geometry/algorithms/detail/overlay/assemble.hpp
Text files modified:
trunk/boost/geometry/algorithms/detail/overlay/overlay.hpp | 74 +++++++++++++++++++++++++--------------
trunk/boost/geometry/algorithms/detail/overlay/select_rings.hpp | 12 ++++-
trunk/boost/geometry/algorithms/difference.hpp | 2
trunk/boost/geometry/algorithms/intersection_inserter.hpp | 20 +++++----
trunk/boost/geometry/algorithms/sym_difference.hpp | 4 +-
trunk/boost/geometry/algorithms/transform.hpp | 36 ++++++++++++++++++-
trunk/boost/geometry/algorithms/union.hpp | 17 ++++----
trunk/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp | 36 +++++++++++++++++++
trunk/boost/geometry/multi/algorithms/transform.hpp | 17 +++++---
9 files changed, 159 insertions(+), 59 deletions(-)
Deleted: trunk/boost/geometry/algorithms/detail/overlay/add_to_containment.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/add_to_containment.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
+++ (empty file)
@@ -1 +0,0 @@
-//obsolete
\ No newline at end of file
Deleted: trunk/boost/geometry/algorithms/detail/overlay/assemble.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/assemble.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
+++ (empty file)
@@ -1 +0,0 @@
-//obsolete
\ No newline at end of file
Modified: trunk/boost/geometry/algorithms/detail/overlay/overlay.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/overlay.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/overlay.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
//
-// Copyright Barend Gehrels 2007-2010, Geodan, Amsterdam, the Netherlands.
+// Copyright Barend Gehrels 2007-2011, Geodan, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -49,7 +49,6 @@
namespace detail { namespace overlay
{
-
// Skip for assemble process
template <typename TurnInfo>
inline bool skip(TurnInfo const& turn_info)
@@ -61,8 +60,6 @@
}
-
-
template <typename TurnPoints, typename Map>
inline void map_turns(Map& map, TurnPoints const& turn_points)
{
@@ -96,6 +93,40 @@
}
+template
+<
+ typename GeometryOut, overlay_type Direction, bool ReverseOut,
+ typename Geometry1, typename Geometry2,
+ typename OutputIterator
+>
+inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ OutputIterator out)
+{
+ typedef typename geometry::range_type<GeometryOut>::type ring_type;
+ typedef std::deque<ring_type> ring_container_type;
+
+ typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
+
+ // Union: return either of them
+ // Intersection: return nothing
+ // Difference: return first of them
+ if (Direction == overlay_intersection
+ || (Direction == overlay_difference
+ && geometry::num_points(geometry1) == 0))
+ {
+ return out;
+ }
+
+ std::map<ring_identifier, int> empty;
+ std::map<ring_identifier, properties> all_of_one_of_them;
+
+ select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them);
+ ring_container_type rings;
+ assign_parents(geometry1, geometry2, rings, all_of_one_of_them);
+ return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out);
+}
+
template
<
@@ -122,25 +153,19 @@
typedef std::deque<turn_info> container_type;
// "Use" rangetype for ringtype:
- // for polygon, it is the type of the exterior ring.
- // for ring, it is the ring itself. That is what is
- // for multi-polygon, it is also the type of the ring.
+ // -> for polygon, it is the type of the exterior ring.
+ // -> for ring, it is the ring itself.
+ // -> for multi-polygon, it is also the type of the ring.
typedef typename geometry::range_type<GeometryOut>::type ring_type;
typedef std::deque<ring_type> ring_container_type;
- // If one input is empty, output the other one for a union.
- // For an intersection, the intersection is empty.
- // TODO: for a difference, take one of them.
if (geometry::num_points(geometry1) == 0
|| geometry::num_points(geometry2) == 0)
{
- if (Direction == overlay_union)
- {
- std::map<ring_identifier, int> map;
- ring_container_type rings;
- ////return assemble<GeometryOut>(rings, map, geometry1, geometry2, Direction, false, false, out);
- }
- return out;
+ return return_if_one_input_is_empty
+ <
+ GeometryOut, Direction, ReverseOut
+ >(geometry1, geometry2, out);
}
container_type turn_points;
@@ -177,7 +202,7 @@
turn_points, rings);
// TEMP condition, reversal should be done in traverse by calling "push_front"
- if (ReverseOut && (Reverse1 || Reverse2))
+ if (ReverseOut)
{
for (typename boost::range_iterator<ring_container_type>::type
it = boost::begin(rings);
@@ -191,15 +216,13 @@
std::map<ring_identifier, int> map;
map_turns(map, turn_points);
- //return assemble<GeometryOut>(rings, map, geometry1, geometry2, Direction, false, false, out);
- typedef ring_properties<typename geometry::point_type<Geometry1>::type> info;
-
- std::map<ring_identifier, info> selected;
+ typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
+ std::map<ring_identifier, properties> selected;
select_rings<Direction>(geometry1, geometry2, map, selected);
- // Add rings from container
+ // Add rings from intersection container
{
ring_identifier id(2, 0, -1);
for (typename boost::range_iterator<ring_container_type>::type
@@ -207,20 +230,19 @@
it != boost::end(rings);
++it)
{
- selected[id] = info(*it);
+ selected[id] = properties(*it);
id.multi_index++;
}
}
assign_parents(geometry1, geometry2, rings, selected);
return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
-
}
};
// Metafunction helper for intersection and union
-template <order_selector Selector, bool Reverse>
+template <order_selector Selector, bool Reverse = false>
struct do_reverse {};
template <>
Modified: trunk/boost/geometry/algorithms/detail/overlay/select_rings.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/select_rings.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/select_rings.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
//
-// Copyright Barend Gehrels 2007-2010, Geodan, Amsterdam, the Netherlands.
+// Copyright Barend Gehrels 2011, Amsterdam, the Netherlands.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -57,13 +57,19 @@
template <typename Geometry, typename Map>
static inline void apply(Ring const& ring, Geometry const& geometry, ring_identifier const& id, Map& map)
{
- map[id] = typename Map::mapped_type(ring, geometry);
+ if (boost::size(ring) > 0)
+ {
+ map[id] = typename Map::mapped_type(ring, geometry);
+ }
}
template <typename Map>
static inline void apply(Ring const& ring, ring_identifier const& id, Map& map)
{
- map[id] = typename Map::mapped_type(ring);
+ if (boost::size(ring) > 0)
+ {
+ map[id] = typename Map::mapped_type(ring);
+ }
}
};
Modified: trunk/boost/geometry/algorithms/difference.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/difference.hpp (original)
+++ trunk/boost/geometry/algorithms/difference.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -50,7 +50,7 @@
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- return detail::intersection::inserter<GeometryOut, false, true, false, overlay_difference>(
+ return detail::intersection::inserter<GeometryOut, true, overlay_difference>(
geometry1, geometry2,
out,
strategy);
Modified: trunk/boost/geometry/algorithms/intersection_inserter.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/intersection_inserter.hpp (original)
+++ trunk/boost/geometry/algorithms/intersection_inserter.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -339,7 +339,7 @@
template
<
typename GeometryOut,
- bool Reverse1, bool Reverse2, bool ReverseOut,
+ bool ReverseSecond,
overlay_type OverlayType,
typename Geometry1, typename Geometry2,
typename OutputIterator,
@@ -362,9 +362,9 @@
geometry::is_areal<Geometry2>::value,
geometry::is_areal<GeometryOut>::value,
Geometry1, Geometry2,
- overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
- overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
- ReverseOut,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
OutputIterator, GeometryOut,
OverlayType,
Strategy
@@ -378,9 +378,9 @@
geometry::is_areal<Geometry2>::value,
geometry::is_areal<GeometryOut>::value,
Geometry1, Geometry2,
- overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
- overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
- ReverseOut,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
OutputIterator, GeometryOut,
OverlayType,
Strategy
@@ -427,8 +427,10 @@
concept::check<Geometry1 const>();
concept::check<Geometry2 const>();
- return detail::intersection::inserter<GeometryOut, false, false, true, overlay_intersection>(
- geometry1, geometry2, out, strategy);
+ return detail::intersection::inserter
+ <
+ GeometryOut, false, overlay_intersection
+ >(geometry1, geometry2, out, strategy);
}
Modified: trunk/boost/geometry/algorithms/sym_difference.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/sym_difference.hpp (original)
+++ trunk/boost/geometry/algorithms/sym_difference.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -51,9 +51,9 @@
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- out = detail::intersection::inserter<GeometryOut, false, true, false, overlay_difference>(
+ out = detail::intersection::inserter<GeometryOut, true, overlay_difference>(
geometry1, geometry2, out, strategy);
- out = detail::intersection::inserter<GeometryOut, false, true, false, overlay_difference>(
+ out = detail::intersection::inserter<GeometryOut, true, overlay_difference>(
geometry2, geometry1, out, strategy);
return out;
}
Modified: trunk/boost/geometry/algorithms/transform.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/transform.hpp (original)
+++ trunk/boost/geometry/algorithms/transform.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -24,6 +24,7 @@
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/mutable_range.hpp>
#include <boost/geometry/core/ring_type.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/transform.hpp>
@@ -85,6 +86,31 @@
}
};
+template <typename Geometry1, typename Geometry2, typename Strategy>
+struct transform_box_or_segment
+{
+ static inline bool apply(Geometry1 const& source, Geometry2& target,
+ Strategy const& strategy)
+ {
+ typedef typename point_type<Geometry1>::type point_type1;
+ typedef typename point_type<Geometry2>::type point_type2;
+
+ point_type1 source_point[2];
+ assign_point_from_index<0>(source, source_point[0]);
+ assign_point_from_index<1>(source, source_point[1]);
+
+ point_type2 target_point[2];
+ if (strategy.apply(source_point[0], target_point[0])
+ && strategy.apply(source_point[1], target_point[1]))
+ {
+ assign_point_to_index<0>(target_point[0], target);
+ assign_point_to_index<1>(target_point[1], target);
+ return true;
+ }
+ return false;
+ }
+};
+
template
<
@@ -246,6 +272,12 @@
{
};
+template <typename Segment1, typename Segment2, typename Strategy>
+struct transform<segment_tag, segment_tag, Segment1, Segment2, Strategy>
+ : detail::transform::transform_box_or_segment<Segment1, Segment2, Strategy>
+{
+};
+
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
@@ -270,8 +302,8 @@
typedef dispatch::transform
<
- typename tag<Geometry1>::type,
- typename tag<Geometry2>::type,
+ typename tag_cast<typename tag<Geometry1>::type, multi_tag>::type,
+ typename tag_cast<typename tag<Geometry2>::type, multi_tag>::type,
Geometry1,
Geometry2,
Strategy
Modified: trunk/boost/geometry/algorithms/union.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/union.hpp (original)
+++ trunk/boost/geometry/algorithms/union.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -111,8 +111,7 @@
template
<
- typename GeometryOut,
- bool Reverse1, bool Reverse2, bool ReverseOut,
+ typename GeometryOut,
typename Geometry1, typename Geometry2,
typename OutputIterator,
typename Strategy
@@ -134,9 +133,9 @@
geometry::is_areal<Geometry2>::value,
geometry::is_areal<GeometryOut>::value,
Geometry1, Geometry2,
- overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
- overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
- ReverseOut,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
OutputIterator, GeometryOut,
Strategy
>,
@@ -149,9 +148,9 @@
geometry::is_areal<Geometry2>::value,
geometry::is_areal<GeometryOut>::value,
Geometry1, Geometry2,
- overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
- overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
- ReverseOut,
+ overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
+ overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
+ overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
OutputIterator, GeometryOut,
Strategy
>
@@ -197,7 +196,7 @@
concept::check<Geometry2 const>();
concept::check<GeometryOut>();
- return detail::union_::inserter<GeometryOut, false, false, true>(geometry1, geometry2, out, strategy);
+ return detail::union_::inserter<GeometryOut>(geometry1, geometry2, out, strategy);
}
/*!
Modified: trunk/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp
==============================================================================
--- trunk/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp (original)
+++ trunk/boost/geometry/extensions/gis/io/wkt/write_wkt.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -11,11 +11,13 @@
#include <ostream>
#include <string>
+#include <boost/array.hpp>
#include <boost/concept/assert.hpp>
#include <boost/range.hpp>
#include <boost/typeof/typeof.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
@@ -206,6 +208,35 @@
}
};
+
+template <typename Segment>
+struct wkt_segment
+{
+ typedef typename point_type<Segment>::type point_type;
+
+ template <typename Char, typename Traits>
+ static inline void apply(std::basic_ostream<Char, Traits>& os,
+ Segment const& segment)
+ {
+ // Convert to two points, then stream
+ typedef boost::array<point_type, 2> sequence;
+
+ sequence points;
+ assign_point_from_index<0>(segment, points[0]);
+ assign_point_from_index<1>(segment, points[1]);
+
+ // In Boost.Geometry a segment is represented
+ // in WKT-format like (for 2D): LINESTRING(x y,x y)
+ os << "LINESTRING";
+ wkt_sequence<sequence>::apply(os, points);
+ }
+
+ private:
+
+ inline wkt_segment()
+ {}
+};
+
}} // namespace detail::wkt
#endif // DOXYGEN_NO_DETAIL
@@ -256,6 +287,11 @@
: detail::wkt::wkt_box<Box>
{};
+template <typename Segment>
+struct wkt<segment_tag, Segment>
+ : detail::wkt::wkt_segment<Segment>
+{};
+
/*!
\brief Specialization to stream a ring as WKT
Modified: trunk/boost/geometry/multi/algorithms/transform.hpp
==============================================================================
--- trunk/boost/geometry/multi/algorithms/transform.hpp (original)
+++ trunk/boost/geometry/multi/algorithms/transform.hpp 2011-03-04 16:39:30 EST (Fri, 04 Mar 2011)
@@ -52,8 +52,6 @@
};
-
-
}} // namespace detail::transform
#endif // DOXYGEN_NO_DETAIL
@@ -62,11 +60,10 @@
namespace dispatch
{
-
template <typename Multi1, typename Multi2, typename Strategy>
struct transform
<
- multi_polygon_tag, multi_polygon_tag,
+ multi_tag, multi_tag,
Multi1, Multi2,
Strategy
>
@@ -74,8 +71,16 @@
<
Multi1,
Multi2,
- detail::transform::transform_polygon
+ transform
<
+ typename single_tag_of
+ <
+ typename tag<Multi1>::type
+ >::type,
+ typename single_tag_of
+ <
+ typename tag<Multi2>::type
+ >::type,
typename boost::range_value<Multi1>::type,
typename boost::range_value<Multi2>::type,
Strategy
@@ -83,8 +88,6 @@
>
{};
-
-
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk