Boost logo

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