From f7de658c2c6fd5cba8c0f5d95cd97e36b618bdc2 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 30 Nov 2017 01:35:28 +0100 Subject: [PATCH 01/19] [algorithms] Add complexify() algorithm. --- .../boost/geometry/algorithms/complexify.hpp | 260 ++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 include/boost/geometry/algorithms/complexify.hpp diff --git a/include/boost/geometry/algorithms/complexify.hpp b/include/boost/geometry/algorithms/complexify.hpp new file mode 100644 index 000000000..9020ffa67 --- /dev/null +++ b/include/boost/geometry/algorithms/complexify.hpp @@ -0,0 +1,260 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP +#define BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace complexify +{ + +template +inline void convert_and_push_back(Range & range, Point const& p) +{ + typename boost::range_value::type p2; + geometry::detail::conversion::convert_point_to_point(p, p2); + range::push_back(range, p2); +} + +template +struct complexify_range +{ + template + static inline void apply(Geometry const& rng, GeometryOut & rng_out, + T const& len, Strategy const& strategy) + { + typedef typename boost::range_value::type point_t; + + std::size_t count = boost::size(rng); + + if (count == 0) + return; + + for (std::size_t i = 1 ; i < count ; ++i) + { + point_t const& p0 = range::at(rng, i - 1); + point_t const& p1 = range::at(rng, i); + + convert_and_push_back(rng_out, p0); + + strategy.apply(p0, p1, rng_out, len); + } + + if (BOOST_GEOMETRY_CONDITION(AppendLastPoint)) + { + convert_and_push_back(rng_out, range::back(rng)); + } + } +}; + +template // false, X +struct complexify_ring +{ + template + static inline void apply(Geometry const& ring, GeometryOut & ring_out, + T const& len, Strategy const& strategy) + { + geometry::detail::complexify::complexify_range + ::apply(ring, ring_out, len, strategy); + + if (boost::size(ring) <= 1) + return; + + typedef typename point_type::type point_t; + point_t const& p0 = range::back(ring); + point_t const& p1 = range::front(ring); + + strategy.apply(p0, p1, ring_out, len); + + if (BOOST_GEOMETRY_CONDITION(IsClosed2)) + { + convert_and_push_back(ring_out, p1); + } + } +}; + +template <> +struct complexify_ring + : complexify_range +{}; + +template <> +struct complexify_ring + : complexify_range +{}; + + +}} // namespace detail::complexify +#endif // DOXYGEN_NO_DETAIL + + +#ifndef DOXYGEN_NO_DISPATCH +namespace dispatch +{ + + +template +< + typename Geometry, + typename GeometryOut, + typename Tag1 = typename tag::type, + typename Tag2 = typename tag::type +> +struct complexify + : not_implemented +{}; + +template +struct complexify + : geometry::detail::complexify::complexify_range<> +{}; + +template +struct complexify +{ + template + static void apply(Geometry const& mls, GeometryOut & mls_out, + T const& len, Strategy const& strategy) + { + std::size_t count = boost::size(mls); + range::resize(mls_out, count); + + for (std::size_t i = 0 ; i < count ; ++i) + { + geometry::detail::complexify::complexify_range<> + ::apply(range::at(mls, i), range::at(mls_out, i), + len, strategy); + } + } +}; + +template +struct complexify + : geometry::detail::complexify::complexify_ring + < + geometry::closure::value != geometry::open, + geometry::closure::value != geometry::open + > +{}; + +template +struct complexify +{ + template + static void apply(Geometry const& poly, GeometryOut & poly_out, + T const& len, Strategy const& strategy) + { + apply_ring(exterior_ring(poly), exterior_ring(poly_out), + length_threshold, sph); + + std::size_t count = boost::size(interior_rings(poly)); + range::resize(interior_rings(poly_out), count); + + for (std::size_t i = 0 ; i < count ; ++i) + { + apply_ring(range::at(interior_rings(poly), i), + range::at(interior_rings(poly_out), i), + length_threshold, sph); + } + } + + template + static void apply_ring(Geometry const& ring, GeometryOut & ring_out, + T const& len, Strategy const& strategy) + { + complexify + ::apply(ring, ring_out, len, strategy); + } +}; + +template +struct complexify +{ + template + static void apply(Geometry const& mpoly, GeometryOut & mpoly_out, + T const& len, Strategy const& strategy) + { + std::size_t count = boost::size(mpoly); + range::resize(mpoly_out, mpoly); + + for (std::size_t i = 0 ; i < count ; ++i) + { + apply_poly(range::at(mpoly, i), + range::at(mpoly_out, i), + length_threshold, sph); + } + } + + template + static void apply_poly(Geometry const& poly, GeometryOut & poly_out, + T const& len, Strategy const& strategy) + { + complexify:: + apply(poly, poly_out, length_threshold, strategy); + } +}; + + +} // namespace dispatch +#endif // DOXYGEN_NO_DISPATCH + + +template +inline void complexify(Geometry const& geometry, + GeometryOut & geometry_out, + T const& length_threshhold, + Strategy const& strategy) +{ + concepts::check(); + concepts::check(); + + geometry::clear(geometry_out); + + dispatch::complexify + < + Geometry, + GeometryOut + >::apply(geometry, geometry_out, length_threshhold, strategy); +} + +template +inline void complexify(Geometry const& geometry, + GeometryOut & geometry_out, + T const& length_threshhold) +{ + + typedef strategy::complexify::services::default_strategy + < + typename cs_tag::type + > strategy_type; + + complexify(geometry, geometry_out, length_threshhold, strategy_type()); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP From 69a2516373d9fd2a0c321d853812e51b6c9a7832 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 30 Nov 2017 01:36:16 +0100 Subject: [PATCH 02/19] [strategies] Add spherical and geographic complexify() strategies. --- .../boost/geometry/strategies/complexify.hpp | 42 +++++ .../strategies/geographic/complexify.hpp | 122 ++++++++++++ .../strategies/spherical/complexify.hpp | 173 ++++++++++++++++++ 3 files changed, 337 insertions(+) create mode 100644 include/boost/geometry/strategies/complexify.hpp create mode 100644 include/boost/geometry/strategies/geographic/complexify.hpp create mode 100644 include/boost/geometry/strategies/spherical/complexify.hpp diff --git a/include/boost/geometry/strategies/complexify.hpp b/include/boost/geometry/strategies/complexify.hpp new file mode 100644 index 000000000..e70abbd4a --- /dev/null +++ b/include/boost/geometry/strategies/complexify.hpp @@ -0,0 +1,42 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP + + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace complexify +{ + +namespace services +{ + +template +struct default_strategy +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_CS + , (types) + ); +}; + +} // namespace services + +}} // namespace strategy::complexify + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP diff --git a/include/boost/geometry/strategies/geographic/complexify.hpp b/include/boost/geometry/strategies/geographic/complexify.hpp new file mode 100644 index 000000000..44384925c --- /dev/null +++ b/include/boost/geometry/strategies/geographic/complexify.hpp @@ -0,0 +1,122 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_COMPLEXIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_COMPLEXIFY_HPP + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace complexify +{ + + +template +< + typename FormulaPolicy = strategy::andoyer, + typename Spheroid = srs::spheroid, + typename CalculationType = void +> +struct geographic +{ + geographic() + : m_spheroid() + {} + + explicit geographic(Spheroid const& spheroid) + : m_spheroid(spheroid) + {} + + template + inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) const + { + typedef typename boost::range_value::type rng_point_t; + typedef typename select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type, + CalculationType + >::type calc_t; + + typedef typename FormulaPolicy::template direct direct_t; + typedef typename FormulaPolicy::template inverse inverse_t; + + typename inverse_t::result_type + inv_r = inverse_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0), + get_as_radian<0>(p1), get_as_radian<1>(p1), + m_spheroid); + + signed_size_type n = signed_size_type(inv_r.distance / length_threshold); + if (n <= 0) + return; + + calc_t step = inv_r.distance / (n + 1); + + calc_t current = step; + for (signed_size_type i = 0 ; i < n ; ++i, current += step) + { + typename direct_t::result_type + dir_r = direct_t::apply(get_as_radian<0>(p0), get_as_radian<1>(p0), + current, inv_r.azimuth, + m_spheroid); + + rng_point_t p; + set_from_radian<0>(p, dir_r.lon2); + set_from_radian<1>(p, dir_r.lat2); + geometry::detail::conversion::point_to_point + < + Point, rng_point_t, + 2, dimension::value + >::apply(p0, p); + + range::push_back(rng, p); + } + } + +private: + Spheroid m_spheroid; +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template <> +struct default_strategy +{ + typedef strategy::complexify::geographic<> type; +}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::complexify + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP diff --git a/include/boost/geometry/strategies/spherical/complexify.hpp b/include/boost/geometry/strategies/spherical/complexify.hpp new file mode 100644 index 000000000..d852725d6 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/complexify.hpp @@ -0,0 +1,173 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPLEXIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPLEXIFY_HPP + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace complexify +{ + + +template +< + typename Sphere = srs::sphere, + typename CalculationType = void +> +struct spherical +{ + // For consistency with area strategy the radius is set to 1 + spherical() + : m_radius(1.0) + {} + + explicit spherical(Sphere const& sphere) + : m_radius(geometry::get_radius<0>(sphere)) + {} + + // TODO: use enable_if/disable_if to distinguish between Sphere and Radius? + template + explicit spherical(OtherSphere const& sphere) + : m_radius(geometry::get_radius<0>(sphere)) + {} + + template + inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) const + { + typedef typename boost::range_value::type rng_point_t; + typedef typename select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type, + CalculationType + >::type calc_t; + + calc_t const c0 = 0; + calc_t const c1 = 1; + calc_t const pi = math::pi(); + + typedef model::point point3d_t; + point3d_t const xyz0 = formula::sph_to_cart3d(p0); + point3d_t const xyz1 = formula::sph_to_cart3d(p1); + calc_t const dot01 = geometry::dot_product(xyz0, xyz1); + calc_t const angle01 = acos(dot01); + + signed_size_type n = signed_size_type(angle01 * m_radius / length_threshold); + if (n <= 0) + return; + + point3d_t axis; + if (! math::equals(angle01, pi)) + { + axis = geometry::cross_product(xyz0, xyz1); + geometry::detail::vec_normalize(axis); + } + else // antipodal + { + calc_t const half_pi = math::half_pi(); + calc_t const lat = geometry::get_as_radian<1>(p0); + + if (math::equals(lat, half_pi)) + { + // pointing east, segment lies on prime meridian, going south + axis = point3d_t(c0, c1, c0); + } + else if (math::equals(lat, -half_pi)) + { + // pointing west, segment lies on prime meridian, going north + axis = point3d_t(c0, -c1, c0); + } + else + { + // lon rotated west by pi/2 at equator + calc_t const lon = geometry::get_as_radian<0>(p0); + axis = point3d_t(sin(lon), -cos(lon), c0); + } + } + + calc_t step = angle01 / (n + 1); + + calc_t a = step; + for (signed_size_type i = 0 ; i < n ; ++i, a += step) + { + // Axis-Angle rotation + // see: https://en.wikipedia.org/wiki/Axis-angle_representation + calc_t const cos_a = cos(a); + calc_t const sin_a = sin(a); + // cos_a * v + point3d_t s1 = xyz0; + geometry::multiply_value(s1, cos_a); + // sin_a * (n x v) + point3d_t s2 = geometry::cross_product(axis, xyz0); + geometry::multiply_value(s2, sin_a); + // (1 - cos_a)(n.v) * n + point3d_t s3 = axis; + geometry::multiply_value(s3, (c1 - cos_a) * geometry::dot_product(axis, xyz0)); + // v_rot = cos_a * v + sin_a * (n x v) + (1 - cos_a)(n.v) * e + point3d_t v_rot = s1; + geometry::add_point(v_rot, s2); + geometry::add_point(v_rot, s3); + + rng_point_t p = formula::cart3d_to_sph(v_rot); + geometry::detail::conversion::point_to_point + < + Point, rng_point_t, + 2, dimension::value + >::apply(p0, p); + + range::push_back(rng, p); + } + } + +private: + typename geometry::radius_type::type m_radius; +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template <> +struct default_strategy +{ + typedef strategy::complexify::spherical<> type; +}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::complexify + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP From 9a23ca90f0dcc497758f0fd41c4e0f2be623c7f9 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 1 Dec 2017 02:52:22 +0100 Subject: [PATCH 03/19] [strategies] Add cartesian complexify() strategy. --- .../strategies/cartesian/complexify.hpp | 123 ++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 include/boost/geometry/strategies/cartesian/complexify.hpp diff --git a/include/boost/geometry/strategies/cartesian/complexify.hpp b/include/boost/geometry/strategies/cartesian/complexify.hpp new file mode 100644 index 000000000..5061a2dd3 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/complexify.hpp @@ -0,0 +1,123 @@ +// Boost.Geometry + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace complexify +{ + + +template +< + typename CalculationType = void +> +struct cartesian +{ + template + static inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) + { + typedef typename boost::range_value::type rng_point_t; + typedef typename select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type, + CalculationType + >::type calc_t; + + typedef model::point point2d_t; + + point2d_t const xy0(geometry::get<0>(p0), geometry::get<1>(p0)); + point2d_t const xy1(geometry::get<0>(p1), geometry::get<1>(p1)); + // dir01 = xy1 - xy0 + point2d_t dir01 = xy1; + geometry::subtract_point(dir01, xy0); + calc_t const dot01 = geometry::dot_product(dir01, dir01); + calc_t const len2d = math::sqrt(dot01); + + // TODO: For consistency with spherical and geographic 2d length is + // taken into account. This probably should be changed. Also in the + // other strategies dimensions > 2 should be taken into account. + signed_size_type n = signed_size_type(len2d / length_threshold); + if (n <= 0) + return; + + // NOTE: Normalization will not work for integral coordinates + // normalize + //geometry::divide_value(dir01, len2d); + + calc_t step = len2d / (n + 1); + + calc_t d = step; + for (signed_size_type i = 0 ; i < n ; ++i, d += step) + { + // pd = xy0 + d * dir01 + point2d_t pd = dir01; + + // without normalization + geometry::multiply_value(pd, calc_t(i + 1)); + geometry::divide_value(pd, calc_t(n + 1)); + // with normalization + //geometry::multiply_value(pd, d); + + geometry::add_point(pd, xy0); + + rng_point_t p; + geometry::set<0>(p, geometry::get<0>(pd)); + geometry::set<1>(p, geometry::get<1>(pd)); + geometry::detail::conversion::point_to_point + < + Point, rng_point_t, + 2, dimension::value + >::apply(p0, p); + + range::push_back(rng, p); + } + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template <> +struct default_strategy +{ + typedef strategy::complexify::cartesian<> type; +}; + + +} // namespace services +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::complexify + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP From 149d817d486255627bd63056aa1af64c85394e98 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 1 Dec 2017 04:12:58 +0100 Subject: [PATCH 04/19] [complexify] Add variant support and make interface consistent with simplify. --- .../boost/geometry/algorithms/complexify.hpp | 124 +++++++++++++++--- 1 file changed, 104 insertions(+), 20 deletions(-) diff --git a/include/boost/geometry/algorithms/complexify.hpp b/include/boost/geometry/algorithms/complexify.hpp index 9020ffa67..74bfdd740 100644 --- a/include/boost/geometry/algorithms/complexify.hpp +++ b/include/boost/geometry/algorithms/complexify.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -223,36 +224,119 @@ struct complexify #endif // DOXYGEN_NO_DISPATCH -template +namespace resolve_strategy +{ + +struct complexify +{ + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) + { + dispatch::complexify + ::apply(geometry, out, max_distance, strategy); + } + + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + default_strategy) + { + typedef strategy::complexify::services::default_strategy + < + typename cs_tag::type + > strategy_type; + + /*BOOST_CONCEPT_ASSERT( + (concepts::ComplexifyStrategy) + );*/ + + apply(geometry, out, max_distance, strategy_type()); + } +}; + +} // namespace resolve_strategy + + +namespace resolve_variant { + +template +struct complexify +{ + template + static inline void apply(Geometry const& geometry, + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) + { + resolve_strategy::complexify::apply(geometry, out, max_distance, strategy); + } +}; + +template +struct complexify > +{ + template + struct visitor: boost::static_visitor + { + Distance const& m_max_distance; + Strategy const& m_strategy; + + visitor(Distance const& max_distance, Strategy const& strategy) + : m_max_distance(max_distance) + , m_strategy(strategy) + {} + + template + void operator()(Geometry const& geometry, Geometry& out) const + { + simplify::apply(geometry, out, m_max_distance, m_strategy); + } + }; + + template + static inline void + apply(boost::variant const& geometry, + boost::variant& out, + Distance const& max_distance, + Strategy const& strategy) + { + boost::apply_visitor( + visitor(max_distance, strategy), + geometry, + out + ); + } +}; + +} // namespace resolve_variant + + +template inline void complexify(Geometry const& geometry, - GeometryOut & geometry_out, - T const& length_threshhold, + Geometry& out, + Distance const& max_distance, Strategy const& strategy) { - concepts::check(); - concepts::check(); + concepts::check(); - geometry::clear(geometry_out); + geometry::clear(out); - dispatch::complexify + resolve_variant::complexify < - Geometry, - GeometryOut - >::apply(geometry, geometry_out, length_threshhold, strategy); + Geometry + >::apply(geometry, out, max_distance, strategy); } -template +template inline void complexify(Geometry const& geometry, - GeometryOut & geometry_out, - T const& length_threshhold) + Geometry& out, + Distance const& max_distance) { - - typedef strategy::complexify::services::default_strategy - < - typename cs_tag::type - > strategy_type; - - complexify(geometry, geometry_out, length_threshhold, strategy_type()); + complexify(geometry, out, max_distance, strategy_type()); } }} // namespace boost::geometry From ff2aaf1ce5f9680243a985604b6c485b6aa5391a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 4 Dec 2017 22:11:31 +0100 Subject: [PATCH 05/19] [complexify] Fix compilation errors (includes, tparams, names). --- .../boost/geometry/algorithms/complexify.hpp | 34 ++++++++++--------- .../strategies/cartesian/complexify.hpp | 1 + .../strategies/spherical/complexify.hpp | 1 + 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/include/boost/geometry/algorithms/complexify.hpp b/include/boost/geometry/algorithms/complexify.hpp index 74bfdd740..be7d362af 100644 --- a/include/boost/geometry/algorithms/complexify.hpp +++ b/include/boost/geometry/algorithms/complexify.hpp @@ -18,7 +18,9 @@ #include #include #include +#include #include +#include #include #include @@ -137,7 +139,7 @@ struct complexify template struct complexify { - template + template static void apply(Geometry const& mls, GeometryOut & mls_out, T const& len, Strategy const& strategy) { @@ -165,12 +167,12 @@ struct complexify template struct complexify { - template + template static void apply(Geometry const& poly, GeometryOut & poly_out, T const& len, Strategy const& strategy) { apply_ring(exterior_ring(poly), exterior_ring(poly_out), - length_threshold, sph); + len, strategy); std::size_t count = boost::size(interior_rings(poly)); range::resize(interior_rings(poly_out), count); @@ -179,15 +181,15 @@ struct complexify { apply_ring(range::at(interior_rings(poly), i), range::at(interior_rings(poly_out), i), - length_threshold, sph); + len, strategy); } } - template - static void apply_ring(Geometry const& ring, GeometryOut & ring_out, + template + static void apply_ring(Ring const& ring, RingOut & ring_out, T const& len, Strategy const& strategy) { - complexify + complexify ::apply(ring, ring_out, len, strategy); } }; @@ -195,27 +197,27 @@ struct complexify template struct complexify { - template + template static void apply(Geometry const& mpoly, GeometryOut & mpoly_out, T const& len, Strategy const& strategy) { std::size_t count = boost::size(mpoly); - range::resize(mpoly_out, mpoly); + range::resize(mpoly_out, count); for (std::size_t i = 0 ; i < count ; ++i) { apply_poly(range::at(mpoly, i), range::at(mpoly_out, i), - length_threshold, sph); + len, strategy); } } - template - static void apply_poly(Geometry const& poly, GeometryOut & poly_out, + template + static void apply_poly(Poly const& poly, PolyOut & poly_out, T const& len, Strategy const& strategy) { - complexify:: - apply(poly, poly_out, length_threshold, strategy); + complexify:: + apply(poly, poly_out, len, strategy); } }; @@ -293,7 +295,7 @@ struct complexify > template void operator()(Geometry const& geometry, Geometry& out) const { - simplify::apply(geometry, out, m_max_distance, m_strategy); + complexify::apply(geometry, out, m_max_distance, m_strategy); } }; @@ -336,7 +338,7 @@ inline void complexify(Geometry const& geometry, Geometry& out, Distance const& max_distance) { - complexify(geometry, out, max_distance, strategy_type()); + complexify(geometry, out, max_distance, default_strategy()); } }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/cartesian/complexify.hpp b/include/boost/geometry/strategies/cartesian/complexify.hpp index 5061a2dd3..9dd8af311 100644 --- a/include/boost/geometry/strategies/cartesian/complexify.hpp +++ b/include/boost/geometry/strategies/cartesian/complexify.hpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include diff --git a/include/boost/geometry/strategies/spherical/complexify.hpp b/include/boost/geometry/strategies/spherical/complexify.hpp index d852725d6..376e58466 100644 --- a/include/boost/geometry/strategies/spherical/complexify.hpp +++ b/include/boost/geometry/strategies/spherical/complexify.hpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include From d3df14abf7e43af77625edba974958f4e9e742d4 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 4 Dec 2017 22:12:11 +0100 Subject: [PATCH 06/19] [test][complexify] Add tests of complexify() algorithm. --- test/algorithms/Jamfile.v2 | 1 + test/algorithms/complexify.cpp | 198 +++++++++++++++++++++++++++++++++ 2 files changed, 199 insertions(+) create mode 100644 test/algorithms/complexify.cpp diff --git a/test/algorithms/Jamfile.v2 b/test/algorithms/Jamfile.v2 index 2806c1a10..1e1f77918 100644 --- a/test/algorithms/Jamfile.v2 +++ b/test/algorithms/Jamfile.v2 @@ -22,6 +22,7 @@ test-suite boost-geometry-algorithms [ run centroid.cpp : : : : algorithms_centroid ] [ run centroid_multi.cpp : : : : algorithms_centroid_multi ] [ run comparable_distance.cpp : : : : algorithms_comparable_distance ] + [ run complexify.cpp : : : : algorithms_complexify ] [ run convert.cpp : : : : algorithms_convert ] [ run convert_multi.cpp : : : : algorithms_convert_multi ] [ run convex_hull.cpp : : : : algorithms_convex_hull ] diff --git a/test/algorithms/complexify.cpp b/test/algorithms/complexify.cpp new file mode 100644 index 000000000..6f3e1f805 --- /dev/null +++ b/test/algorithms/complexify.cpp @@ -0,0 +1,198 @@ +// Boost.Geometry +// Unit Test + +// Copyright (c) 2017, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + + +struct check_lengths +{ + template + void operator()(G const& g, G const& o, S const& s) const + { + double d1 = bg::length(g, s); + double d2 = bg::length(o, s); + + BOOST_CHECK_CLOSE(d1, d2, 0.0001); + } +}; + +struct check_perimeters +{ + template + void operator()(G const& g, G const& o, S const& s) const + { + double d1 = bg::perimeter(g, s); + double d2 = bg::perimeter(o, s); + + BOOST_CHECK_CLOSE(d1, d2, 0.0001); + } +}; + +template +double inline shortest_length(G const& g, DistS const& dist_s) +{ + double min_len = (std::numeric_limits::max)(); + for (bg::segment_iterator it = bg::segments_begin(g); + it != bg::segments_end(g); ++it) + { + double len = bg::length(*it, dist_s); + min_len = (std::min)(min_len, len); + } + return min_len; +} + +template +double inline greatest_length(G const& o, DistS const& dist_s) +{ + double max_len = 0.0; + for (bg::segment_iterator it = bg::segments_begin(o); + it != bg::segments_end(o); ++it) + { + double len = bg::length(*it, dist_s); + max_len = (std::max)(max_len, len); + } + return max_len; +} + +template ::type> +struct cs_data +{}; + +template +struct cs_data +{ + bg::strategy::complexify::cartesian<> compl_s; + bg::strategy::distance::pythagoras<> dist_s; +}; + +template +struct cs_data +{ + cs_data() + : model(6378137.0) + , compl_s(model) + , dist_s(6378137.0) + {} + + bg::srs::sphere model; + bg::strategy::complexify::spherical<> compl_s; + bg::strategy::distance::haversine dist_s; +}; + +template +struct cs_data +{ + cs_data() + : model(6378137.0, 6356752.3142451793) + , compl_s(model) + , dist_s(model) + {} + + bg::srs::spheroid model; + bg::strategy::complexify::geographic<> compl_s; + bg::strategy::distance::geographic<> dist_s; +}; + +template +inline void test_geometry(std::string const& wkt, Check const& check) +{ + cs_data d; + + G g; + bg::read_wkt(wkt, g); + + double max_distance = shortest_length(g, d.dist_s) / 3.0; + + G o; + bg::complexify(g, o, max_distance, d.compl_s); + + // geometry was indeed complexified + std::size_t g_count = bg::num_points(g); + std::size_t o_count = bg::num_points(o); + BOOST_CHECK(g_count < o_count); + + // all segments have lengths smaller or equal to max_distance + double gr_len = greatest_length(o, d.dist_s); + // NOTE: Currently geographic strategies can generate segments that have + // lengths slightly greater than max_distance. In order to change + // this the generation of new points should e.g. be recursive with + // stop condition comparing the current distance calculated by + // inverse strategy. + // NOTE: Closeness value tweaked for Andoyer + bool is_close = (gr_len - max_distance) / (std::max)(gr_len, max_distance) < 0.0001; + BOOST_CHECK(gr_len <= max_distance || is_close); + + // the overall length or perimeter didn't change + check(g, o, d.dist_s); +} + +template +inline void test_linear(std::string const& wkt) +{ + test_geometry(wkt, check_lengths()); +} + +template +inline void test_areal(std::string const& wkt) +{ + test_geometry(wkt, check_perimeters()); +} + +template +void test_all() +{ + typedef bg::model::linestring

ls_t; + typedef bg::model::multi_linestring mls_t; + + typedef bg::model::ring

ring_t; + typedef bg::model::polygon

poly_t; + typedef bg::model::multi_polygon mpoly_t; + + test_linear("LINESTRING(4 -4, 4 -1)"); + test_linear("LINESTRING(4 4, 4 1)"); + test_linear("LINESTRING(0 0, 180 0)"); + test_linear("LINESTRING(1 1, -179 -1)"); + + test_linear("LINESTRING(1 1, 2 2, 4 2)"); + test_linear("MULTILINESTRING((1 1, 2 2),(2 2, 4 2))"); + + test_linear("POLYGON((1 1, 1 2, 2 2, 1 1))"); + test_linear("POLYGON((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1))"); + test_linear("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1)),((4 4, 5 5, 5 4, 4 4)))"); +} + +int test_main(int, char* []) +{ + test_all< bg::model::point >(); + test_all< bg::model::point > >(); + test_all< bg::model::point > >(); + + return 0; +} From b04a0b97b7892a4bb9a2fc367fe83d695533a4d7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 6 Dec 2017 16:15:06 +0100 Subject: [PATCH 07/19] [densify] Rename complexify algorithm and strategies to densify. --- .../{complexify.hpp => densify.hpp} | 70 +++++++++---------- .../cartesian/{complexify.hpp => densify.hpp} | 14 ++-- .../{complexify.hpp => densify.hpp} | 10 +-- .../{complexify.hpp => densify.hpp} | 14 ++-- .../spherical/{complexify.hpp => densify.hpp} | 14 ++-- 5 files changed, 61 insertions(+), 61 deletions(-) rename include/boost/geometry/algorithms/{complexify.hpp => densify.hpp} (82%) rename include/boost/geometry/strategies/cartesian/{complexify.hpp => densify.hpp} (90%) rename include/boost/geometry/strategies/{complexify.hpp => densify.hpp} (71%) rename include/boost/geometry/strategies/geographic/{complexify.hpp => densify.hpp} (90%) rename include/boost/geometry/strategies/spherical/{complexify.hpp => densify.hpp} (93%) diff --git a/include/boost/geometry/algorithms/complexify.hpp b/include/boost/geometry/algorithms/densify.hpp similarity index 82% rename from include/boost/geometry/algorithms/complexify.hpp rename to include/boost/geometry/algorithms/densify.hpp index be7d362af..c4d5ecfe9 100644 --- a/include/boost/geometry/algorithms/complexify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP -#define BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP +#ifndef BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP #include @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include #include @@ -32,7 +32,7 @@ namespace boost { namespace geometry #ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace complexify +namespace detail { namespace densify { template @@ -44,7 +44,7 @@ inline void convert_and_push_back(Range & range, Point const& p) } template -struct complexify_range +struct densify_range { template static inline void apply(Geometry const& rng, GeometryOut & rng_out, @@ -75,13 +75,13 @@ struct complexify_range }; template // false, X -struct complexify_ring +struct densify_ring { template static inline void apply(Geometry const& ring, GeometryOut & ring_out, T const& len, Strategy const& strategy) { - geometry::detail::complexify::complexify_range + geometry::detail::densify::densify_range ::apply(ring, ring_out, len, strategy); if (boost::size(ring) <= 1) @@ -101,17 +101,17 @@ struct complexify_ring }; template <> -struct complexify_ring - : complexify_range +struct densify_ring + : densify_range {}; template <> -struct complexify_ring - : complexify_range +struct densify_ring + : densify_range {}; -}} // namespace detail::complexify +}} // namespace detail::densify #endif // DOXYGEN_NO_DETAIL @@ -127,17 +127,17 @@ template typename Tag1 = typename tag::type, typename Tag2 = typename tag::type > -struct complexify +struct densify : not_implemented {}; template -struct complexify - : geometry::detail::complexify::complexify_range<> +struct densify + : geometry::detail::densify::densify_range<> {}; template -struct complexify +struct densify { template static void apply(Geometry const& mls, GeometryOut & mls_out, @@ -148,7 +148,7 @@ struct complexify + geometry::detail::densify::densify_range<> ::apply(range::at(mls, i), range::at(mls_out, i), len, strategy); } @@ -156,8 +156,8 @@ struct complexify -struct complexify - : geometry::detail::complexify::complexify_ring +struct densify + : geometry::detail::densify::densify_ring < geometry::closure::value != geometry::open, geometry::closure::value != geometry::open @@ -165,7 +165,7 @@ struct complexify {}; template -struct complexify +struct densify { template static void apply(Geometry const& poly, GeometryOut & poly_out, @@ -189,13 +189,13 @@ struct complexify static void apply_ring(Ring const& ring, RingOut & ring_out, T const& len, Strategy const& strategy) { - complexify + densify ::apply(ring, ring_out, len, strategy); } }; template -struct complexify +struct densify { template static void apply(Geometry const& mpoly, GeometryOut & mpoly_out, @@ -216,7 +216,7 @@ struct complexify static void apply_poly(Poly const& poly, PolyOut & poly_out, T const& len, Strategy const& strategy) { - complexify:: + densify:: apply(poly, poly_out, len, strategy); } }; @@ -229,7 +229,7 @@ struct complexify namespace resolve_strategy { -struct complexify +struct densify { template static inline void apply(Geometry const& geometry, @@ -237,7 +237,7 @@ struct complexify Distance const& max_distance, Strategy const& strategy) { - dispatch::complexify + dispatch::densify ::apply(geometry, out, max_distance, strategy); } @@ -247,7 +247,7 @@ struct complexify Distance const& max_distance, default_strategy) { - typedef strategy::complexify::services::default_strategy + typedef strategy::densify::services::default_strategy < typename cs_tag::type > strategy_type; @@ -266,7 +266,7 @@ struct complexify namespace resolve_variant { template -struct complexify +struct densify { template static inline void apply(Geometry const& geometry, @@ -274,12 +274,12 @@ struct complexify Distance const& max_distance, Strategy const& strategy) { - resolve_strategy::complexify::apply(geometry, out, max_distance, strategy); + resolve_strategy::densify::apply(geometry, out, max_distance, strategy); } }; template -struct complexify > +struct densify > { template struct visitor: boost::static_visitor @@ -295,7 +295,7 @@ struct complexify > template void operator()(Geometry const& geometry, Geometry& out) const { - complexify::apply(geometry, out, m_max_distance, m_strategy); + densify::apply(geometry, out, m_max_distance, m_strategy); } }; @@ -318,7 +318,7 @@ struct complexify > template -inline void complexify(Geometry const& geometry, +inline void densify(Geometry const& geometry, Geometry& out, Distance const& max_distance, Strategy const& strategy) @@ -327,20 +327,20 @@ inline void complexify(Geometry const& geometry, geometry::clear(out); - resolve_variant::complexify + resolve_variant::densify < Geometry >::apply(geometry, out, max_distance, strategy); } template -inline void complexify(Geometry const& geometry, +inline void densify(Geometry const& geometry, Geometry& out, Distance const& max_distance) { - complexify(geometry, out, max_distance, default_strategy()); + densify(geometry, out, max_distance, default_strategy()); } }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP +#endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP diff --git a/include/boost/geometry/strategies/cartesian/complexify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp similarity index 90% rename from include/boost/geometry/strategies/cartesian/complexify.hpp rename to include/boost/geometry/strategies/cartesian/densify.hpp index 9dd8af311..0de4817d8 100644 --- a/include/boost/geometry/strategies/cartesian/complexify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP -#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP +#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP #include @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,7 +28,7 @@ namespace boost { namespace geometry { -namespace strategy { namespace complexify +namespace strategy { namespace densify { @@ -108,7 +108,7 @@ namespace services template <> struct default_strategy { - typedef strategy::complexify::cartesian<> type; + typedef strategy::densify::cartesian<> type; }; @@ -116,9 +116,9 @@ struct default_strategy #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -}} // namespace strategy::complexify +}} // namespace strategy::densify }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_COMPLEXIFY_HPP +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DENSIFY_HPP diff --git a/include/boost/geometry/strategies/complexify.hpp b/include/boost/geometry/strategies/densify.hpp similarity index 71% rename from include/boost/geometry/strategies/complexify.hpp rename to include/boost/geometry/strategies/densify.hpp index e70abbd4a..cde061af9 100644 --- a/include/boost/geometry/strategies/complexify.hpp +++ b/include/boost/geometry/strategies/densify.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP -#define BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP +#ifndef BOOST_GEOMETRY_STRATEGIES_DENSIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_DENSIFY_HPP #include @@ -17,7 +17,7 @@ namespace boost { namespace geometry { -namespace strategy { namespace complexify +namespace strategy { namespace densify { namespace services @@ -35,8 +35,8 @@ struct default_strategy } // namespace services -}} // namespace strategy::complexify +}} // namespace strategy::densify }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_STRATEGIES_COMPLEXIFY_HPP +#endif // BOOST_GEOMETRY_STRATEGIES_DENSIFY_HPP diff --git a/include/boost/geometry/strategies/geographic/complexify.hpp b/include/boost/geometry/strategies/geographic/densify.hpp similarity index 90% rename from include/boost/geometry/strategies/geographic/complexify.hpp rename to include/boost/geometry/strategies/geographic/densify.hpp index 44384925c..2555de4f1 100644 --- a/include/boost/geometry/strategies/geographic/complexify.hpp +++ b/include/boost/geometry/strategies/geographic/densify.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_COMPLEXIFY_HPP -#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_COMPLEXIFY_HPP +#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DENSIFY_HPP #include @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include @@ -28,7 +28,7 @@ namespace boost { namespace geometry { -namespace strategy { namespace complexify +namespace strategy { namespace densify { @@ -106,7 +106,7 @@ namespace services template <> struct default_strategy { - typedef strategy::complexify::geographic<> type; + typedef strategy::densify::geographic<> type; }; @@ -114,9 +114,9 @@ struct default_strategy #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -}} // namespace strategy::complexify +}} // namespace strategy::densify }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP +#endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP diff --git a/include/boost/geometry/strategies/spherical/complexify.hpp b/include/boost/geometry/strategies/spherical/densify.hpp similarity index 93% rename from include/boost/geometry/strategies/spherical/complexify.hpp rename to include/boost/geometry/strategies/spherical/densify.hpp index 376e58466..dc9356d8a 100644 --- a/include/boost/geometry/strategies/spherical/complexify.hpp +++ b/include/boost/geometry/strategies/spherical/densify.hpp @@ -7,8 +7,8 @@ // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPLEXIFY_HPP -#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_COMPLEXIFY_HPP +#ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DENSIFY_HPP #include @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -32,7 +32,7 @@ namespace boost { namespace geometry { -namespace strategy { namespace complexify +namespace strategy { namespace densify { @@ -158,7 +158,7 @@ namespace services template <> struct default_strategy { - typedef strategy::complexify::spherical<> type; + typedef strategy::densify::spherical<> type; }; @@ -166,9 +166,9 @@ struct default_strategy #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -}} // namespace strategy::complexify +}} // namespace strategy::densify }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_ALGORITHMS_COMPLEXIFY_HPP +#endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP From 7fa4d057351a34d61765ef75b88ff1a5821729ab Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 6 Dec 2017 16:15:51 +0100 Subject: [PATCH 08/19] [test][densify] Rename complexify in tests to densify. --- test/algorithms/Jamfile.v2 | 2 +- .../{complexify.cpp => densify.cpp} | 19 +++++++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) rename test/algorithms/{complexify.cpp => densify.cpp} (92%) diff --git a/test/algorithms/Jamfile.v2 b/test/algorithms/Jamfile.v2 index 1e1f77918..c0ae853b7 100644 --- a/test/algorithms/Jamfile.v2 +++ b/test/algorithms/Jamfile.v2 @@ -22,7 +22,6 @@ test-suite boost-geometry-algorithms [ run centroid.cpp : : : : algorithms_centroid ] [ run centroid_multi.cpp : : : : algorithms_centroid_multi ] [ run comparable_distance.cpp : : : : algorithms_comparable_distance ] - [ run complexify.cpp : : : : algorithms_complexify ] [ run convert.cpp : : : : algorithms_convert ] [ run convert_multi.cpp : : : : algorithms_convert_multi ] [ run convex_hull.cpp : : : : algorithms_convex_hull ] @@ -30,6 +29,7 @@ test-suite boost-geometry-algorithms [ run correct.cpp : : : : algorithms_correct ] [ run correct_multi.cpp : : : : algorithms_correct_multi ] [ run correct_closure.cpp : : : : algorithms_correct_closure ] + [ run densify.cpp : : : : algorithms_densify ] [ run for_each.cpp : : : : algorithms_for_each ] [ run for_each_multi.cpp : : : : algorithms_for_each_multi ] [ run is_convex.cpp : : : : algorithms_is_convex ] diff --git a/test/algorithms/complexify.cpp b/test/algorithms/densify.cpp similarity index 92% rename from test/algorithms/complexify.cpp rename to test/algorithms/densify.cpp index 6f3e1f805..b262c9667 100644 --- a/test/algorithms/complexify.cpp +++ b/test/algorithms/densify.cpp @@ -13,20 +13,19 @@ #include -#include -#include -#include -#include - +#include #include #include #include #include +#include #include -#include +#include #include +#include +#include #include @@ -88,7 +87,7 @@ struct cs_data template struct cs_data { - bg::strategy::complexify::cartesian<> compl_s; + bg::strategy::densify::cartesian<> compl_s; bg::strategy::distance::pythagoras<> dist_s; }; @@ -102,7 +101,7 @@ struct cs_data {} bg::srs::sphere model; - bg::strategy::complexify::spherical<> compl_s; + bg::strategy::densify::spherical<> compl_s; bg::strategy::distance::haversine dist_s; }; @@ -116,7 +115,7 @@ struct cs_data {} bg::srs::spheroid model; - bg::strategy::complexify::geographic<> compl_s; + bg::strategy::densify::geographic<> compl_s; bg::strategy::distance::geographic<> dist_s; }; @@ -131,7 +130,7 @@ inline void test_geometry(std::string const& wkt, Check const& check) double max_distance = shortest_length(g, d.dist_s) / 3.0; G o; - bg::complexify(g, o, max_distance, d.compl_s); + bg::densify(g, o, max_distance, d.compl_s); // geometry was indeed complexified std::size_t g_count = bg::num_points(g); From 27c82ca4c619e9f6ef8b454dd60f5ce84660523b Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 9 Jan 2018 12:35:31 +0100 Subject: [PATCH 09/19] [densify][strategies] Take AssignPolicy instead of RangeOut in strategies. This allows moving range handling, e.g. push_back() calls from strategies to algorithm. --- include/boost/geometry/algorithms/densify.hpp | 40 ++++++++++++++----- .../geometry/strategies/cartesian/densify.hpp | 21 +++++----- .../strategies/geographic/densify.hpp | 21 +++++----- .../geometry/strategies/spherical/densify.hpp | 21 +++++----- 4 files changed, 58 insertions(+), 45 deletions(-) diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index c4d5ecfe9..6ee60b9c6 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,6 +35,24 @@ namespace boost { namespace geometry namespace detail { namespace densify { +template +struct push_back_policy +{ + typedef typename boost::range_value::type point_type; + + inline explicit push_back_policy(Range & rng) + : m_rng(rng) + {} + + inline void apply(point_type const& p) + { + range::push_back(m_rng, p); + } + +private: + Range & m_rng; +}; + template inline void convert_and_push_back(Range & range, Point const& p) { @@ -57,6 +75,8 @@ struct densify_range if (count == 0) return; + push_back_policy policy(rng_out); + for (std::size_t i = 1 ; i < count ; ++i) { point_t const& p0 = range::at(rng, i - 1); @@ -64,7 +84,7 @@ struct densify_range convert_and_push_back(rng_out, p0); - strategy.apply(p0, p1, rng_out, len); + strategy.apply(p0, p1, policy, len); } if (BOOST_GEOMETRY_CONDITION(AppendLastPoint)) @@ -91,7 +111,9 @@ struct densify_ring point_t const& p0 = range::back(ring); point_t const& p1 = range::front(ring); - strategy.apply(p0, p1, ring_out, len); + push_back_policy policy(ring_out); + + strategy.apply(p0, p1, policy, len); if (BOOST_GEOMETRY_CONDITION(IsClosed2)) { @@ -253,7 +275,7 @@ struct densify > strategy_type; /*BOOST_CONCEPT_ASSERT( - (concepts::ComplexifyStrategy) + (concepts::DensifyStrategy) );*/ apply(geometry, out, max_distance, strategy_type()); @@ -319,9 +341,9 @@ struct densify > template inline void densify(Geometry const& geometry, - Geometry& out, - Distance const& max_distance, - Strategy const& strategy) + Geometry& out, + Distance const& max_distance, + Strategy const& strategy) { concepts::check(); @@ -335,8 +357,8 @@ inline void densify(Geometry const& geometry, template inline void densify(Geometry const& geometry, - Geometry& out, - Distance const& max_distance) + Geometry& out, + Distance const& max_distance) { densify(geometry, out, max_distance, default_strategy()); } diff --git a/include/boost/geometry/strategies/cartesian/densify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp index 0de4817d8..4e4c1253d 100644 --- a/include/boost/geometry/strategies/cartesian/densify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -19,11 +19,8 @@ #include #include #include -#include #include -#include - namespace boost { namespace geometry { @@ -38,14 +35,14 @@ template > struct cartesian { - template - static inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) + template + static inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) { - typedef typename boost::range_value::type rng_point_t; + typedef typename AssignPolicy::point_type out_point_t; typedef typename select_most_precise < typename coordinate_type::type, - typename coordinate_type::type, + typename coordinate_type::type, CalculationType >::type calc_t; @@ -86,16 +83,16 @@ struct cartesian geometry::add_point(pd, xy0); - rng_point_t p; + out_point_t p; geometry::set<0>(p, geometry::get<0>(pd)); geometry::set<1>(p, geometry::get<1>(pd)); geometry::detail::conversion::point_to_point < - Point, rng_point_t, - 2, dimension::value + Point, out_point_t, + 2, dimension::value >::apply(p0, p); - range::push_back(rng, p); + policy.apply(p); } } }; diff --git a/include/boost/geometry/strategies/geographic/densify.hpp b/include/boost/geometry/strategies/geographic/densify.hpp index 2555de4f1..17ae20614 100644 --- a/include/boost/geometry/strategies/geographic/densify.hpp +++ b/include/boost/geometry/strategies/geographic/densify.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -19,11 +19,8 @@ #include #include #include -#include #include -#include - namespace boost { namespace geometry { @@ -48,14 +45,14 @@ struct geographic : m_spheroid(spheroid) {} - template - inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) const + template + inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const { - typedef typename boost::range_value::type rng_point_t; + typedef typename AssignPolicy::point_type out_point_t; typedef typename select_most_precise < typename coordinate_type::type, - typename coordinate_type::type, + typename coordinate_type::type, CalculationType >::type calc_t; @@ -81,16 +78,16 @@ struct geographic current, inv_r.azimuth, m_spheroid); - rng_point_t p; + out_point_t p; set_from_radian<0>(p, dir_r.lon2); set_from_radian<1>(p, dir_r.lat2); geometry::detail::conversion::point_to_point < - Point, rng_point_t, - 2, dimension::value + Point, out_point_t, + 2, dimension::value >::apply(p0, p); - range::push_back(rng, p); + policy.apply(p); } } diff --git a/include/boost/geometry/strategies/spherical/densify.hpp b/include/boost/geometry/strategies/spherical/densify.hpp index dc9356d8a..65d238ba2 100644 --- a/include/boost/geometry/strategies/spherical/densify.hpp +++ b/include/boost/geometry/strategies/spherical/densify.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -23,11 +23,8 @@ #include #include #include -#include #include -#include - namespace boost { namespace geometry { @@ -58,14 +55,14 @@ struct spherical : m_radius(geometry::get_radius<0>(sphere)) {} - template - inline void apply(Point const& p0, Point const& p1, RangeOut & rng, T const& length_threshold) const + template + inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) const { - typedef typename boost::range_value::type rng_point_t; + typedef typename AssignPolicy::point_type out_point_t; typedef typename select_most_precise < typename coordinate_type::type, - typename coordinate_type::type, + typename coordinate_type::type, CalculationType >::type calc_t; @@ -135,14 +132,14 @@ struct spherical geometry::add_point(v_rot, s2); geometry::add_point(v_rot, s3); - rng_point_t p = formula::cart3d_to_sph(v_rot); + out_point_t p = formula::cart3d_to_sph(v_rot); geometry::detail::conversion::point_to_point < - Point, rng_point_t, - 2, dimension::value + Point, out_point_t, + 2, dimension::value >::apply(p0, p); - range::push_back(rng, p); + policy.apply(p); } } From 63562cc81b0d8bf73158702f2912d1de573737aa Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 10 Jan 2018 23:03:52 +0100 Subject: [PATCH 10/19] [densify] Refactor densify_range, implement using iterators. Now it requires FwdRng. --- include/boost/geometry/algorithms/densify.hpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index 6ee60b9c6..09e6e143e 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -64,23 +64,28 @@ inline void convert_and_push_back(Range & range, Point const& p) template struct densify_range { - template - static inline void apply(Geometry const& rng, GeometryOut & rng_out, + template + static inline void apply(FwdRng const& rng, MutRng & rng_out, T const& len, Strategy const& strategy) { - typedef typename boost::range_value::type point_t; + typedef typename boost::range_iterator::type iterator_t; + typedef typename boost::range_value::type point_t; - std::size_t count = boost::size(rng); + iterator_t it = boost::begin(rng); + iterator_t end = boost::end(rng); - if (count == 0) - return; - - push_back_policy policy(rng_out); - - for (std::size_t i = 1 ; i < count ; ++i) + if (it == end) // empty(rng) { - point_t const& p0 = range::at(rng, i - 1); - point_t const& p1 = range::at(rng, i); + return; + } + + push_back_policy policy(rng_out); + + iterator_t prev = it; + for ( ++it ; it != end ; prev = it++) + { + point_t const& p0 = *prev; + point_t const& p1 = *it; convert_and_push_back(rng_out, p0); @@ -89,7 +94,7 @@ struct densify_range if (BOOST_GEOMETRY_CONDITION(AppendLastPoint)) { - convert_and_push_back(rng_out, range::back(rng)); + convert_and_push_back(rng_out, *prev); // back(rng) } } }; From 08dccb11745f6bb26eec35145cb02c63c58b0430 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 10 Jan 2018 23:04:21 +0100 Subject: [PATCH 11/19] [test][densify] Add test cases for open Areal geometries. --- test/algorithms/densify.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/algorithms/densify.cpp b/test/algorithms/densify.cpp index b262c9667..7c78f7ab7 100644 --- a/test/algorithms/densify.cpp +++ b/test/algorithms/densify.cpp @@ -174,6 +174,10 @@ void test_all() typedef bg::model::polygon

poly_t; typedef bg::model::multi_polygon mpoly_t; + typedef bg::model::ring oring_t; + typedef bg::model::polygon opoly_t; + typedef bg::model::multi_polygon ompoly_t; + test_linear("LINESTRING(4 -4, 4 -1)"); test_linear("LINESTRING(4 4, 4 1)"); test_linear("LINESTRING(0 0, 180 0)"); @@ -182,9 +186,16 @@ void test_all() test_linear("LINESTRING(1 1, 2 2, 4 2)"); test_linear("MULTILINESTRING((1 1, 2 2),(2 2, 4 2))"); - test_linear("POLYGON((1 1, 1 2, 2 2, 1 1))"); - test_linear("POLYGON((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1))"); - test_linear("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1)),((4 4, 5 5, 5 4, 4 4)))"); + test_areal("POLYGON((1 1, 1 2, 2 2, 1 1))"); + test_areal("POLYGON((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1))"); + test_areal("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1, 1 1),(1 1, 2 2, 2 3, 1 1)),((4 4, 5 5, 5 4, 4 4)))"); + + test_areal("POLYGON((1 1, 1 2, 2 2))"); + test_areal("POLYGON((1 1, 1 4, 4 4, 4 1),(1 1, 2 2, 2 3))"); + test_areal("MULTIPOLYGON(((1 1, 1 4, 4 4, 4 1),(1 1, 2 2, 2 3)),((4 4, 5 5, 5 4)))"); + + test_areal("POLYGON((0 0,0 40,40 40,40 0,0 0))"); + test_areal("POLYGON((0 0,0 40,40 40,40 0))"); } int test_main(int, char* []) From 3dd641347869c4c5b8af4998c2af882f107ece74 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 10 Jan 2018 23:23:33 +0100 Subject: [PATCH 12/19] [strategies][densify] Support arbitrary dimension in cartesian densify strategy. --- .../geometry/strategies/cartesian/densify.hpp | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/include/boost/geometry/strategies/cartesian/densify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp index 4e4c1253d..326669fe6 100644 --- a/include/boost/geometry/strategies/cartesian/densify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -46,34 +46,35 @@ struct cartesian CalculationType >::type calc_t; - typedef model::point point2d_t; + typedef model::point::value, cs::cartesian> calc_point_t; - point2d_t const xy0(geometry::get<0>(p0), geometry::get<1>(p0)); - point2d_t const xy1(geometry::get<0>(p1), geometry::get<1>(p1)); - // dir01 = xy1 - xy0 - point2d_t dir01 = xy1; - geometry::subtract_point(dir01, xy0); - calc_t const dot01 = geometry::dot_product(dir01, dir01); - calc_t const len2d = math::sqrt(dot01); + calc_point_t cp0, cp1; + geometry::detail::conversion::convert_point_to_point(p0, cp0); + geometry::detail::conversion::convert_point_to_point(p1, cp1); - // TODO: For consistency with spherical and geographic 2d length is - // taken into account. This probably should be changed. Also in the - // other strategies dimensions > 2 should be taken into account. - signed_size_type n = signed_size_type(len2d / length_threshold); + // dir01 = xy1 - xy0 + calc_point_t dir01 = cp1; + geometry::subtract_point(dir01, cp0); + calc_t const dot01 = geometry::dot_product(dir01, dir01); + calc_t const len = math::sqrt(dot01); + + signed_size_type n = signed_size_type(len / length_threshold); if (n <= 0) + { return; + } // NOTE: Normalization will not work for integral coordinates // normalize - //geometry::divide_value(dir01, len2d); + //geometry::divide_value(dir01, len); - calc_t step = len2d / (n + 1); + calc_t step = len / (n + 1); calc_t d = step; for (signed_size_type i = 0 ; i < n ; ++i, d += step) { // pd = xy0 + d * dir01 - point2d_t pd = dir01; + calc_point_t pd = dir01; // without normalization geometry::multiply_value(pd, calc_t(i + 1)); @@ -81,17 +82,14 @@ struct cartesian // with normalization //geometry::multiply_value(pd, d); - geometry::add_point(pd, xy0); + geometry::add_point(pd, cp0); + // NOTE: Only needed if types calc_point_t and out_point_t are different + // otherwise pd could simply be passed into policy out_point_t p; - geometry::set<0>(p, geometry::get<0>(pd)); - geometry::set<1>(p, geometry::get<1>(pd)); - geometry::detail::conversion::point_to_point - < - Point, out_point_t, - 2, dimension::value - >::apply(p0, p); - + assert_dimension_equal(); + geometry::detail::conversion::convert_point_to_point(pd, p); + policy.apply(p); } } From 3daa5956f94e4b64cf75f5444e57daa35411d440 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 10 Jan 2018 23:31:53 +0100 Subject: [PATCH 13/19] [densify][strategies] Throw on invalid max_distance (in algorithm), assert max_distance > 0 (in strategies). --- include/boost/geometry/algorithms/densify.hpp | 8 ++++++++ include/boost/geometry/strategies/cartesian/densify.hpp | 3 +++ include/boost/geometry/strategies/geographic/densify.hpp | 3 +++ include/boost/geometry/strategies/spherical/densify.hpp | 3 +++ 4 files changed, 17 insertions(+) diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index 09e6e143e..48df22644 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -26,6 +27,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -352,6 +355,11 @@ inline void densify(Geometry const& geometry, { concepts::check(); + if (max_distance <= Distance(0)) + { + BOOST_THROW_EXCEPTION(geometry::invalid_input_exception()); + } + geometry::clear(out); resolve_variant::densify diff --git a/include/boost/geometry/strategies/cartesian/densify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp index 326669fe6..939b05c1b 100644 --- a/include/boost/geometry/strategies/cartesian/densify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -58,6 +59,8 @@ struct cartesian calc_t const dot01 = geometry::dot_product(dir01, dir01); calc_t const len = math::sqrt(dot01); + BOOST_GEOMETRY_ASSERT(length_threshold > T(0)); + signed_size_type n = signed_size_type(len / length_threshold); if (n <= 0) { diff --git a/include/boost/geometry/strategies/geographic/densify.hpp b/include/boost/geometry/strategies/geographic/densify.hpp index 17ae20614..a69ec7a63 100644 --- a/include/boost/geometry/strategies/geographic/densify.hpp +++ b/include/boost/geometry/strategies/geographic/densify.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -64,6 +65,8 @@ struct geographic get_as_radian<0>(p1), get_as_radian<1>(p1), m_spheroid); + BOOST_GEOMETRY_ASSERT(length_threshold > T(0)); + signed_size_type n = signed_size_type(inv_r.distance / length_threshold); if (n <= 0) return; diff --git a/include/boost/geometry/strategies/spherical/densify.hpp b/include/boost/geometry/strategies/spherical/densify.hpp index 65d238ba2..2b810c93d 100644 --- a/include/boost/geometry/strategies/spherical/densify.hpp +++ b/include/boost/geometry/strategies/spherical/densify.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,8 @@ struct spherical calc_t const dot01 = geometry::dot_product(xyz0, xyz1); calc_t const angle01 = acos(dot01); + BOOST_GEOMETRY_ASSERT(length_threshold > T(0)); + signed_size_type n = signed_size_type(angle01 * m_radius / length_threshold); if (n <= 0) return; From b7b7e2ef08b27e946477347638d5577b926d506d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 10 Jan 2018 23:33:18 +0100 Subject: [PATCH 14/19] [test][densify] Fix comment. --- test/algorithms/densify.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/algorithms/densify.cpp b/test/algorithms/densify.cpp index 7c78f7ab7..423b0128f 100644 --- a/test/algorithms/densify.cpp +++ b/test/algorithms/densify.cpp @@ -1,7 +1,7 @@ // Boost.Geometry // Unit Test -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -132,7 +132,7 @@ inline void test_geometry(std::string const& wkt, Check const& check) G o; bg::densify(g, o, max_distance, d.compl_s); - // geometry was indeed complexified + // geometry was indeed densified std::size_t g_count = bg::num_points(g); std::size_t o_count = bg::num_points(o); BOOST_CHECK(g_count < o_count); From e99370beaa5119a2776a79bedd4a4c45f675b0c1 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 11 Jan 2018 18:31:42 +0100 Subject: [PATCH 15/19] [geometry] Include densify algorithm and strategies in top-most headers. --- include/boost/geometry/geometry.hpp | 5 +++-- include/boost/geometry/strategies/strategies.hpp | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/geometry.hpp b/include/boost/geometry/geometry.hpp index aa8070110..f81a78c02 100644 --- a/include/boost/geometry/geometry.hpp +++ b/include/boost/geometry/geometry.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014, 2015, 2016. -// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -61,6 +61,7 @@ #include #include #include +#include #include #include #include diff --git a/include/boost/geometry/strategies/strategies.hpp b/include/boost/geometry/strategies/strategies.hpp index e7f3604ab..77076a092 100644 --- a/include/boost/geometry/strategies/strategies.hpp +++ b/include/boost/geometry/strategies/strategies.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014-2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -70,6 +72,7 @@ #include #include +#include #include #include #include @@ -82,6 +85,7 @@ #include #include +#include #include #include #include From f35a4f927eb14706d4c661def150cdf21b6ae35c Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Jan 2018 02:31:06 +0100 Subject: [PATCH 16/19] [doc][densify] Add documentation for densify algorithm and strategies. Change strategies from structs to classes as this is the requirement of the docs generating tool. --- doc/doxy/doxygen_input/groups/groups.hpp | 5 ++ doc/make_qbk.py | 8 +++- doc/quickref.xml | 37 +++++++++------ doc/reference.qbk | 11 ++++- doc/reference/algorithms/densify.qbk | 27 +++++++++++ include/boost/geometry/algorithms/densify.hpp | 46 +++++++++++++++++++ .../geometry/strategies/cartesian/densify.hpp | 13 +++++- .../strategies/geographic/densify.hpp | 15 +++++- .../geometry/strategies/spherical/densify.hpp | 14 +++++- 9 files changed, 156 insertions(+), 20 deletions(-) create mode 100644 doc/reference/algorithms/densify.qbk diff --git a/doc/doxy/doxygen_input/groups/groups.hpp b/doc/doxy/doxygen_input/groups/groups.hpp index 9889ebd76..fabf1f376 100644 --- a/doc/doxy/doxygen_input/groups/groups.hpp +++ b/doc/doxy/doxygen_input/groups/groups.hpp @@ -2,6 +2,10 @@ // // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // 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) @@ -26,6 +30,7 @@ \defgroup covered_by covered_by: detect if a geometry is inside or on the border of another geometry, a.o. point-in-polygon (border included) \defgroup crosses crosses: detect if two geometries crosses each other \defgroup cs coordinate systems +\defgroup densify densify: add points to geometry, keeping shape \defgroup difference difference: difference of two geometries \defgroup disjoint disjoint: detect if geometries are not spatially related \defgroup distance distance: calculate distance between two geometries diff --git a/doc/make_qbk.py b/doc/make_qbk.py index cace58ff8..10824e120 100755 --- a/doc/make_qbk.py +++ b/doc/make_qbk.py @@ -5,6 +5,9 @@ # Copyright (c) 2008-2012 Bruno Lalande, Paris, France. # Copyright (c) 2009-2012 Mateusz Loskot (mateusz@loskot.net), London, UK # Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland +# +# Copyright (c) 2018, Oracle and/or its affiliates. +# Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle # # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -91,7 +94,7 @@ call_doxygen() algorithms = ["append", "assign", "make", "clear" , "area", "buffer", "centroid", "convert", "correct", "covered_by" - , "convex_hull", "crosses", "difference", "disjoint", "distance" + , "convex_hull", "crosses", "densify", "difference", "disjoint", "distance" , "envelope", "equals", "expand", "for_each", "is_empty" , "is_simple", "is_valid", "intersection", "intersects", "length" , "num_geometries", "num_interior_rings", "num_points" @@ -120,7 +123,8 @@ models = ["point", "linestring", "box" , "multi_linestring", "multi_point", "multi_polygon", "referring_segment"] -strategies = ["distance::pythagoras", "distance::pythagoras_box_box" +strategies = ["densify::cartesian", "densify::geographic", "densify::spherical" + , "distance::pythagoras", "distance::pythagoras_box_box" , "distance::pythagoras_point_box", "distance::haversine" , "distance::cross_track", "distance::cross_track_point_box" , "distance::projected_point" diff --git a/doc/quickref.xml b/doc/quickref.xml index 755fdd255..7c96b545f 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -10,8 +10,8 @@ Copyright (c) 2009-2015 Bruno Lalande, Paris, France. Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. - This file was modified by Oracle on 2014, 2015, 2017. - Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. + This file was modified by Oracle on 2014, 2015, 2017, 2018. + Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -389,6 +389,10 @@ + Densify + + densify + Distance distance @@ -410,17 +414,16 @@ for each (point, segment) + + Intersection intersection - - Length length - - + Num_ (counting) num_interior_rings @@ -428,8 +431,6 @@ num_points num_segments - - Perimeter perimeter @@ -439,12 +440,12 @@ relate relation + + Reverse reverse - - Simplify simplify @@ -554,6 +555,14 @@ strategy::convex_hull::graham_andrew + + Densify + + strategy::densify::cartesian + strategy::densify::geographic + strategy::densify::spherical + + Distance @@ -566,6 +575,8 @@ strategy::distance::haversine + + Side @@ -574,8 +585,6 @@ strategy::side::spherical_side_formula - - Simplify @@ -593,7 +602,9 @@ strategy::transform::rotate_transformer - + + + Within strategy::winding diff --git a/doc/reference.qbk b/doc/reference.qbk index 699712399..865989929 100644 --- a/doc/reference.qbk +++ b/doc/reference.qbk @@ -6,8 +6,8 @@ Copyright (c) 2009-2017 Bruno Lalande, Paris, France. Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland. - This file was modified by Oracle on 2014, 2017. - Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. + This file was modified by Oracle on 2014, 2017, 2018. + Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -102,6 +102,10 @@ [include generated/crosses.qbk] [endsect] +[section:densify densify] +[include generated/densify.qbk] +[endsect] + [section:difference difference] [include generated/difference.qbk] [endsect] @@ -332,6 +336,9 @@ [section:strategies Strategies] +[include generated/densify_cartesian.qbk] +[include generated/densify_geographic.qbk] +[include generated/densify_spherical.qbk] [include generated/distance_pythagoras.qbk] [include generated/distance_pythagoras_box_box.qbk] [include generated/distance_pythagoras_point_box.qbk] diff --git a/doc/reference/algorithms/densify.qbk b/doc/reference/algorithms/densify.qbk new file mode 100644 index 000000000..67dad9190 --- /dev/null +++ b/doc/reference/algorithms/densify.qbk @@ -0,0 +1,27 @@ +[/============================================================================ + Boost.Geometry + + Copyright (c) 2018, Oracle and/or its affiliates. + Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + + 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) +=============================================================================/] + +[def __this_function__ densify] + +[heading_conformance_no_ogc __this_function__] +[note PostGIS contains an algorithm ST_Segmentize with the same functionality. + See the [@http://www.postgis.org/docs/ST_Segmentize.html PostGIS documentation]. +] + +[heading Behavior] +The algorithm divides segments of a geometry if they are longer than passed +distance into smaller segments. + +[note The units of the distance depends on strategy. By default in cartesian +they are the units of the coordinate system, in spherical they are radians, +in geographic they are meters on WGS84 spheroid. In order to change this a user +has to create a strategy and pass it explicitly into the algorithm. +] diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index 48df22644..275c2cb9d 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -347,6 +347,33 @@ struct densify > } // namespace resolve_variant +/*! +\brief Densify a geometry using a specified strategy +\ingroup densify +\tparam Geometry \tparam_geometry +\tparam Distance A numerical distance measure +\tparam Strategy A type fulfilling a DensifyStrategy concept +\param geometry Input geometry, to be densified +\param out Output geometry, densified version of the input geometry +\param max_distance Distance threshold (in units depending on strategy) +\param strategy Densify strategy to be used for densification + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/densify.qbk]} + +\qbk{ +[heading Available Strategies] +\* [link geometry.reference.strategies.strategy_densify_cartesian Cartesian] +\* [link geometry.reference.strategies.strategy_densify_spherical Spherical] +\* [link geometry.reference.strategies.strategy_densify_geographic Geographic] +} + +\qbk{ +[/heading Example] +[/densify_strategy] +[/densify_strategy_output] +} +*/ template inline void densify(Geometry const& geometry, Geometry& out, @@ -368,6 +395,24 @@ inline void densify(Geometry const& geometry, >::apply(geometry, out, max_distance, strategy); } + +/*! +\brief Densify a geometry +\ingroup densify +\tparam Geometry \tparam_geometry +\tparam Distance A numerical distance measure +\param geometry Input geometry, to be densified +\param out Output geometry, densified version of the input geometry +\param max_distance Distance threshold (in units depending on coordinate system) + +\qbk{[include reference/algorithms/densify.qbk]} + +\qbk{ +[/heading Example] +[/densify] +[/densify_output] +} +*/ template inline void densify(Geometry const& geometry, Geometry& out, @@ -376,6 +421,7 @@ inline void densify(Geometry const& geometry, densify(geometry, out, max_distance, default_strategy()); } + }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP diff --git a/include/boost/geometry/strategies/cartesian/densify.hpp b/include/boost/geometry/strategies/cartesian/densify.hpp index 939b05c1b..23651637b 100644 --- a/include/boost/geometry/strategies/cartesian/densify.hpp +++ b/include/boost/geometry/strategies/cartesian/densify.hpp @@ -30,12 +30,23 @@ namespace strategy { namespace densify { +/*! +\brief Densification of cartesian segment. +\ingroup strategies +\tparam CalculationType \tparam_calculation + +\qbk{ +[heading See also] +[link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)] +} + */ template < typename CalculationType = void > -struct cartesian +class cartesian { +public: template static inline void apply(Point const& p0, Point const& p1, AssignPolicy & policy, T const& length_threshold) { diff --git a/include/boost/geometry/strategies/geographic/densify.hpp b/include/boost/geometry/strategies/geographic/densify.hpp index a69ec7a63..a2908ea4a 100644 --- a/include/boost/geometry/strategies/geographic/densify.hpp +++ b/include/boost/geometry/strategies/geographic/densify.hpp @@ -30,14 +30,27 @@ namespace strategy { namespace densify { +/*! +\brief Densification of geographic segment. +\ingroup strategies +\tparam FormulaPolicy The geodesic formulas used internally. +\tparam Spheroid The spheroid model. +\tparam CalculationType \tparam_calculation + +\qbk{ +[heading See also] +[link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)] +} + */ template < typename FormulaPolicy = strategy::andoyer, typename Spheroid = srs::spheroid, typename CalculationType = void > -struct geographic +class geographic { +public: geographic() : m_spheroid() {} diff --git a/include/boost/geometry/strategies/spherical/densify.hpp b/include/boost/geometry/strategies/spherical/densify.hpp index 2b810c93d..a9b58dd41 100644 --- a/include/boost/geometry/strategies/spherical/densify.hpp +++ b/include/boost/geometry/strategies/spherical/densify.hpp @@ -34,13 +34,25 @@ namespace strategy { namespace densify { +/*! +\brief Densification of spherical segment. +\ingroup strategies +\tparam Sphere The sphere model. +\tparam CalculationType \tparam_calculation + +\qbk{ +[heading See also] +[link geometry.reference.algorithms.densify.densify_4_with_strategy densify (with strategy)] +} + */ template < typename Sphere = srs::sphere, typename CalculationType = void > -struct spherical +class spherical { +public: // For consistency with area strategy the radius is set to 1 spherical() : m_radius(1.0) From 1cafdc6d43fdfb45db5bfb2bb9b3ccf5069b8997 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Jan 2018 19:23:43 +0100 Subject: [PATCH 17/19] [densify] Fix default strategy type and remove wrong template parameter. --- include/boost/geometry/algorithms/densify.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index 275c2cb9d..e51ecbb97 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -277,10 +277,10 @@ struct densify Distance const& max_distance, default_strategy) { - typedef strategy::densify::services::default_strategy + typedef typename strategy::densify::services::default_strategy < typename cs_tag::type - > strategy_type; + >::type strategy_type; /*BOOST_CONCEPT_ASSERT( (concepts::DensifyStrategy) @@ -413,7 +413,7 @@ inline void densify(Geometry const& geometry, [/densify_output] } */ -template +template inline void densify(Geometry const& geometry, Geometry& out, Distance const& max_distance) From 4b2304c5b790a821a7bbc761f7617163a694f058 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Jan 2018 19:24:42 +0100 Subject: [PATCH 18/19] [test][densify] Test default strategy version of algorithm. --- test/algorithms/densify.cpp | 47 ++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/test/algorithms/densify.cpp b/test/algorithms/densify.cpp index 423b0128f..bf723bbc1 100644 --- a/test/algorithms/densify.cpp +++ b/test/algorithms/densify.cpp @@ -119,26 +119,17 @@ struct cs_data bg::strategy::distance::geographic<> dist_s; }; -template -inline void test_geometry(std::string const& wkt, Check const& check) +template +inline void check_result(G const& g, G const& o, double max_distance, + DistS const& dist_s, Check const& check) { - cs_data d; - - G g; - bg::read_wkt(wkt, g); - - double max_distance = shortest_length(g, d.dist_s) / 3.0; - - G o; - bg::densify(g, o, max_distance, d.compl_s); - // geometry was indeed densified std::size_t g_count = bg::num_points(g); std::size_t o_count = bg::num_points(o); BOOST_CHECK(g_count < o_count); // all segments have lengths smaller or equal to max_distance - double gr_len = greatest_length(o, d.dist_s); + double gr_len = greatest_length(o, dist_s); // NOTE: Currently geographic strategies can generate segments that have // lengths slightly greater than max_distance. In order to change // this the generation of new points should e.g. be recursive with @@ -149,7 +140,35 @@ inline void test_geometry(std::string const& wkt, Check const& check) BOOST_CHECK(gr_len <= max_distance || is_close); // the overall length or perimeter didn't change - check(g, o, d.dist_s); + check(g, o, dist_s); +} + +template +inline void test_geometry(std::string const& wkt, Check const& check) +{ + cs_data d; + + G g; + bg::read_wkt(wkt, g); + + { + bg::default_strategy def_s; + double max_distance = shortest_length(g, def_s) / 3.0; + + G o; + bg::densify(g, o, max_distance); + + check_result(g, o, max_distance, def_s, check); + } + + { + double max_distance = shortest_length(g, d.dist_s) / 3.0; + + G o; + bg::densify(g, o, max_distance, d.compl_s); + + check_result(g, o, max_distance, d.dist_s, check); + } } template From 5f19586ef63539181871a29ea3cd5f20663cd8df Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Jan 2018 19:46:55 +0100 Subject: [PATCH 19/19] [doc][densify] Add examples. --- doc/imports.qbk | 5 ++ doc/reference/algorithms/densify.qbk | 8 ++- doc/src/examples/algorithms/Jamfile.v2 | 7 ++- doc/src/examples/algorithms/densify.cpp | 47 +++++++++++++++++ .../examples/algorithms/densify_strategy.cpp | 50 +++++++++++++++++++ include/boost/geometry/algorithms/densify.hpp | 14 +++--- 6 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 doc/src/examples/algorithms/densify.cpp create mode 100644 doc/src/examples/algorithms/densify_strategy.cpp diff --git a/doc/imports.qbk b/doc/imports.qbk index 6c4863add..fd8aab313 100644 --- a/doc/imports.qbk +++ b/doc/imports.qbk @@ -5,6 +5,9 @@ Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Copyright (c) 2009-2012 Bruno Lalande, Paris, France. + Copyright (c) 2018, Oracle and/or its affiliates. + Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + 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) @@ -27,6 +30,8 @@ [import src/examples/algorithms/convert.cpp] [import src/examples/algorithms/convex_hull.cpp] [import src/examples/algorithms/correct.cpp] +[import src/examples/algorithms/densify.cpp] +[import src/examples/algorithms/densify_strategy.cpp] [import src/examples/algorithms/distance.cpp] [import src/examples/algorithms/difference.cpp] [import src/examples/algorithms/envelope.cpp] diff --git a/doc/reference/algorithms/densify.qbk b/doc/reference/algorithms/densify.qbk index 67dad9190..676e59a13 100644 --- a/doc/reference/algorithms/densify.qbk +++ b/doc/reference/algorithms/densify.qbk @@ -20,8 +20,6 @@ The algorithm divides segments of a geometry if they are longer than passed distance into smaller segments. -[note The units of the distance depends on strategy. By default in cartesian -they are the units of the coordinate system, in spherical they are radians, -in geographic they are meters on WGS84 spheroid. In order to change this a user -has to create a strategy and pass it explicitly into the algorithm. -] +[note The units of the distance depends on strategy. In order to change the +default behavior a user has to create a strategy and pass it explicitly into +the algorithm.] diff --git a/doc/src/examples/algorithms/Jamfile.v2 b/doc/src/examples/algorithms/Jamfile.v2 index 38c39dbd1..9b62521e1 100644 --- a/doc/src/examples/algorithms/Jamfile.v2 +++ b/doc/src/examples/algorithms/Jamfile.v2 @@ -4,10 +4,11 @@ # Copyright (c) 2008-2015 Bruno Lalande, Paris, France. # Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -# This file was modified by Oracle on 2014, 2015. -# Modifications copyright (c) 2014-2015, Oracle and/or its affiliates. +# This file was modified by Oracle on 2014, 2015, 2018. +# Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. # Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +# Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -40,6 +41,8 @@ exe convert : convert.cpp ; exe convex_hull : convex_hull.cpp ; exe correct : correct.cpp ; +exe densify : densify.cpp ; +exe densify_strategy : densify_strategy.cpp ; exe difference : difference.cpp ; exe distance : distance.cpp ; diff --git a/doc/src/examples/algorithms/densify.cpp b/doc/src/examples/algorithms/densify.cpp new file mode 100644 index 000000000..68f7426c6 --- /dev/null +++ b/doc/src/examples/algorithms/densify.cpp @@ -0,0 +1,47 @@ +// Boost.Geometry +// QuickBook Example + +// Copyright (c) 2018, Oracle and/or its affiliates +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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) + +//[densify +//` Shows how to densify a polygon + +#include + +#include +#include +#include + +int main() +{ + typedef boost::geometry::model::d2::point_xy point_type; + typedef boost::geometry::model::polygon polygon_type; + + polygon_type poly; + boost::geometry::read_wkt( + "POLYGON((0 0,0 10,10 10,10 0,0 0),(1 1,4 1,4 4,1 4,1 1))", poly); + + polygon_type res; + + boost::geometry::densify(poly, res, 6.0); + + std::cout << "densified: " << boost::geometry::wkt(res) << std::endl; + + return 0; +} + +//] + +//[densify_output +/*` +Output: +[pre +densified: POLYGON((0 0,0 5,0 10,5 10,10 10,10 5,10 0,5 0,0 0),(1 1,4 1,4 4,1 4,1 1)) +] +*/ +//] diff --git a/doc/src/examples/algorithms/densify_strategy.cpp b/doc/src/examples/algorithms/densify_strategy.cpp new file mode 100644 index 000000000..eb9934995 --- /dev/null +++ b/doc/src/examples/algorithms/densify_strategy.cpp @@ -0,0 +1,50 @@ +// Boost.Geometry +// QuickBook Example + +// Copyright (c) 2018, Oracle and/or its affiliates +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// 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) + +//[densify_strategy +//` Shows how to densify a linestring in geographic coordinate system + +#include + +#include +#include +#include + +int main() +{ + namespace bg = boost::geometry; + typedef bg::model::point > point_type; + typedef bg::model::linestring linestring_type; + + linestring_type ls; + bg::read_wkt("LINESTRING(0 0,1 1)", ls); + + linestring_type res; + + bg::srs::spheroid spheroid(6378137.0, 6356752.3142451793); + bg::strategy::densify::geographic<> strategy(spheroid); + + boost::geometry::densify(ls, res, 50000.0, strategy); + + std::cout << "densified: " << boost::geometry::wkt(res) << std::endl; + + return 0; +} + +//] + +//[densify_strategy_output +/*` +Output: +[pre +densified: LINESTRING(0 0,0.249972 0.250011,0.499954 0.500017,0.749954 0.750013,1 1) +] +*/ +//] diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp index e51ecbb97..ed948b346 100644 --- a/include/boost/geometry/algorithms/densify.hpp +++ b/include/boost/geometry/algorithms/densify.hpp @@ -366,12 +366,10 @@ struct densify > \* [link geometry.reference.strategies.strategy_densify_cartesian Cartesian] \* [link geometry.reference.strategies.strategy_densify_spherical Spherical] \* [link geometry.reference.strategies.strategy_densify_geographic Geographic] -} -\qbk{ -[/heading Example] -[/densify_strategy] -[/densify_strategy_output] +[heading Example] +[densify_strategy] +[densify_strategy_output] } */ template @@ -408,9 +406,9 @@ inline void densify(Geometry const& geometry, \qbk{[include reference/algorithms/densify.qbk]} \qbk{ -[/heading Example] -[/densify] -[/densify_output] +[heading Example] +[densify] +[densify_output] } */ template