diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 1e73ee596..80c2ee174 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -120,8 +120,8 @@ class douglas_peucker PSDistanceStrategy const& ps_distance_strategy) { typedef typename std::iterator_traits::value_type::point_type point_type; - using distance_type = decltype(ps_distance_strategy.apply( - std::declval(), std::declval(), std::declval())); + typedef decltype(ps_distance_strategy.apply(std::declval(), + std::declval(), std::declval())) distance_type; std::size_t size = end - begin; @@ -153,7 +153,7 @@ class douglas_peucker // Find most far point, compare to the current segment //geometry::segment s(begin->p, last->p); distance_type md(-1.0); // any value < 0 - Iterator candidate; + Iterator candidate = end; for (Iterator it = begin + 1; it != last; ++it) { distance_type dist = ps_distance_strategy.apply(*(it->p), *(begin->p), *(last->p)); @@ -174,7 +174,7 @@ class douglas_peucker // If a point is found, set the include flag // and handle segments in between recursively - if (max_dist < md) + if (max_dist < md && candidate != end) { #ifdef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER std::cout << "use " << dsv(candidate->p) << std::endl; @@ -411,10 +411,9 @@ public : return; } - // TODO: use calculate_point_order - // TODO: pass strategies + // TODO: instead of area() use calculate_point_order() ? - int const input_sign = area_sign(geometry::area(ring)); + int const input_sign = area_sign(geometry::area(ring, strategies)); std::set visited_indexes; @@ -464,12 +463,11 @@ public : simplify_range<0>::apply(rotated, out, max_distance, impl, strategies); - // TODO: use calculate_point_order - // TODO: pass strategies + // TODO: instead of area() use calculate_point_order() ? // Verify that what was positive, stays positive (or goes to 0) // and what was negative stays negative (or goes to 0) - int const output_sign = area_sign(geometry::area(out)); + int const output_sign = area_sign(geometry::area(out, strategies)); if (output_sign == input_sign) { // Result is considered as satisfactory (usually this is the @@ -482,10 +480,8 @@ public : // when another starting point is used geometry::clear(out); - // TODO: pass strategies - if (iteration == 0 - && geometry::perimeter(ring) < 3 * max_distance) + && geometry::perimeter(ring, strategies) < 3 * max_distance) { // Check if it is useful to iterate. A minimal triangle has a // perimeter of a bit more than 3 times the simplify distance diff --git a/include/boost/geometry/strategies/simplify/cartesian.hpp b/include/boost/geometry/strategies/simplify/cartesian.hpp index 223630655..936632072 100644 --- a/include/boost/geometry/strategies/simplify/cartesian.hpp +++ b/include/boost/geometry/strategies/simplify/cartesian.hpp @@ -19,6 +19,8 @@ #include #include +#include + #include @@ -32,6 +34,26 @@ template struct cartesian : public strategies::detail::cartesian_base { + // TODO: Replace this if calculate_point_order() is used in simplify + template + static auto area(Geometry const&) + { + return strategy::area::cartesian(); + } + + // For perimeter() + template + static auto distance(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) + { + return strategy::distance::pythagoras(); + } + + // For douglas_peucker template static auto distance(Geometry1 const&, Geometry2 const&, std::enable_if_t @@ -51,6 +73,7 @@ struct cartesian >(); } + // For equals() template static auto relate(Geometry1 const&, Geometry2 const&, std::enable_if_t diff --git a/include/boost/geometry/strategies/simplify/geographic.hpp b/include/boost/geometry/strategies/simplify/geographic.hpp index 0b06ccc6a..f8e750f0f 100644 --- a/include/boost/geometry/strategies/simplify/geographic.hpp +++ b/include/boost/geometry/strategies/simplify/geographic.hpp @@ -18,6 +18,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -43,6 +45,35 @@ public: : base_t(spheroid) {} + // TODO: Replace this if calculate_point_order() is used in simplify + template + auto area(Geometry const&) const + { + return strategy::area::geographic + < + FormulaPolicy, + strategy::default_order::value, + Spheroid, + CalculationType + >(base_t::m_spheroid); + } + + // For perimeter() + template + auto distance(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) const + { + return strategy::distance::geographic + < + FormulaPolicy, Spheroid, CalculationType + >(base_t::m_spheroid); + } + + // For douglas_peucker template auto distance(Geometry1 const&, Geometry2 const&, std::enable_if_t @@ -61,6 +92,7 @@ public: >(base_t::m_spheroid); } + // For equals() template static auto relate(Geometry1 const&, Geometry2 const&, std::enable_if_t diff --git a/include/boost/geometry/strategies/simplify/spherical.hpp b/include/boost/geometry/strategies/simplify/spherical.hpp index d5a23178e..80ab24510 100644 --- a/include/boost/geometry/strategies/simplify/spherical.hpp +++ b/include/boost/geometry/strategies/simplify/spherical.hpp @@ -19,6 +19,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -44,6 +46,32 @@ public: : base_t(radius_or_sphere) {} + // TODO: Replace this if calculate_point_order() is used in simplify + template + auto area(Geometry const&) const + { + return strategy::area::spherical + < + typename base_t::radius_type, CalculationType + >(base_t::radius()); + } + + // For perimeter() + template + auto distance(Geometry1 const&, Geometry2 const&, + std::enable_if_t + < + util::is_pointlike::value + && util::is_pointlike::value + > * = nullptr) const + { + return strategy::distance::haversine + < + typename base_t::radius_type, CalculationType + >(base_t::radius()); + } + + // For douglas_peucker template auto distance(Geometry1 const&, Geometry2 const&, std::enable_if_t @@ -63,6 +91,7 @@ public: >(base_t::radius()); } + // For equals() template static auto relate(Geometry1 const&, Geometry2 const&, std::enable_if_t