diff --git a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp index 78160f520..7cc91f726 100644 --- a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp @@ -372,7 +372,7 @@ inline void assign_parents(Geometry1 const& geometry1, } -// Version for one geometry (called by buffer) +// Version for one geometry (called by buffer/dissolve) template < typename Geometry, diff --git a/include/boost/geometry/extensions/algorithms/dissolve.hpp b/include/boost/geometry/extensions/algorithms/dissolve.hpp index ac0bc5a84..6fef44a64 100644 --- a/include/boost/geometry/extensions/algorithms/dissolve.hpp +++ b/include/boost/geometry/extensions/algorithms/dissolve.hpp @@ -164,108 +164,104 @@ struct dissolve_ring_or_polygon visitor.visit_turns(1, turns); - // The dissolve process is not necessary if there are no turns at all - - if (boost::size(turns) > 0) - { - typedef typename ring_type::type ring_type; - typedef std::vector out_vector; - out_vector rings; - - typedef std::map - < - signed_size_type, - detail::overlay::cluster_info - > cluster_type; - - cluster_type clusters; - - // Enrich/traverse the polygons twice: first for union... - typename Strategy::side_strategy_type const - side_strategy = strategy.get_side_strategy(); - - enrich_intersection_points(turns, - clusters, geometry, geometry, rescale_policy, - side_strategy); - - visitor.visit_turns(2, turns); - - visitor.visit_clusters(clusters, turns); - - std::map turn_info_per_ring; - - detail::overlay::traverse - < - false, false, - Geometry, Geometry, - overlay_dissolve_union, - backtrack_for_dissolve - >::apply(geometry, geometry, - strategy, rescale_policy, - turns, rings, turn_info_per_ring, clusters, visitor); - - visitor.visit_turns(3, turns); - - // ... and then for intersection - clear(turns); - enrich_intersection_points(turns, - clusters, geometry, geometry, rescale_policy, - side_strategy); - - visitor.visit_turns(4, turns); - - detail::overlay::traverse - < - false, false, - Geometry, Geometry, - overlay_dissolve_intersection, - backtrack_for_dissolve - >::apply(geometry, geometry, - strategy, rescale_policy, - turns, rings, turn_info_per_ring, clusters, visitor); - - visitor.visit_turns(5, turns); - - detail::overlay::get_ring_turn_info(turn_info_per_ring, turns, clusters); - - typedef typename geometry::point_type::type point_type; - typedef typename Strategy::template area_strategy - < - point_type - >::type area_strategy_type; - typedef typename area_strategy_type::return_type area_result_type; - typedef detail::overlay::ring_properties properties; - - std::map selected; - - detail::overlay::select_rings(geometry, turn_info_per_ring, selected, strategy); - - // Add intersected rings - { - area_strategy_type const area_strategy = strategy.template get_area_strategy(); - - ring_identifier id(2, 0, -1); - for (typename boost::range_iterator const>::type - it = boost::begin(rings); - it != boost::end(rings); - ++it) - { - selected[id] = properties(*it, area_strategy); - id.multi_index++; - } - } - - detail::overlay::assign_parents(geometry, rings, selected, strategy, true); - return detail::overlay::add_rings(selected, geometry, rings, out); - - } - else + if (boost::size(turns) == 0) { + // No self-turns, then add original geometry GeometryOut g; geometry::convert(geometry, g); *out++ = g; return out; } + + typedef typename ring_type::type ring_type; + typedef std::vector out_vector; + out_vector rings; + + typedef std::map + < + signed_size_type, + detail::overlay::cluster_info + > cluster_type; + + cluster_type clusters; + + // Enrich/traverse the polygons twice: first for union... + typename Strategy::side_strategy_type const + side_strategy = strategy.get_side_strategy(); + + enrich_intersection_points(turns, + clusters, geometry, geometry, rescale_policy, + side_strategy); + + visitor.visit_turns(2, turns); + + visitor.visit_clusters(clusters, turns); + + std::map turn_info_per_ring; + + detail::overlay::traverse + < + false, false, + Geometry, Geometry, + overlay_dissolve_union, + backtrack_for_dissolve + >::apply(geometry, geometry, + strategy, rescale_policy, + turns, rings, turn_info_per_ring, clusters, visitor); + + visitor.visit_turns(3, turns); + + // ... and then for intersection + clear(turns); + enrich_intersection_points(turns, + clusters, geometry, geometry, rescale_policy, + side_strategy); + + visitor.visit_turns(4, turns); + + detail::overlay::traverse + < + false, false, + Geometry, Geometry, + overlay_dissolve_intersection, + backtrack_for_dissolve + >::apply(geometry, geometry, + strategy, rescale_policy, + turns, rings, turn_info_per_ring, clusters, visitor); + + visitor.visit_turns(5, turns); + + detail::overlay::get_ring_turn_info(turn_info_per_ring, turns, clusters); + + typedef typename geometry::point_type::type point_type; + typedef typename Strategy::template area_strategy + < + point_type + >::type area_strategy_type; + typedef typename area_strategy_type::return_type area_result_type; + typedef detail::overlay::ring_properties properties; + + std::map selected; + + detail::overlay::select_rings(geometry, turn_info_per_ring, selected, strategy); + + // Add intersected rings + { + area_strategy_type const area_strategy = strategy.template get_area_strategy(); + + ring_identifier id(2, 0, -1); + for (typename boost::range_iterator const>::type + it = boost::begin(rings); + it != boost::end(rings); + ++it) + { + selected[id] = properties(*it, area_strategy); + id.multi_index++; + } + } + + detail::overlay::assign_parents(geometry, rings, selected, strategy, true); + return detail::overlay::add_rings(selected, geometry, rings, out); } };