void test_all(ut_settings const& settings_for_sensitive_cases)
{
- typedef bg::model::ring ring;
- typedef bg::model::polygon
polygon;
+ typedef bg::model::ring
ring;
+ typedef bg::model::polygon
polygon;
typedef bg::model::multi_polygon multi_polygon;
- TEST_DISSOLVE(dissolve_1, 8.0, 1, 0, 6);
+ TEST_DISSOLVE(dissolve_1, 8.0, 1, 0, 4);
TEST_DISSOLVE(dissolve_2, 7.9296875, 1, 1, 12);
TEST_DISSOLVE(dissolve_3, 4.0, 2, 0, 8);
TEST_DISSOLVE(dissolve_4, 8.0, 2, 0, 8);
TEST_DISSOLVE(dissolve_5, 12.0, 2, 0, 8);
- TEST_DISSOLVE(dissolve_6, 16.0, 1, 0, 6);
+ TEST_DISSOLVE(dissolve_6, 16.0, 1, 0, 5);
TEST_DISSOLVE(dissolve_7, 50.48056402439, 1, 0, 7);
TEST_DISSOLVE(dissolve_8, 25.6158412, 1, 0, 11);
@@ -563,22 +598,27 @@ void test_all(ut_settings const& settings_for_sensitive_cases)
TEST_DISSOLVE(dissolve_14, 4.0, 3, 0, 13);
TEST_DISSOLVE(dissolve_15, 4.0, 3, 0, 13);
-#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
- TEST_DISSOLVE(dissolve_16, 99999.0, 9, 99, 999);
-#endif
+ TEST_DISSOLVE(dissolve_16, 8.2667, 8, 0, 38);
+
+ TEST_DISSOLVE(dissolve_17, 14.5, 2, 0, 11);
+ TEST_DISSOLVE(dissolve_18, 15.0, 3, 0, 15);
TEST_DISSOLVE(dissolve_d1, 8.0, 1, 0, 4);
- TEST_DISSOLVE(dissolve_d2, 16.0, 1, 0, 10);
+ TEST_DISSOLVE(dissolve_d2, 16.0, 1, 0, 5);
- TEST_DISSOLVE(dissolve_h1_a, 16.0, 1, 0, 6);
- TEST_DISSOLVE(dissolve_h1_b, 14.0, 1, 1, 10);
- TEST_DISSOLVE(dissolve_h2, 16.25, 1, 0, 8);
- TEST_DISSOLVE(dissolve_h3, 16.0, 1, 0, 5); // no generated hole (yet)
- TEST_DISSOLVE(dissolve_h4, 14.484848, 1, 1, 9);
+ TEST_DISSOLVE(dissolve_h1_a, 14.0, 1, 1, 9);
+ TEST_DISSOLVE(dissolve_h1_b, 14.0, 1, 1, 9);
+ TEST_DISSOLVE(dissolve_h2, 12.5, 2, 0, 13);
+ TEST_DISSOLVE(dissolve_h3, 10.75, 1, 1, 14);
+ TEST_DISSOLVE(dissolve_h4, 14.3447, 1, 3, 17);
+
+ TEST_DISSOLVE(dissolve_star_a, 7.38821, 2, 0, 15);
+ TEST_DISSOLVE(dissolve_star_b, 7.28259, 2, 0, 15);
+ TEST_DISSOLVE(dissolve_star_c, 7.399696, 1, 0, 11);
TEST_DISSOLVE(dissolve_mail_2017_09_24_a, 0.5, 2, 0, 8);
- TEST_DISSOLVE(dissolve_mail_2017_09_24_b, 16.0, 1, 0, 6);
+ TEST_DISSOLVE(dissolve_mail_2017_09_24_b, 16.0, 1, 0, 5);
TEST_DISSOLVE(dissolve_mail_2017_09_24_c, 0.5, 2, 0, 8);
TEST_DISSOLVE(dissolve_mail_2017_09_24_d, 0.5, 1, 0, 4);
TEST_DISSOLVE(dissolve_mail_2017_09_24_e, 0.001801138128, 5, 0, 69);
@@ -588,7 +628,7 @@ void test_all(ut_settings const& settings_for_sensitive_cases)
TEST_DISSOLVE(dissolve_mail_2017_09_24_h, 0.5, 1, 0, 4);
TEST_DISSOLVE(dissolve_mail_2017_10_26_a, 7.0, 1, 1, 12);
- TEST_DISSOLVE(dissolve_mail_2017_10_26_b, 16.0, 1, 0, 7);
+ TEST_DISSOLVE(dissolve_mail_2017_10_26_b, 16.0, 1, 0, 5);
TEST_DISSOLVE(dissolve_mail_2017_10_26_c, 6.0, 1, 0, 6);
TEST_DISSOLVE(dissolve_mail_2017_10_30_a, 0.0001241171, 2, 0, 9);
@@ -601,31 +641,27 @@ void test_all(ut_settings const& settings_for_sensitive_cases)
TEST_MULTI(multi_simplex_four, 20.7581, 1, 0, 18);
TEST_MULTI(multi_disjoint, 24.0, 4, 0, 16);
TEST_MULTI(multi_new_interior, 19.5206, 1, 1, 18);
- TEST_MULTI(ggl_list_20110307_javier_01_a, 6400.0, 2, 0, 14);
+ TEST_MULTI(ggl_list_20110307_javier_01_a, 6400.0, 2, 0, 11);
- TEST_DISSOLVE(ggl_list_20110307_javier_01_b, 3993600.0, 1, 2, 19);
+ TEST_DISSOLVE(ggl_list_20110307_javier_01_b, 3993600.0, 1, 2, 16);
TEST_DISSOLVE_WITH(dissolve_ticket17, 0.00920834633689, 1, 1, 228,
settings_for_sensitive_cases);
TEST_DISSOLVE_WITH(dissolve_reallife, 91756.916526794434, 1, 0, 25,
settings_for_sensitive_cases);
-#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
- // To fix this, and ggl_list_denis, it is necessary to follow in both
- // positive AND negative direction, which is not supported yet.
- TEST_DISSOLVE(gitter_2013_04_a, 99999.0, 9, 99, 999);
-#endif
+ TEST_DISSOLVE(gitter_2013_04_a, 3043.9181, 3, 0, 21);
TEST_DISSOLVE(gitter_2013_04_b, 31210.429356259738, 1, 0, 11);
-#ifdef BOOST_GEOMETRY_TEST_INCLUDE_FAILING_TESTS
- TEST_DISSOLVE(ggl_list_denis, 99999.0, 9, 99, 999);
-#endif
+ TEST_DISSOLVE(ggl_list_denis, 21123.3281, 2, 0, 22);
}
int test_main(int, char* [])
{
- test_all >(ut_settings(0.01));
- test_all >(ut_settings());
+ test_all, true >(ut_settings(0.01));
+ test_all, true >(ut_settings());
+ // Counter clockwise input does not work correctly in all cases, it is
+ // partly a problem of the test itself
return 0;
}
diff --git a/extensions/test/gis/Jamfile.v2 b/extensions/test/gis/Jamfile.v2
index ac76bde76..bc67517dd 100644
--- a/extensions/test/gis/Jamfile.v2
+++ b/extensions/test/gis/Jamfile.v2
@@ -5,11 +5,14 @@
# Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
# Copyright (c) 2015 Adam Wulkiewicz, Lodz, Poland.
#
+# This file was modified by Oracle on 2017.
+# Modifications copyright (c) 2017, 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)
build-project io ;
build-project latlong ;
-build-project projections ;
diff --git a/extensions/test/gis/projections/Jamfile.v2 b/extensions/test/gis/projections/Jamfile.v2
deleted file mode 100644
index 8e68c39a3..000000000
--- a/extensions/test/gis/projections/Jamfile.v2
+++ /dev/null
@@ -1,18 +0,0 @@
-# Boost.Geometry (aka GGL, Generic Geometry Library)
-#
-# Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
-# Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
-# Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-#
-# 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)
-
-test-suite boost-geometry-extensions-gis-projections
- :
- [ run projection.cpp ]
- [ run projections.cpp ]
- [ run projections_combined.cpp ]
- [ run projections_static.cpp ]
- [ run projection_epsg.cpp ]
- ;
diff --git a/extensions/test/gis/projections/projections_combined.cpp b/extensions/test/gis/projections/projections_combined.cpp
deleted file mode 100644
index 7e77722ad..000000000
--- a/extensions/test/gis/projections/projections_combined.cpp
+++ /dev/null
@@ -1,121 +0,0 @@
-// Boost.Geometry (aka GGL, Generic Geometry Library)
-// Unit Test
-
-// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
-
-// 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)
-
-
-#if defined(_MSC_VER)
-#pragma warning( disable : 4305 ) // truncation double -> float
-#endif // defined(_MSC_VER)
-
-#include
-
-#include
-#include
-
-#include
-#include
-#include
-
-
-#include
-#include
-
-#include
-#include
-#include
-#include
-
-
-template class Projection, typename GeoPoint>
-void test_forward(GeoPoint const& geo_point1, GeoPoint const& geo_point2,
- std::string const& parameters, int deviation = 1)
-{
- typedef typename bg::coordinate_type::type coordinate_type;
- typedef bg::model::d2::point_xy cartesian_point_type;
- typedef Projection projection_type;
-
- try
- {
- bg::projections::parameters par = bg::projections::detail::pj_init_plus(parameters);
-
- projection_type prj(par);
-
- cartesian_point_type xy1, xy2;
- prj.forward(geo_point1, xy1);
- prj.forward(geo_point2, xy2);
-
- // Calculate distances in KM
- int const distance_expected = static_cast(bg::distance(geo_point1, geo_point2) / 1000.0);
- int const distance_found = static_cast(bg::distance(xy1, xy2) / 1000.0);
-
- int const difference = std::abs(distance_expected - distance_found);
- BOOST_CHECK_MESSAGE(difference <= 1 || difference == deviation,
- " projection: " << projection_type::get_name()
- << " distance found: " << distance_found
- << " expected: " << distance_expected);
-
-// For debug:
-// std::cout << projection_type::get_name() << " " << distance_expected
-// << " " << distance_found
-// << " " << (difference > 1 && difference != deviation ? " *** WRONG ***" : "")
-// << " " << difference
-// << std::endl;
- }
- catch(bg::projections::proj_exception const& e)
- {
- std::cout << "Exception in " << projection_type::get_name() << " : " << e.code() << std::endl;
- }
- catch(...)
- {
- std::cout << "Exception (unknown) in " << projection_type::get_name() << std::endl;
- }
-}
-
-template
-void test_all()
-{
- typedef bg::model::ll::point geo_point_type;
-
- geo_point_type amsterdam = bg::make(4.8925, 52.3731);
- geo_point_type utrecht = bg::make(5.1213, 52.0907);
-
- geo_point_type anchorage = bg::make(-149.90, 61.22);
- geo_point_type juneau = bg::make(-134.42, 58.30);
-
- geo_point_type auckland = bg::make(174.74, -36.84);
- geo_point_type wellington = bg::make(177.78, -41.29);
-
- geo_point_type aspen = bg::make(-106.84, 39.19);
- geo_point_type denver = bg::make(-104.88, 39.76);
-
- // IGH (internally using moll/sinu)
- test_forward(amsterdam, utrecht, "+ellps=sphere +units=m", 5);
- test_forward(aspen, denver, "+ellps=sphere +units=m", 3);
- test_forward(auckland, wellington, "+ellps=sphere +units=m", 152);
- test_forward(anchorage, juneau, "+ellps=sphere +units=m", 28);
-
- // Using moll
- test_forward(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 4);
- test_forward(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 5);
- test_forward(aspen, denver, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 19);
- test_forward(aspen, denver, "+ellps=WGS84 +units=m +o_proj=moll +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 19);
-
- // Using sinu
- test_forward(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=sinu +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 5);
- test_forward(amsterdam, utrecht, "+ellps=WGS84 +units=m +o_proj=sinu +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 4);
- test_forward(aspen, denver, "+ellps=WGS84 +units=m +o_proj=sinu +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 14);
- test_forward(aspen, denver, "+ellps=WGS84 +units=m +o_proj=sinu +o_lat_p=10 +o_lon_p=90 +o_lon_o=11.50", 6);
-
-}
-
-int test_main(int, char* [])
-{
- test_all();
-
- return 0;
-}
diff --git a/include/boost/geometry/algorithms/area.hpp b/include/boost/geometry/algorithms/area.hpp
index 18aea2403..c6e237e7c 100644
--- a/include/boost/geometry/algorithms/area.hpp
+++ b/include/boost/geometry/algorithms/area.hpp
@@ -3,9 +3,10 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
-// This file was modified by Oracle on 2017.
-// Modifications copyright (c) 2017 Oracle and/or its affiliates.
+// This file was modified by Oracle on 2017, 2018.
+// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -19,7 +20,6 @@
#define BOOST_GEOMETRY_ALGORITHMS_AREA_HPP
#include
-#include
#include
#include
@@ -43,7 +43,9 @@
#include
#include
+#include
#include
+#include
#include
@@ -56,6 +58,7 @@
namespace boost { namespace geometry
{
+
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace area
{
@@ -83,10 +86,10 @@ template
struct ring_area
{
template
- static inline typename Strategy::return_type
+ static inline typename area_result::type
apply(Ring const& ring, Strategy const& strategy)
{
- BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy) );
+ BOOST_CONCEPT_ASSERT( (geometry::concepts::AreaStrategy) );
assert_dimension();
// Ignore warning (because using static method sometimes) on strategy
@@ -98,7 +101,7 @@ struct ring_area
if (boost::size(ring)
< core_detail::closure::minimum_ring_size::value)
{
- return typename Strategy::return_type();
+ return typename area_result::type();
}
typedef typename reversible_view::type rview_type;
@@ -110,7 +113,7 @@ struct ring_area
rview_type rview(ring);
view_type view(rview);
- typename Strategy::state_type state;
+ typename Strategy::template state state;
iterator_type it = boost::begin(view);
iterator_type end = boost::end(view);
@@ -144,9 +147,13 @@ template
struct area : detail::calculate_null
{
template
- static inline typename Strategy::return_type apply(Geometry const& geometry, Strategy const& strategy)
+ static inline typename area_result::type
+ apply(Geometry const& geometry, Strategy const& strategy)
{
- return calculate_null::apply(geometry, strategy);
+ return calculate_null::apply
+ <
+ typename area_result::type
+ >(geometry, strategy);
}
};
@@ -170,10 +177,11 @@ template
struct area : detail::calculate_polygon_sum
{
template
- static inline typename Strategy::return_type apply(Polygon const& polygon, Strategy const& strategy)
+ static inline typename area_result::type
+ apply(Polygon const& polygon, Strategy const& strategy)
{
return calculate_polygon_sum::apply<
- typename Strategy::return_type,
+ typename area_result::type,
detail::area::ring_area
<
order_as_direction::value>::value,
@@ -188,12 +196,12 @@ template
struct area : detail::multi_sum
{
template
- static inline typename Strategy::return_type
+ static inline typename area_result::type
apply(MultiGeometry const& multi, Strategy const& strategy)
{
return multi_sum::apply
<
- typename Strategy::return_type,
+ typename area_result::type,
area::type>
>(multi, strategy);
}
@@ -204,39 +212,73 @@ struct area : detail::multi_sum
#endif // DOXYGEN_NO_DISPATCH
-namespace resolve_variant {
+namespace resolve_strategy
+{
+
+struct area
+{
+ template
+ static inline typename area_result::type
+ apply(Geometry const& geometry, Strategy const& strategy)
+ {
+ return dispatch::area::apply(geometry, strategy);
+ }
+
+ template
+ static inline typename area_result::type
+ apply(Geometry const& geometry, default_strategy)
+ {
+ typedef typename strategy::area::services::default_strategy
+ <
+ typename cs_tag::type
+ >::type strategy_type;
+
+ return dispatch::area::apply(geometry, strategy_type());
+ }
+};
+
+
+} // namespace resolve_strategy
+
+
+namespace resolve_variant
+{
template
struct area
{
template
- static inline typename Strategy::return_type apply(Geometry const& geometry,
- Strategy const& strategy)
+ static inline typename area_result::type
+ apply(Geometry const& geometry, Strategy const& strategy)
{
- return dispatch::area::apply(geometry, strategy);
+ return resolve_strategy::area::apply(geometry, strategy);
}
};
template
struct area >
{
+ typedef boost::variant variant_type;
+
template
- struct visitor: boost::static_visitor
+ struct visitor
+ : boost::static_visitor::type>
{
Strategy const& m_strategy;
visitor(Strategy const& strategy): m_strategy(strategy) {}
template
- typename Strategy::return_type operator()(Geometry const& geometry) const
+ typename area_result::type
+ operator()(Geometry const& geometry) const
{
return area::apply(geometry, m_strategy);
}
};
template
- static inline typename Strategy::return_type
- apply(boost::variant const& geometry,
+ static inline typename area_result::type
+ apply(variant_type const& geometry,
Strategy const& strategy)
{
return boost::apply_visitor(visitor(strategy), geometry);
@@ -268,22 +310,14 @@ and Geographic as well.
\qbk{[area] [area_output]}
*/
template
-inline typename default_area_result::type area(Geometry const& geometry)
+inline typename area_result::type
+area(Geometry const& geometry)
{
concepts::check();
- // TODO put this into a resolve_strategy stage
- // (and take the return type from resolve_variant)
- typedef typename point_type::type point_type;
- typedef typename strategy::area::services::default_strategy
- <
- typename cs_tag::type,
- point_type
- >::type strategy_type;
-
// detail::throw_on_empty_input(geometry);
- return resolve_variant::area::apply(geometry, strategy_type());
+ return resolve_variant::area::apply(geometry, default_strategy());
}
/*!
@@ -301,19 +335,19 @@ inline typename default_area_result::type area(Geometry const& geometr
\qbk{
[include reference/algorithms/area.qbk]
+[heading Available Strategies]
+\* [link geometry.reference.strategies.strategy_area_cartesian Cartesian]
+\* [link geometry.reference.strategies.strategy_area_spherical Spherical]
+\* [link geometry.reference.strategies.strategy_area_geographic Geographic]
+
[heading Example]
[area_with_strategy]
[area_with_strategy_output]
-
-[heading Available Strategies]
-\* [link geometry.reference.strategies.strategy_area_surveyor Surveyor (cartesian)]
-\* [link geometry.reference.strategies.strategy_area_spherical Spherical]
-[/link geometry.reference.strategies.strategy_area_geographic Geographic]
}
*/
template
-inline typename Strategy::return_type area(
- Geometry const& geometry, Strategy const& strategy)
+inline typename area_result::type
+area(Geometry const& geometry, Strategy const& strategy)
{
concepts::check();
diff --git a/include/boost/geometry/algorithms/convert.hpp b/include/boost/geometry/algorithms/convert.hpp
index 6a8ba1acb..6ccaa0dd4 100644
--- a/include/boost/geometry/algorithms/convert.hpp
+++ b/include/boost/geometry/algorithms/convert.hpp
@@ -5,6 +5,10 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// This file was modified by Oracle on 2017.
+// Modifications copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -29,10 +33,8 @@
#include
#include
-#include
#include
#include
-#include
#include
#include
#include
@@ -153,7 +155,23 @@ struct range_to_range
geometry::closure::value
>::type view_type;
+ struct default_policy
+ {
+ template
+ static inline void apply(Point1 const& point1, Point2 & point2)
+ {
+ geometry::detail::conversion::convert_point_to_point(point1, point2);
+ }
+ };
+
static inline void apply(Range1 const& source, Range2& destination)
+ {
+ apply(source, destination, default_policy());
+ }
+
+ template
+ static inline ConvertPointPolicy apply(Range1 const& source, Range2& destination,
+ ConvertPointPolicy convert_point)
{
geometry::clear(destination);
@@ -179,8 +197,12 @@ struct range_to_range
it != boost::end(view) && i < n;
++it, ++i)
{
- geometry::append(destination, *it);
+ typename boost::range_value::type point;
+ convert_point.apply(*it, point);
+ range::push_back(destination, point);
}
+
+ return convert_point;
}
};
diff --git a/include/boost/geometry/algorithms/correct.hpp b/include/boost/geometry/algorithms/correct.hpp
index 07e012faf..21b9977ce 100644
--- a/include/boost/geometry/algorithms/correct.hpp
+++ b/include/boost/geometry/algorithms/correct.hpp
@@ -3,7 +3,7 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
-// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
+// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
@@ -144,7 +144,7 @@ struct correct_ring
detail::correct_closure::close_or_open_ring::apply(r);
// Check area
- typedef typename Strategy::return_type area_result_type;
+ typedef typename area_result::type area_result_type;
Predicate predicate;
area_result_type const zero = 0;
if (predicate(ring_area_type::apply(r, strategy), zero))
@@ -322,8 +322,7 @@ inline void correct(Geometry& geometry)
typedef typename strategy::area::services::default_strategy
<
- typename cs_tag::type,
- point_type
+ typename cs_tag::type
>::type strategy_type;
resolve_variant::correct::apply(geometry, strategy_type());
diff --git a/include/boost/geometry/algorithms/densify.hpp b/include/boost/geometry/algorithms/densify.hpp
new file mode 100644
index 000000000..ed948b346
--- /dev/null
+++ b/include/boost/geometry/algorithms/densify.hpp
@@ -0,0 +1,425 @@
+// Boost.Geometry
+
+// Copyright (c) 2017-2018, 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_DENSIFY_HPP
+#define BOOST_GEOMETRY_ALGORITHMS_DENSIFY_HPP
+
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+
+namespace boost { namespace geometry
+{
+
+
+#ifndef DOXYGEN_NO_DETAIL
+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)
+{
+ typename boost::range_value::type p2;
+ geometry::detail::conversion::convert_point_to_point(p, p2);
+ range::push_back(range, p2);
+}
+
+template
+struct densify_range
+{
+ template
+ static inline void apply(FwdRng const& rng, MutRng & rng_out,
+ T const& len, Strategy const& strategy)
+ {
+ typedef typename boost::range_iterator::type iterator_t;
+ typedef typename boost::range_value::type point_t;
+
+ iterator_t it = boost::begin(rng);
+ iterator_t end = boost::end(rng);
+
+ if (it == end) // empty(rng)
+ {
+ 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);
+
+ strategy.apply(p0, p1, policy, len);
+ }
+
+ if (BOOST_GEOMETRY_CONDITION(AppendLastPoint))
+ {
+ convert_and_push_back(rng_out, *prev); // back(rng)
+ }
+ }
+};
+
+template // false, X
+struct densify_ring
+{
+ template
+ static inline void apply(Geometry const& ring, GeometryOut & ring_out,
+ T const& len, Strategy const& strategy)
+ {
+ geometry::detail::densify::densify_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);
+
+ push_back_policy policy(ring_out);
+
+ strategy.apply(p0, p1, policy, len);
+
+ if (BOOST_GEOMETRY_CONDITION(IsClosed2))
+ {
+ convert_and_push_back(ring_out, p1);
+ }
+ }
+};
+
+template <>
+struct densify_ring
+ : densify_range
+{};
+
+template <>
+struct densify_ring
+ : densify_range
+{};
+
+
+}} // namespace detail::densify
+#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 densify
+ : not_implemented
+{};
+
+template
+struct densify
+ : geometry::detail::densify::densify_range<>
+{};
+
+template
+struct densify
+{
+ 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::densify::densify_range<>
+ ::apply(range::at(mls, i), range::at(mls_out, i),
+ len, strategy);
+ }
+ }
+};
+
+template
+struct densify
+ : geometry::detail::densify::densify_ring
+ <
+ geometry::closure::value != geometry::open,
+ geometry::closure::value != geometry::open
+ >
+{};
+
+template
+struct densify
+{
+ 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),
+ len, strategy);
+
+ 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),
+ len, strategy);
+ }
+ }
+
+ template
+ static void apply_ring(Ring const& ring, RingOut & ring_out,
+ T const& len, Strategy const& strategy)
+ {
+ densify
+ ::apply(ring, ring_out, len, strategy);
+ }
+};
+
+template
+struct densify
+{
+ 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, count);
+
+ for (std::size_t i = 0 ; i < count ; ++i)
+ {
+ apply_poly(range::at(mpoly, i),
+ range::at(mpoly_out, i),
+ len, strategy);
+ }
+ }
+
+ template
+ static void apply_poly(Poly const& poly, PolyOut & poly_out,
+ T const& len, Strategy const& strategy)
+ {
+ densify::
+ apply(poly, poly_out, len, strategy);
+ }
+};
+
+
+} // namespace dispatch
+#endif // DOXYGEN_NO_DISPATCH
+
+
+namespace resolve_strategy
+{
+
+struct densify
+{
+ template
+ static inline void apply(Geometry const& geometry,
+ Geometry& out,
+ Distance const& max_distance,
+ Strategy const& strategy)
+ {
+ dispatch::densify
+ ::apply(geometry, out, max_distance, strategy);
+ }
+
+ template
+ static inline void apply(Geometry const& geometry,
+ Geometry& out,
+ Distance const& max_distance,
+ default_strategy)
+ {
+ typedef typename strategy::densify::services::default_strategy
+ <
+ typename cs_tag