From 8a12ebdb694aef6fc0d83f14c48db5d890f96051 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 4 Jul 2017 04:45:37 +0200 Subject: [PATCH] [buffer][is_valid][overlay] Use area strategy got from intersection strategy. --- .../buffer/buffered_piece_collection.hpp | 41 +++++++----- .../algorithms/detail/is_valid/ring.hpp | 5 +- .../detail/overlay/assign_parents.hpp | 16 +++-- .../algorithms/detail/overlay/overlay.hpp | 26 ++++++-- .../detail/overlay/ring_properties.hpp | 10 +-- .../detail/overlay/select_rings.hpp | 65 +++++++++++-------- 6 files changed, 103 insertions(+), 60 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index aa6302f39..4bb7a281f 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -142,10 +142,20 @@ struct buffered_piece_collection robust_point_type >::type robust_comparable_radius_type; - typedef typename strategy::side::services::default_strategy + typedef typename IntersectionStrategy::side_strategy_type side_strategy_type; + + typedef typename IntersectionStrategy::template area_strategy < - typename cs_tag::type - >::type side_strategy; + point_type + >::type area_strategy_type; + + typedef typename IntersectionStrategy::template area_strategy + < + robust_point_type + >::type robust_area_strategy_type; + + typedef typename area_strategy_type::return_type area_result_type; + typedef typename robust_area_strategy_type::return_type robust_area_result_type; typedef typename geometry::rescale_policy_type < @@ -306,7 +316,10 @@ struct buffered_piece_collection cluster_type m_clusters; - IntersectionStrategy const& m_intersection_strategy; + IntersectionStrategy m_intersection_strategy; + side_strategy_type m_side_strategy; + area_strategy_type m_area_strategy; + robust_area_strategy_type m_robust_area_strategy; RobustPolicy const& m_robust_policy; struct redundant_turn @@ -321,6 +334,9 @@ struct buffered_piece_collection RobustPolicy const& robust_policy) : m_first_piece_index(-1) , m_intersection_strategy(intersection_strategy) + , m_side_strategy(intersection_strategy.get_side_strategy()) + , m_area_strategy(intersection_strategy.template get_area_strategy()) + , m_robust_area_strategy(intersection_strategy.template get_area_strategy()) , m_robust_policy(robust_policy) {} @@ -699,7 +715,7 @@ struct buffered_piece_collection ++it) { piece& pc = *it; - if (geometry::area(pc.robust_ring) < 0) + if (geometry::area(pc.robust_ring, m_robust_area_strategy) < 0) { // Rings can be ccw: // - in a concave piece @@ -1220,14 +1236,9 @@ struct buffered_piece_collection inline void enrich() { - typedef typename strategy::side::services::default_strategy - < - typename cs_tag::type - >::type side_strategy_type; - enrich_intersection_points(m_turns, m_clusters, offsetted_rings, offsetted_rings, - m_robust_policy, side_strategy_type()); + m_robust_policy, m_side_strategy); } // Discards all rings which do have not-OK intersection points only. @@ -1314,7 +1325,7 @@ struct buffered_piece_collection buffered_ring& ring = *it; if (! ring.has_intersections() && boost::size(ring) > 0u - && geometry::area(ring) < 0) + && geometry::area(ring, m_area_strategy) < 0) { if (! point_coveredby_original(geometry::range::front(ring))) { @@ -1391,7 +1402,7 @@ struct buffered_piece_collection template inline OutputIterator assign(OutputIterator out) const { - typedef detail::overlay::ring_properties properties; + typedef detail::overlay::ring_properties properties; std::map selected; @@ -1407,7 +1418,7 @@ struct buffered_piece_collection if (! it->has_intersections() && ! it->is_untouched_outside_original) { - properties p = properties(*it); + properties p = properties(*it, m_area_strategy); if (p.valid) { ring_identifier id(0, index, -1); @@ -1423,7 +1434,7 @@ struct buffered_piece_collection it != boost::end(traversed_rings); ++it, ++index) { - properties p = properties(*it); + properties p = properties(*it, m_area_strategy); if (p.valid) { ring_identifier id(2, index, -1); diff --git a/include/boost/geometry/algorithms/detail/is_valid/ring.hpp b/include/boost/geometry/algorithms/detail/is_valid/ring.hpp index 9ab68fdc4..996da7d96 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/ring.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/ring.hpp @@ -115,7 +115,10 @@ struct is_properly_oriented geometry::closure::value > ring_area_type; - typedef typename default_area_result::type area_result_type; + typedef typename Strategy::template area_strategy + < + point_type + >::type::return_type area_result_type; typename ring_area_predicate < diff --git a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp index e8bb2c1ac..78160f520 100644 --- a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp @@ -107,21 +107,19 @@ static inline bool within_selected_input(Item const& item2, } -template +template struct ring_info_helper { - typedef typename geometry::default_area_result::type area_type; - ring_identifier id; - area_type real_area; - area_type abs_area; + AreaType real_area; + AreaType abs_area; model::box envelope; inline ring_info_helper() : real_area(0), abs_area(0) {} - inline ring_info_helper(ring_identifier i, area_type a) + inline ring_info_helper(ring_identifier i, AreaType const& a) : id(i), real_area(a), abs_area(geometry::math::abs(a)) {} }; @@ -234,11 +232,15 @@ inline void assign_parents(Geometry1 const& geometry1, typedef typename RingMap::mapped_type ring_info_type; typedef typename ring_info_type::point_type point_type; typedef model::box box_type; + typedef typename Strategy::template area_strategy + < + point_type + >::type::return_type area_result_type; typedef typename RingMap::iterator map_iterator_type; { - typedef ring_info_helper helper; + typedef ring_info_helper helper; typedef std::vector vector_type; typedef typename boost::range_iterator::type vector_iterator_type; diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index 90258cc84..10829abd4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -197,7 +197,16 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1, typename geometry::ring_type::type > ring_container_type; - typedef ring_properties::type> properties; + typedef typename geometry::point_type::type point_type1; + + typedef ring_properties + < + point_type1, + typename Strategy::template area_strategy + < + point_type1 + >::type::return_type + > properties; // Silence warning C4127: conditional expression is constant #if defined(_MSC_VER) @@ -309,7 +318,7 @@ std::cout << "get turns" << std::endl; #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE std::cout << "enrich" << std::endl; #endif - typename Strategy::side_strategy_type side_strategy; + typename Strategy::side_strategy_type side_strategy = strategy.get_side_strategy(); cluster_type clusters; geometry::enrich_intersection_points(turns, @@ -341,10 +350,13 @@ std::cout << "traverse" << std::endl; std::map turn_info_per_ring; get_ring_turn_info(turn_info_per_ring, turns, clusters); + typedef typename Strategy::template area_strategy::type area_strategy_type; + typedef ring_properties - < - typename geometry::point_type::type - > properties; + < + point_type, + typename area_strategy_type::return_type + > properties; // Select all rings which are NOT touched by any intersection point std::map selected_ring_properties; @@ -353,13 +365,15 @@ std::cout << "traverse" << std::endl; // Add rings created during traversal { + area_strategy_type const area_strategy = strategy.template get_area_strategy(); + ring_identifier id(2, 0, -1); for (typename boost::range_iterator::type it = boost::begin(rings); it != boost::end(rings); ++it) { - selected_ring_properties[id] = properties(*it); + selected_ring_properties[id] = properties(*it, area_strategy); selected_ring_properties[id].reversed = ReverseOut; id.multi_index++; } diff --git a/include/boost/geometry/algorithms/detail/overlay/ring_properties.hpp b/include/boost/geometry/algorithms/detail/overlay/ring_properties.hpp index abade1fe1..7dbc5d5fa 100644 --- a/include/boost/geometry/algorithms/detail/overlay/ring_properties.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/ring_properties.hpp @@ -27,11 +27,11 @@ namespace boost { namespace geometry namespace detail { namespace overlay { -template +template struct ring_properties { typedef Point point_type; - typedef typename default_area_result::type area_type; + typedef AreaType area_type; bool valid; @@ -56,13 +56,13 @@ struct ring_properties , parent_area(-1) {} - template - inline ring_properties(RingOrBox const& ring_or_box) + template + inline ring_properties(RingOrBox const& ring_or_box, AreaStrategy const& strategy) : reversed(false) , discarded(false) , parent_area(-1) { - this->area = geometry::area(ring_or_box); + this->area = geometry::area(ring_or_box, strategy); valid = geometry::point_on_border(this->point, ring_or_box); } diff --git a/include/boost/geometry/algorithms/detail/overlay/select_rings.hpp b/include/boost/geometry/algorithms/detail/overlay/select_rings.hpp index 638bcf474..67a4f4bb7 100644 --- a/include/boost/geometry/algorithms/detail/overlay/select_rings.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/select_rings.hpp @@ -59,41 +59,45 @@ namespace dispatch template struct select_rings { - template + template static inline void apply(Box const& box, Geometry const& , - ring_identifier const& id, RingPropertyMap& ring_properties) + ring_identifier const& id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { - ring_properties[id] = typename RingPropertyMap::mapped_type(box); + ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy); } - template + template static inline void apply(Box const& box, - ring_identifier const& id, RingPropertyMap& ring_properties) + ring_identifier const& id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { - ring_properties[id] = typename RingPropertyMap::mapped_type(box); + ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy); } }; template struct select_rings { - template + template static inline void apply(Ring const& ring, Geometry const& , - ring_identifier const& id, RingPropertyMap& ring_properties) + ring_identifier const& id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { if (boost::size(ring) > 0) { - ring_properties[id] = typename RingPropertyMap::mapped_type(ring); + ring_properties[id] = typename RingPropertyMap::mapped_type(ring, strategy); } } - template + template static inline void apply(Ring const& ring, - ring_identifier const& id, RingPropertyMap& ring_properties) + ring_identifier const& id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { if (boost::size(ring) > 0) { - ring_properties[id] = typename RingPropertyMap::mapped_type(ring); + ring_properties[id] = typename RingPropertyMap::mapped_type(ring, strategy); } } }; @@ -102,14 +106,15 @@ namespace dispatch template struct select_rings { - template + template static inline void apply(Polygon const& polygon, Geometry const& geometry, - ring_identifier id, RingPropertyMap& ring_properties) + ring_identifier id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { typedef typename geometry::ring_type::type ring_type; typedef select_rings per_ring; - per_ring::apply(exterior_ring(polygon), geometry, id, ring_properties); + per_ring::apply(exterior_ring(polygon), geometry, id, ring_properties, strategy); typename interior_return_type::type rings = interior_rings(polygon); @@ -117,18 +122,19 @@ namespace dispatch it = boost::begin(rings); it != boost::end(rings); ++it) { id.ring_index++; - per_ring::apply(*it, geometry, id, ring_properties); + per_ring::apply(*it, geometry, id, ring_properties, strategy); } } - template + template static inline void apply(Polygon const& polygon, - ring_identifier id, RingPropertyMap& ring_properties) + ring_identifier id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { typedef typename geometry::ring_type::type ring_type; typedef select_rings per_ring; - per_ring::apply(exterior_ring(polygon), id, ring_properties); + per_ring::apply(exterior_ring(polygon), id, ring_properties, strategy); typename interior_return_type::type rings = interior_rings(polygon); @@ -136,7 +142,7 @@ namespace dispatch it = boost::begin(rings); it != boost::end(rings); ++it) { id.ring_index++; - per_ring::apply(*it, id, ring_properties); + per_ring::apply(*it, id, ring_properties, strategy); } } }; @@ -144,9 +150,10 @@ namespace dispatch template struct select_rings { - template + template static inline void apply(Multi const& multi, Geometry const& geometry, - ring_identifier id, RingPropertyMap& ring_properties) + ring_identifier id, RingPropertyMap& ring_properties, + AreaStrategy const& strategy) { typedef typename boost::range_iterator < @@ -159,7 +166,7 @@ namespace dispatch for (iterator_type it = boost::begin(multi); it != boost::end(multi); ++it) { id.ring_index = -1; - per_polygon::apply(*it, geometry, id, ring_properties); + per_polygon::apply(*it, geometry, id, ring_properties, strategy); id.multi_index++; } } @@ -311,12 +318,16 @@ inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2, { typedef typename geometry::tag::type tag1; typedef typename geometry::tag::type tag2; + typedef typename geometry::point_type::type point1_type; + typedef typename geometry::point_type::type point2_type; RingPropertyMap all_ring_properties; dispatch::select_rings::apply(geometry1, geometry2, - ring_identifier(0, -1, -1), all_ring_properties); + ring_identifier(0, -1, -1), all_ring_properties, + strategy.template get_area_strategy()); dispatch::select_rings::apply(geometry2, geometry1, - ring_identifier(1, -1, -1), all_ring_properties); + ring_identifier(1, -1, -1), all_ring_properties, + strategy.template get_area_strategy()); update_ring_selection(geometry1, geometry2, turn_info_per_ring, all_ring_properties, selected_ring_properties, @@ -337,10 +348,12 @@ inline void select_rings(Geometry const& geometry, Strategy const& strategy) { typedef typename geometry::tag::type tag; + typedef typename geometry::point_type::type point_type; RingPropertyMap all_ring_properties; dispatch::select_rings::apply(geometry, - ring_identifier(0, -1, -1), all_ring_properties); + ring_identifier(0, -1, -1), all_ring_properties, + strategy.template get_area_strategy()); update_ring_selection(geometry, geometry, turn_info_per_ring, all_ring_properties, selected_ring_properties,