Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r69517 - trunk/boost/geometry/algorithms/detail/overlay
From: barend.gehrels_at_[hidden]
Date: 2011-03-03 11:13:54


Author: barendgehrels
Date: 2011-03-03 11:13:52 EST (Thu, 03 Mar 2011)
New Revision: 69517
URL: http://svn.boost.org/trac/boost/changeset/69517

Log:
Fixed behaviour of new approach for dissolve
Text files modified:
   trunk/boost/geometry/algorithms/detail/overlay/add_rings.hpp | 24 +++++++
   trunk/boost/geometry/algorithms/detail/overlay/assign_parents.hpp | 45 +++++++++++++-
   trunk/boost/geometry/algorithms/detail/overlay/ring_properties.hpp | 8 +
   trunk/boost/geometry/algorithms/detail/overlay/select_rings.hpp | 122 +++++++++++++++++++++++++--------------
   4 files changed, 147 insertions(+), 52 deletions(-)

Modified: trunk/boost/geometry/algorithms/detail/overlay/add_rings.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/add_rings.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/add_rings.hpp 2011-03-03 11:13:52 EST (Thu, 03 Mar 2011)
@@ -77,7 +77,8 @@
         it != boost::end(map);
         ++it)
     {
- if (it->second.parent.source_index == -1)
+ if (! it->second.discarded
+ && it->second.parent.source_index == -1)
         {
             GeometryOut result;
             convert_and_add(result, geometry1, geometry2, collection,
@@ -90,7 +91,8 @@
                 ++child_it)
             {
                 iterator mit = map.find(*child_it);
- if (mit != map.end())
+ if (mit != map.end()
+ && ! mit->second.discarded)
                 {
                     convert_and_add(result, geometry1, geometry2, collection,
                             *child_it, mit->second.reversed, true);
@@ -103,6 +105,24 @@
 }
 
 
+template
+<
+ typename GeometryOut,
+ typename SelectionMap,
+ typename Geometry,
+ typename RingCollection,
+ typename OutputIterator
+>
+inline OutputIterator add_rings(SelectionMap const& map,
+ Geometry const& geometry,
+ RingCollection const& collection,
+ OutputIterator out)
+{
+ Geometry empty;
+ return add_rings<GeometryOut>(map, geometry, empty, collection, out);
+}
+
+
 }} // namespace detail::overlay
 #endif // DOXYGEN_NO_DETAIL
 

Modified: trunk/boost/geometry/algorithms/detail/overlay/assign_parents.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/assign_parents.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/assign_parents.hpp 2011-03-03 11:13:52 EST (Thu, 03 Mar 2011)
@@ -95,7 +95,8 @@
 inline void assign_parents(Geometry1 const& geometry1,
             Geometry2 const& geometry2,
             RingCollection const& collection,
- RingMap& ring_map)
+ RingMap& ring_map,
+ bool check_for_orientation = false)
 {
     typedef typename geometry::tag<Geometry1>::type tag1;
     typedef typename geometry::tag<Geometry2>::type tag2;
@@ -119,15 +120,15 @@
             switch(it->first.source_index)
             {
                 case 0 :
- geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
+ geometry::envelope(get_ring<tag1>::apply(it->first, geometry1),
                             vector.back().envelope);
                     break;
                 case 1 :
- geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
+ geometry::envelope(get_ring<tag2>::apply(it->first, geometry2),
                             vector.back().envelope);
                     break;
                 case 2 :
- geometry::envelope(get_ring<void>::apply(it->first, collection),
+ geometry::envelope(get_ring<void>::apply(it->first, collection),
                             vector.back().envelope);
                     break;
             }
@@ -149,7 +150,7 @@
                 {
                     ring_info_type& inner = ring_map[inn_it->id];
 
- if (inner.get_area() < 0
+ if ( (inner.get_area() < 0 || check_for_orientation)
                         && geometry::within(inner.point, out_it->envelope)
                         && contains(out_it->id, outer, inner, geometry1, geometry2, collection))
                     {
@@ -160,6 +161,24 @@
         }
     }
 
+ if (check_for_orientation)
+ {
+ for (map_iterator_type it = boost::begin(ring_map); it != boost::end(ring_map); ++it)
+ {
+ if (it->second.parent.source_index >= 0 && it->second.get_area() > 0)
+ {
+ // Discard positive inner ring with parent
+ it->second.discarded = true;
+ it->second.parent.source_index = -1;
+ }
+ else if (it->second.parent.source_index < 0 && it->second.get_area() < 0)
+ {
+ // Reverse negative ring without parent
+ it->second.reversed = true;
+ }
+ }
+ }
+
     // Assign childlist
     for (map_iterator_type it = boost::begin(ring_map); it != boost::end(ring_map); ++it)
     {
@@ -168,7 +187,23 @@
             ring_map[it->second.parent].children.push_back(it->first);
         }
     }
+}
+
+template
+<
+ typename Geometry,
+ typename RingCollection,
+ typename RingMap
+>
+inline void assign_parents(Geometry const& geometry,
+ RingCollection const& collection,
+ RingMap& ring_map)
+{
+ // Call it with an empty geometry
+ // (ring_map should be empty for source_id==1)
 
+ Geometry empty;
+ assign_parents(geometry, empty, collection, ring_map, true);
 }
 
 

Modified: trunk/boost/geometry/algorithms/detail/overlay/ring_properties.hpp
==============================================================================
--- trunk/boost/geometry/algorithms/detail/overlay/ring_properties.hpp (original)
+++ trunk/boost/geometry/algorithms/detail/overlay/ring_properties.hpp 2011-03-03 11:13:52 EST (Thu, 03 Mar 2011)
@@ -34,6 +34,7 @@
 
     int within_code;
     bool reversed;
+ bool discarded;
 
     // Filled/used by "assign_rings"
     ring_identifier parent;
@@ -41,14 +42,16 @@
 
     inline ring_properties()
         : area(area_type())
- , within_code(0)
+ , within_code(-1)
         , reversed(false)
+ , discarded(false)
     {}
 
     template <typename RingOrBox>
     inline ring_properties(RingOrBox const& ring_or_box)
- : within_code(0)
+ : within_code(-1)
         , reversed(false)
+ , discarded(false)
     {
         this->area = geometry::area(ring_or_box);
         geometry::point_on_border(this->point, ring_or_box, true);
@@ -57,6 +60,7 @@
     template <typename RingOrBox, typename Geometry>
     inline ring_properties(RingOrBox const& ring_or_box, Geometry const& geometry)
         : reversed(false)
+ , discarded(false)
     {
         this->area = geometry::area(ring_or_box);
         geometry::point_on_border(this->point, ring_or_box, true);

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-03 11:13:52 EST (Thu, 03 Mar 2011)
@@ -8,10 +8,8 @@
 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_SELECT_RINGS_HPP
 
+#include <map>
 
-#include <vector>
-
-#include <boost/range.hpp>
 
 #include <boost/geometry/algorithms/area.hpp>
 #include <boost/geometry/algorithms/within.hpp>
@@ -30,7 +28,6 @@
 {
 
 
-
 namespace dispatch
 {
 
@@ -44,8 +41,13 @@
         template <typename Geometry, typename Map>
         static inline void apply(Box const& box, Geometry const& geometry, ring_identifier const& id, Map& map)
         {
- typedef typename Map::mapped_type info;
- map[id] = info(box, geometry);
+ map[id] = typename Map::mapped_type(box, geometry);
+ }
+
+ template <typename Map>
+ static inline void apply(Box const& box, ring_identifier const& id, Map& map)
+ {
+ map[id] = typename Map::mapped_type(box);
         }
     };
 
@@ -55,10 +57,13 @@
         template <typename Geometry, typename Map>
         static inline void apply(Ring const& ring, Geometry const& geometry, ring_identifier const& id, Map& map)
         {
- // MAYBE use within-code algorithm (but not important - all these rings should be untouched)
+ map[id] = typename Map::mapped_type(ring, geometry);
+ }
 
- typedef typename Map::mapped_type info;
- map[id] = info(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);
         }
     };
 
@@ -82,6 +87,23 @@
                 per_ring::apply(*it, geometry, id, map);
             }
         }
+
+ template <typename Map>
+ static inline void apply(Polygon const& polygon, ring_identifier id, Map& map)
+ {
+ typedef typename geometry::ring_type<Polygon>::type ring_type;
+ typedef select_rings<ring_tag, ring_type> per_ring;
+
+ per_ring::apply(exterior_ring(polygon), id, map);
+
+ typename interior_return_type<Polygon const>::type rings
+ = interior_rings(polygon);
+ for (BOOST_AUTO(it, boost::begin(rings)); it != boost::end(rings); ++it)
+ {
+ id.ring_index++;
+ per_ring::apply(*it, id, map);
+ }
+ }
     };
 }
 
@@ -98,16 +120,12 @@
     {
         return code.within_code * -1 == 1;
     }
+
     template <typename Code>
     static bool reversed(ring_identifier const& , Code const& )
     {
         return false;
     }
- template <typename Code>
- static std::string reverse(ring_identifier const& , Code const& )
- {
- return "";
- }
 };
 
 template<>
@@ -119,20 +137,12 @@
         bool is_first = id.source_index == 0;
         return code.within_code * -1 * (is_first ? 1 : -1) == 1;
     }
+
     template <typename Code>
     static bool reversed(ring_identifier const& id, Code const& code)
     {
         return include(id, code) && id.source_index == 1;
     }
- template <typename Code>
- static std::string reverse(ring_identifier const& id, Code const& code)
- {
- if (include(id, code) && id.source_index == 1)
- {
- return " REV";
- }
- return "";
- }
 };
 
 template<>
@@ -143,42 +153,28 @@
     {
         return code.within_code * 1 == 1;
     }
+
     template <typename Code>
     static bool reversed(ring_identifier const& , Code const& )
     {
         return false;
     }
- template <typename Code>
- static std::string reverse(ring_identifier const& , Code const& )
- {
- return "";
- }
 };
 
 
-/*!
-\brief The function select_rings select rings based on the overlay-type (union,intersection)
-*/
 template
 <
     overlay_type OverlayType,
- typename Geometry1, typename Geometry2,
     typename IntersectionMap, typename SelectionMap
>
-inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
- IntersectionMap const& intersection_map, SelectionMap& selection_map)
+inline void update_selection_map(IntersectionMap const& intersection_map,
+ SelectionMap const& map_with_all, SelectionMap& selection_map)
 {
- typedef typename geometry::tag<Geometry1>::type tag1;
- typedef typename geometry::tag<Geometry2>::type tag2;
-
- // geometry1 and 2 is a ring, or a (multi)polygon -> dispatch on that
- SelectionMap map_with_all;
- dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2, ring_identifier(0, -1, -1), map_with_all);
- dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1, ring_identifier(1, -1, -1), map_with_all);
-
     selection_map.clear();
 
- for (BOOST_AUTO(it, boost::begin(map_with_all)); it != boost::end(map_with_all); ++it)
+ for (typename SelectionMap::const_iterator it = boost::begin(map_with_all);
+ it != boost::end(map_with_all);
+ ++it)
     {
         /*
         int union_code = it->second.within_code * -1;
@@ -207,6 +203,46 @@
 }
 
 
+/*!
+\brief The function select_rings select rings based on the overlay-type (union,intersection)
+*/
+template
+<
+ overlay_type OverlayType,
+ typename Geometry1, typename Geometry2,
+ typename IntersectionMap, typename SelectionMap
+>
+inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
+ IntersectionMap const& intersection_map, SelectionMap& selection_map)
+{
+ typedef typename geometry::tag<Geometry1>::type tag1;
+ typedef typename geometry::tag<Geometry2>::type tag2;
+
+ SelectionMap map_with_all;
+ dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2, ring_identifier(0, -1, -1), map_with_all);
+ dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1, ring_identifier(1, -1, -1), map_with_all);
+
+ update_selection_map<OverlayType>(intersection_map, map_with_all, selection_map);
+}
+
+template
+<
+ overlay_type OverlayType,
+ typename Geometry,
+ typename IntersectionMap, typename SelectionMap
+>
+inline void select_rings(Geometry const& geometry,
+ IntersectionMap const& intersection_map, SelectionMap& selection_map)
+{
+ typedef typename geometry::tag<Geometry>::type tag;
+
+ SelectionMap map_with_all;
+ dispatch::select_rings<tag, Geometry>::apply(geometry, ring_identifier(0, -1, -1), map_with_all);
+
+ update_selection_map<OverlayType>(intersection_map, map_with_all, selection_map);
+}
+
+
 }} // namespace detail::overlay
 #endif // DOXYGEN_NO_DETAIL
 


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