summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/geometry/test/algorithms/distance
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 18:24:20 +0000
commit483eb2f56657e8e7f419ab1a4fab8dce9ade8609 (patch)
treee5d88d25d870d5dedacb6bbdbe2a966086a0a5cf /src/boost/libs/geometry/test/algorithms/distance
parentInitial commit. (diff)
downloadceph-upstream.tar.xz
ceph-upstream.zip
Adding upstream version 14.2.21.upstream/14.2.21upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/boost/libs/geometry/test/algorithms/distance')
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/Jamfile.v235
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance.cpp536
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_all.cpp20
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp1356
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_ar_ar.cpp437
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_ar.cpp972
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_l.cpp321
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_ar.cpp671
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_l.cpp318
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_pl.cpp123
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_geo_linear_box.cpp567
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_geo_pl_l.cpp728
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_ar_ar.cpp943
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_ar.cpp651
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_l.cpp286
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_ar.cpp687
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_pl.cpp122
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_l.cpp556
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_pl.cpp299
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/test_distance.hpp138
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/test_distance_common.hpp611
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/test_distance_geo_common.hpp577
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/test_distance_se_common.hpp381
-rw-r--r--src/boost/libs/geometry/test/algorithms/distance/test_empty_geometry.hpp213
24 files changed, 11548 insertions, 0 deletions
diff --git a/src/boost/libs/geometry/test/algorithms/distance/Jamfile.v2 b/src/boost/libs/geometry/test/algorithms/distance/Jamfile.v2
new file mode 100644
index 00000000..beebe9d4
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/Jamfile.v2
@@ -0,0 +1,35 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
+# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
+# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+#
+# 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 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
+# http://www.boost.org/LICENSE_1_0.txt)
+
+test-suite boost-geometry-algorithms-distance
+ :
+ [ run distance.cpp : : : : algorithms_distance ]
+ [ run distance_ca_ar_ar.cpp : : : : algorithms_distance_ca_ar_ar ]
+ [ run distance_ca_l_ar.cpp : : : : algorithms_distance_ca_l_ar ]
+ [ run distance_ca_l_l.cpp : : : : algorithms_distance_ca_l_l ]
+ [ run distance_ca_pl_ar.cpp : : : : algorithms_distance_ca_pl_ar ]
+ [ run distance_ca_pl_l.cpp : : : : algorithms_distance_ca_pl_l ]
+ [ run distance_ca_pl_pl.cpp : : : : algorithms_distance_ca_pl_pl ]
+ [ run distance_se_geo_ar_ar.cpp : : : : algorithms_distance_se_geo_ar_ar ]
+ [ run distance_se_geo_l_ar.cpp : : : : algorithms_distance_se_geo_l_ar ]
+ [ run distance_se_geo_l_l.cpp : : : : algorithms_distance_se_geo_l_l ]
+ [ run distance_se_geo_pl_ar.cpp : : : : algorithms_distance_se_geo_pl_ar ]
+ [ run distance_geo_pl_l.cpp : : : : algorithms_distance_geo_pl_l ]
+ [ run distance_se_geo_pl_pl.cpp : : : : algorithms_distance_se_geo_pl_pl ]
+ [ run distance_se_pl_l.cpp : : : : algorithms_distance_se_pl_l ]
+ [ run distance_se_pl_pl.cpp : : : : algorithms_distance_se_pl_pl ]
+ ;
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance.cpp
new file mode 100644
index 00000000..f8696920
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance.cpp
@@ -0,0 +1,536 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, 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)
+
+//#include <boost/geometry/geometry.hpp>
+
+#include <string>
+#include <sstream>
+
+#include "test_distance.hpp"
+
+#include <boost/array.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/typeof/typeof.hpp>
+
+#include <boost/geometry/geometries/geometries.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/adapted/c_array.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+
+#include <test_common/test_point.hpp>
+#include <test_geometries/custom_segment.hpp>
+#include <test_geometries/wrapped_boost_array.hpp>
+
+#include <boost/variant/variant.hpp>
+
+BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+
+// Register boost array as a linestring
+namespace boost { namespace geometry { namespace traits
+{
+template <typename Point, std::size_t PointCount>
+struct tag< boost::array<Point, PointCount> >
+{
+ typedef linestring_tag type;
+};
+
+}}}
+
+template <typename P>
+void test_distance_point()
+{
+ namespace services = bg::strategy::distance::services;
+ typedef typename bg::default_distance_result<P>::type return_type;
+
+ // Basic, trivial test
+
+ P p1;
+ bg::set<0>(p1, 1);
+ bg::set<1>(p1, 1);
+
+ P p2;
+ bg::set<0>(p2, 2);
+ bg::set<1>(p2, 2);
+
+ return_type d = bg::distance(p1, p2);
+ BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001);
+
+ // Test specifying strategy manually
+ typename services::default_strategy
+ <
+ bg::point_tag, bg::point_tag, P
+ >::type strategy;
+
+ d = bg::distance(p1, p2, strategy);
+ BOOST_CHECK_CLOSE(d, return_type(1.4142135), 0.001);
+
+ {
+ // Test custom strategy
+ BOOST_CONCEPT_ASSERT( (bg::concepts::PointDistanceStrategy<taxicab_distance, P, P>) );
+
+ typedef typename services::return_type<taxicab_distance, P, P>::type cab_return_type;
+ BOOST_MPL_ASSERT((boost::is_same<cab_return_type, typename bg::coordinate_type<P>::type>));
+
+ taxicab_distance tcd;
+ cab_return_type d = bg::distance(p1, p2, tcd);
+
+ BOOST_CHECK( bg::math::abs(d - cab_return_type(2)) <= cab_return_type(0.01) );
+ }
+
+ {
+ // test comparability
+
+ typedef typename services::default_strategy
+ <
+ bg::point_tag, bg::point_tag, P
+ >::type strategy_type;
+ typedef typename services::comparable_type<strategy_type>::type comparable_strategy_type;
+
+ strategy_type strategy;
+ comparable_strategy_type comparable_strategy = services::get_comparable<strategy_type>::apply(strategy);
+ return_type comparable = services::result_from_distance<comparable_strategy_type, P, P>::apply(comparable_strategy, 3);
+
+ BOOST_CHECK_CLOSE(comparable, return_type(9), 0.001);
+ }
+}
+
+template <typename P>
+void test_distance_segment()
+{
+ typedef typename bg::default_distance_result<P>::type return_type;
+
+ P s1; bg::set<0>(s1, 1); bg::set<1>(s1, 1);
+ P s2; bg::set<0>(s2, 4); bg::set<1>(s2, 4);
+
+ // Check points left, right, projected-left, projected-right, on segment
+ P p1; bg::set<0>(p1, 0); bg::set<1>(p1, 1);
+ P p2; bg::set<0>(p2, 1); bg::set<1>(p2, 0);
+ P p3; bg::set<0>(p3, 3); bg::set<1>(p3, 1);
+ P p4; bg::set<0>(p4, 1); bg::set<1>(p4, 3);
+ P p5; bg::set<0>(p5, 3); bg::set<1>(p5, 3);
+
+ bg::model::referring_segment<P const> const seg(s1, s2);
+
+ return_type d1 = bg::distance(p1, seg);
+ return_type d2 = bg::distance(p2, seg);
+ return_type d3 = bg::distance(p3, seg);
+ return_type d4 = bg::distance(p4, seg);
+ return_type d5 = bg::distance(p5, seg);
+
+ BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
+ BOOST_CHECK_CLOSE(d2, return_type(1), 0.001);
+ BOOST_CHECK_CLOSE(d3, return_type(1.4142135), 0.001);
+ BOOST_CHECK_CLOSE(d4, return_type(1.4142135), 0.001);
+ BOOST_CHECK_CLOSE(d5, return_type(0), 0.001);
+
+ // Reverse case: segment/point instead of point/segment
+ return_type dr1 = bg::distance(seg, p1);
+ return_type dr2 = bg::distance(seg, p2);
+
+ BOOST_CHECK_CLOSE(dr1, d1, 0.001);
+ BOOST_CHECK_CLOSE(dr2, d2, 0.001);
+
+ // Test specifying strategy manually:
+ // 1) point-point-distance
+ typename bg::strategy::distance::services::default_strategy
+ <
+ bg::point_tag, bg::point_tag, P
+ >::type pp_strategy;
+ d1 = bg::distance(p1, seg, pp_strategy);
+ BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
+
+ // 2) point-segment-distance
+ typename bg::strategy::distance::services::default_strategy
+ <
+ bg::point_tag, bg::segment_tag, P
+ >::type ps_strategy;
+ d1 = bg::distance(p1, seg, ps_strategy);
+ BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
+
+ // 3) custom point strategy
+ taxicab_distance tcd;
+ d1 = bg::distance(p1, seg, tcd);
+ BOOST_CHECK_CLOSE(d1, return_type(1), 0.001);
+}
+
+template <typename Point, typename Geometry, typename T>
+void test_distance_linear(std::string const& wkt_point, std::string const& wkt_geometry, T const& expected)
+{
+ Point p;
+ bg::read_wkt(wkt_point, p);
+
+ Geometry g;
+ bg::read_wkt(wkt_geometry, g);
+
+ typedef typename bg::default_distance_result<Point>::type return_type;
+ return_type d = bg::distance(p, g);
+
+ // For point-to-linestring (or point-to-polygon), both a point-strategy and a point-segment-strategy can be specified.
+ // Test this.
+ return_type ds1 = bg::distance(p, g, bg::strategy::distance::pythagoras<>());
+ return_type ds2 = bg::distance(p, g, bg::strategy::distance::projected_point<>());
+
+ BOOST_CHECK_CLOSE(d, return_type(expected), 0.001);
+ BOOST_CHECK_CLOSE(ds1, return_type(expected), 0.001);
+ BOOST_CHECK_CLOSE(ds2, return_type(expected), 0.001);
+}
+
+template <typename P>
+void test_distance_array_as_linestring()
+{
+ typedef typename bg::default_distance_result<P>::type return_type;
+
+ // Normal array does not have
+ boost::array<P, 2> points;
+ bg::set<0>(points[0], 1);
+ bg::set<1>(points[0], 1);
+ bg::set<0>(points[1], 3);
+ bg::set<1>(points[1], 3);
+
+ P p;
+ bg::set<0>(p, 2);
+ bg::set<1>(p, 1);
+
+ return_type d = bg::distance(p, points);
+ BOOST_CHECK_CLOSE(d, return_type(0.70710678), 0.001);
+
+ bg::set<0>(p, 5); bg::set<1>(p, 5);
+ d = bg::distance(p, points);
+ BOOST_CHECK_CLOSE(d, return_type(2.828427), 0.001);
+}
+
+
+// code moved from the distance unit test in multi/algorithms -- start
+template <typename Geometry1, typename Geometry2>
+void test_distance(std::string const& wkt1, std::string const& wkt2, double expected)
+{
+ Geometry1 g1;
+ Geometry2 g2;
+ bg::read_wkt(wkt1, g1);
+ bg::read_wkt(wkt2, g2);
+ typename bg::default_distance_result<Geometry1, Geometry2>::type d = bg::distance(g1, g2);
+
+ BOOST_CHECK_CLOSE(d, expected, 0.0001);
+}
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+void test_distance(Strategy const& strategy, std::string const& wkt1,
+ std::string const& wkt2, double expected)
+{
+ Geometry1 g1;
+ Geometry2 g2;
+ bg::read_wkt(wkt1, g1);
+ bg::read_wkt(wkt2, g2);
+ typename bg::default_distance_result<Geometry1, Geometry2>::type d = bg::distance(g1, g2, strategy);
+
+ BOOST_CHECK_CLOSE(d, expected, 0.0001);
+}
+
+
+template <typename P>
+void test_2d()
+{
+ typedef bg::model::multi_point<P> mp;
+ typedef bg::model::multi_linestring<bg::model::linestring<P> > ml;
+ test_distance<P, P>("POINT(0 0)", "POINT(1 1)", sqrt(2.0));
+ test_distance<P, mp>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<mp, P>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp, mp>("MULTIPOINT((1 1),(1 0),(0 2))", "MULTIPOINT((2 2),(2 3))", sqrt(2.0));
+ test_distance<P, ml>("POINT(0 0)", "MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", 1.0);
+ test_distance<ml, P>("MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", "POINT(0 0)", 1.0);
+ test_distance<ml, mp>("MULTILINESTRING((1 1,2 2),(1 0,2 0),(0 2,0 3))", "MULTIPOINT((0 0),(1 1))", 0.0);
+
+ // Test with a strategy
+ bg::strategy::distance::pythagoras<> pyth;
+ test_distance<P, P>(pyth, "POINT(0 0)", "POINT(1 1)", sqrt(2.0));
+ test_distance<P, mp>(pyth, "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<mp, P>(pyth, "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+}
+
+
+template <typename P>
+void test_3d()
+{
+ typedef bg::model::multi_point<P> mp;
+ test_distance<P, P>("POINT(0 0 0)", "POINT(1 1 1)", sqrt(3.0));
+ test_distance<P, mp>("POINT(0 0 0)", "MULTIPOINT((1 1 1),(1 0 0),(0 1 2))", 1.0);
+ test_distance<mp, mp>("MULTIPOINT((1 1 1),(1 0 0),(0 0 2))", "MULTIPOINT((2 2 2),(2 3 4))", sqrt(3.0));
+}
+
+
+template <typename P1, typename P2>
+void test_mixed()
+{
+ typedef bg::model::multi_point<P1> mp1;
+ typedef bg::model::multi_point<P2> mp2;
+
+ test_distance<P1, P2>("POINT(0 0)", "POINT(1 1)", sqrt(2.0));
+
+ test_distance<P1, mp1>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P1, mp2>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P2, mp1>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P2, mp2>("POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+
+ // Test automatic reversal
+ test_distance<mp1, P1>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp1, P2>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp2, P1>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp2, P2>("MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+
+ // Test multi-multi using different point types for each
+ test_distance<mp1, mp2>("MULTIPOINT((1 1),(1 0),(0 2))", "MULTIPOINT((2 2),(2 3))", sqrt(2.0));
+
+ // Test with a strategy
+ using namespace bg::strategy::distance;
+
+ test_distance<P1, P2>(pythagoras<>(), "POINT(0 0)", "POINT(1 1)", sqrt(2.0));
+
+ test_distance<P1, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P1, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P2, mp1>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+ test_distance<P2, mp2>(pythagoras<>(), "POINT(0 0)", "MULTIPOINT((1 1),(1 0),(0 2))", 1.0);
+
+ // Most interesting: reversal AND a strategy (note that the stategy must be reversed automatically
+ test_distance<mp1, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp1, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp2, P1>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+ test_distance<mp2, P2>(pythagoras<>(), "MULTIPOINT((1 1),(1 0),(0 2))", "POINT(0 0)", 1.0);
+}
+// code moved from the distance unit test in multi/algorithms -- end
+
+
+
+
+template <typename P>
+void test_all()
+{
+ test_distance_point<P>();
+ test_distance_segment<P>();
+ test_distance_array_as_linestring<P>();
+
+ test_geometry<P, bg::model::segment<P> >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+ test_geometry<P, bg::model::segment<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+
+ test_geometry<P, P>("POINT(1 1)", "POINT(2 2)", sqrt(2.0));
+ test_geometry<P, P>("POINT(0 0)", "POINT(0 3)", 3.0);
+ test_geometry<P, P>("POINT(0 0)", "POINT(4 0)", 4.0);
+ test_geometry<P, P>("POINT(0 3)", "POINT(4 0)", 5.0);
+ test_geometry<P, bg::model::linestring<P> >("POINT(1 3)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+ test_geometry<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+ test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50)", sqrt(50.0));
+ test_geometry<P, bg::model::linestring<P> >("POINT(50 50)", "LINESTRING(50 40, 40 50, 0 90)", sqrt(50.0));
+ test_geometry<bg::model::linestring<P>, P>("LINESTRING(1 1,4 4)", "POINT(1 3)", sqrt(2.0));
+ test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50)", "POINT(50 50)", sqrt(50.0));
+ test_geometry<bg::model::linestring<P>, P>("LINESTRING(50 40, 40 50, 0 90)", "POINT(50 50)", sqrt(50.0));
+
+ // Rings
+ test_geometry<P, bg::model::ring<P> >("POINT(1 3)", "POLYGON((1 1,4 4,5 0,1 1))", sqrt(2.0));
+ test_geometry<P, bg::model::ring<P> >("POINT(3 1)", "POLYGON((1 1,4 4,5 0,1 1))", 0.0);
+ // other way round
+ test_geometry<bg::model::ring<P>, P>("POLYGON((1 1,4 4,5 0,1 1))", "POINT(3 1)", 0.0);
+ // open ring
+ test_geometry<P, bg::model::ring<P, true, false> >("POINT(1 3)", "POLYGON((4 4,5 0,1 1))", sqrt(2.0));
+
+ // Polygons
+ test_geometry<P, bg::model::polygon<P> >("POINT(1 3)", "POLYGON((1 1,4 4,5 0,1 1))", sqrt(2.0));
+ test_geometry<P, bg::model::polygon<P> >("POINT(3 1)", "POLYGON((1 1,4 4,5 0,1 1))", 0.0);
+ // other way round
+ test_geometry<bg::model::polygon<P>, P>("POLYGON((1 1,4 4,5 0,1 1))", "POINT(3 1)", 0.0);
+ // open polygon
+ test_geometry<P, bg::model::polygon<P, true, false> >("POINT(1 3)", "POLYGON((4 4,5 0,1 1))", sqrt(2.0));
+
+ // Polygons with holes
+ std::string donut = "POLYGON ((0 0,1 9,8 1,0 0),(1 1,4 1,1 4,1 1))";
+ test_geometry<P, bg::model::polygon<P> >("POINT(2 2)", donut, 0.5 * sqrt(2.0));
+ test_geometry<P, bg::model::polygon<P> >("POINT(3 3)", donut, 0.0);
+ // other way round
+ test_geometry<bg::model::polygon<P>, P>(donut, "POINT(2 2)", 0.5 * sqrt(2.0));
+ // open
+ test_geometry<P, bg::model::polygon<P, true, false> >("POINT(2 2)", "POLYGON ((0 0,1 9,8 1),(1 1,4 1,1 4))", 0.5 * sqrt(2.0));
+
+ // Should (currently) give compiler assertion
+ // test_geometry<bg::model::polygon<P>, bg::model::polygon<P> >(donut, donut, 0.5 * sqrt(2.0));
+
+ // DOES NOT COMPILE - cannot do read_wkt (because boost::array is not variably sized)
+ // test_geometry<P, boost::array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+
+ test_geometry<P, test::wrapped_boost_array<P, 2> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+
+ test_distance_linear<P, bg::model::linestring<P> >("POINT(3 1)", "LINESTRING(1 1,4 4)", sqrt(2.0));
+}
+
+template <typename P>
+void test_empty_input()
+{
+ P p;
+ bg::model::linestring<P> line_empty;
+ bg::model::polygon<P> poly_empty;
+ bg::model::ring<P> ring_empty;
+ bg::model::multi_point<P> mp_empty;
+ bg::model::multi_linestring<bg::model::linestring<P> > ml_empty;
+
+ test_empty_input(p, line_empty);
+ test_empty_input(p, poly_empty);
+ test_empty_input(p, ring_empty);
+
+ test_empty_input(p, mp_empty);
+ test_empty_input(p, ml_empty);
+ test_empty_input(mp_empty, mp_empty);
+
+ // Test behaviour if one of the inputs is empty
+ bg::model::multi_point<P> mp;
+ mp.push_back(p);
+ test_empty_input(mp_empty, mp);
+ test_empty_input(mp, mp_empty);
+}
+
+void test_large_integers()
+{
+ typedef bg::model::point<int, 2, bg::cs::cartesian> int_point_type;
+ typedef bg::model::point<double, 2, bg::cs::cartesian> double_point_type;
+
+ // point-point
+ {
+ std::string const a = "POINT(2544000 528000)";
+ std::string const b = "POINT(2768040 528000)";
+ int_point_type ia, ib;
+ double_point_type da, db;
+ bg::read_wkt(a, ia);
+ bg::read_wkt(b, ib);
+ bg::read_wkt(a, da);
+ bg::read_wkt(b, db);
+
+ BOOST_AUTO(idist, bg::distance(ia, ib));
+ BOOST_AUTO(ddist, bg::distance(da, db));
+
+ BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1,
+ "within<a double> different from within<an int>");
+ }
+ // Point-segment
+ {
+ std::string const a = "POINT(2600000 529000)";
+ std::string const b = "LINESTRING(2544000 528000, 2768040 528000)";
+ int_point_type ia;
+ double_point_type da;
+ bg::model::segment<int_point_type> ib;
+ bg::model::segment<double_point_type> db;
+ bg::read_wkt(a, ia);
+ bg::read_wkt(b, ib);
+ bg::read_wkt(a, da);
+ bg::read_wkt(b, db);
+
+ BOOST_AUTO(idist, bg::distance(ia, ib));
+ BOOST_AUTO(ddist, bg::distance(da, db));
+
+ BOOST_CHECK_MESSAGE(std::abs(idist - ddist) < 0.1,
+ "within<a double> different from within<an int>");
+ }
+}
+
+template <typename T>
+void test_variant()
+{
+ typedef bg::model::point<T, 2, bg::cs::cartesian> point_type;
+ typedef bg::model::segment<point_type> segment_type;
+ typedef bg::model::box<point_type> box_type;
+ typedef boost::variant<point_type, segment_type, box_type> variant_type;
+
+ point_type point;
+ std::string const point_li = "POINT(1 3)";
+ bg::read_wkt(point_li, point);
+
+ segment_type seg;
+ std::string const seg_li = "LINESTRING(1 1,4 4)";
+ bg::read_wkt(seg_li, seg);
+
+ variant_type v1, v2;
+
+ BOOST_MPL_ASSERT((
+ boost::is_same
+ <
+ typename bg::distance_result
+ <
+ variant_type, variant_type, bg::default_strategy
+ >::type,
+ double
+ >
+ ));
+
+ // Default strategy
+ v1 = point;
+ v2 = point;
+ BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, point), 0.0001);
+ BOOST_CHECK_CLOSE(bg::distance(v1, point), bg::distance(point, point), 0.0001);
+ BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, point), 0.0001);
+ v1 = point;
+ v2 = seg;
+ BOOST_CHECK_CLOSE(bg::distance(v1, v2), bg::distance(point, seg), 0.0001);
+ BOOST_CHECK_CLOSE(bg::distance(v1, seg), bg::distance(point, seg), 0.0001);
+ BOOST_CHECK_CLOSE(bg::distance(point, v2), bg::distance(point, seg), 0.0001);
+
+ // User defined strategy
+ v1 = point;
+ v2 = point;
+ bg::strategy::distance::haversine<double> s;
+ //BOOST_CHECK_CLOSE(bg::distance(v1, v2, s), bg::distance(point, point, s), 0.0001);
+ //BOOST_CHECK_CLOSE(bg::distance(v1, point, s), bg::distance(point, point, s), 0.0001);
+ //BOOST_CHECK_CLOSE(bg::distance(point, v2, s), bg::distance(point, point, s), 0.0001);
+}
+
+int test_main(int, char* [])
+{
+#ifdef TEST_ARRAY
+ //test_all<int[2]>();
+ //test_all<float[2]>();
+ //test_all<double[2]>();
+ //test_all<test::test_point>(); // located here because of 3D
+#endif
+
+ test_large_integers();
+
+ test_all<bg::model::d2::point_xy<int> >();
+ test_all<boost::tuple<float, float> >();
+ test_all<bg::model::d2::point_xy<float> >();
+ test_all<bg::model::d2::point_xy<double> >();
+
+#ifdef HAVE_TTMATH
+ test_all<bg::model::d2::point_xy<ttmath_big> >();
+#endif
+
+ test_empty_input<bg::model::d2::point_xy<int> >();
+
+ // below are the test cases moved here from the distance unit test
+ // in test/multi/algorithms
+ test_2d<boost::tuple<float, float> >();
+ test_2d<bg::model::d2::point_xy<float> >();
+ test_2d<bg::model::d2::point_xy<double> >();
+
+ test_3d<boost::tuple<float, float, float> >();
+ test_3d<bg::model::point<double, 3, bg::cs::cartesian> >();
+
+ test_mixed<bg::model::d2::point_xy<float>, bg::model::d2::point_xy<double> >();
+
+#ifdef HAVE_TTMATH
+ test_2d<bg::model::d2::point_xy<ttmath_big> >();
+ test_mixed<bg::model::d2::point_xy<ttmath_big>, bg::model::d2::point_xy<double> >();
+#endif
+
+ test_empty_input<bg::model::d2::point_xy<int> >();
+
+ test_variant<double>();
+ test_variant<int>();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_all.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_all.cpp
new file mode 100644
index 00000000..74a46fff
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_all.cpp
@@ -0,0 +1,20 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_all
+#endif
+
+#include "distance_pointlike_pointlike.cpp"
+#include "distance_pointlike_linear.cpp"
+#include "distance_pointlike_areal.cpp"
+#include "distance_linear_linear.cpp"
+#include "distance_linear_areal.cpp"
+#include "distance_areal_areal.cpp"
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp b/src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
new file mode 100644
index 00000000..82d0015b
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_brute_force.hpp
@@ -0,0 +1,1356 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
+
+#include <iterator>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/or.hpp>
+#include <boost/range.hpp>
+
+#include <boost/geometry/core/reverse_dispatch.hpp>
+#include <boost/geometry/core/tag.hpp>
+#include <boost/geometry/core/tag_cast.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/iterators/segment_iterator.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/intersects.hpp>
+#include <boost/geometry/algorithms/not_implemented.hpp>
+
+
+namespace boost { namespace geometry
+{
+
+namespace unit_test
+{
+
+namespace detail { namespace distance_brute_force
+{
+
+struct distance_from_bg
+{
+ template <typename G>
+ struct use_distance_from_bg
+ {
+ typedef typename boost::mpl::or_
+ <
+ boost::is_same<typename tag<G>::type, point_tag>,
+ typename boost::mpl::or_
+ <
+ boost::is_same<typename tag<G>::type, segment_tag>,
+ boost::is_same<typename tag<G>::type, box_tag>
+ >::type
+ >::type type;
+ };
+
+ template <typename Geometry1, typename Geometry2, typename Strategy>
+ static inline
+ typename distance_result<Geometry1, Geometry2, Strategy>::type
+ apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry1>::type));
+ BOOST_MPL_ASSERT((typename use_distance_from_bg<Geometry2>::type));
+
+ return geometry::distance(geometry1, geometry2, strategy);
+ }
+};
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline
+typename distance_result<Geometry1, Geometry2, Strategy>::type
+bg_distance(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return distance_from_bg::apply(geometry1, geometry2, strategy);
+}
+
+
+template <typename Policy>
+struct one_to_many
+{
+ template <typename Geometry, typename Iterator, typename Strategy>
+ static inline typename distance_result
+ <
+ Geometry,
+ typename std::iterator_traits<Iterator>::value_type,
+ Strategy
+ >::type
+ apply(Geometry const& geometry, Iterator begin, Iterator end,
+ Strategy const& strategy)
+ {
+ typedef typename distance_result
+ <
+ Geometry,
+ typename std::iterator_traits<Iterator>::value_type,
+ Strategy
+ >::type distance_type;
+
+ bool first = true;
+ distance_type d_min(0);
+ for (Iterator it = begin; it != end; ++it, first = false)
+ {
+ distance_type d = Policy::apply(geometry, *it, strategy);
+
+ if ( first || d < d_min )
+ {
+ d_min = d;
+ }
+ }
+ return d_min;
+ }
+};
+
+
+
+}} // namespace detail::distance_brute_force
+
+
+namespace dispatch
+{
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy,
+ typename Tag1 = typename tag_cast
+ <
+ typename tag<Geometry1>::type,
+ segment_tag,
+ linear_tag
+ >::type,
+ typename Tag2 = typename tag_cast
+ <
+ typename tag<Geometry2>::type,
+ segment_tag,
+ linear_tag
+ >::type,
+ bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
+>
+struct distance_brute_force
+ : not_implemented<Geometry1, Geometry2>
+{};
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename Strategy,
+ typename Tag1,
+ typename Tag2
+>
+struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
+{
+ static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
+ apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+ {
+ return distance_brute_force
+ <
+ Geometry2, Geometry1, Strategy
+ >::apply(geometry2, geometry1, strategy);
+ }
+};
+
+//===================================================================
+
+template
+<
+ typename Point1,
+ typename Point2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point1, Point2, Strategy,
+ point_tag, point_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+
+template
+<
+ typename Point,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Segment, Strategy,
+ point_tag, segment_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+template
+<
+ typename Point,
+ typename Linear,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Linear, Strategy,
+ point_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, Linear, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& point,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(point,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+template
+<
+ typename Point,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Ring, Strategy,
+ point_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& point,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+
+ if (geometry::covered_by(point, ring))
+ {
+ return 0;
+ }
+
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Point,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(point,
+ geometry::segments_begin(ring),
+ geometry::segments_end(ring),
+ strategy);
+ }
+};
+
+//TODO do it more brute force (also in all polygon-geometry cases)
+template
+<
+ typename Point,
+ typename Polygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Polygon, Strategy,
+ point_tag, polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, Polygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& point,
+ Polygon const& polygon,
+ Strategy const& strategy)
+ {
+ return geometry::distance(point, polygon, strategy);
+ }
+};
+
+template
+<
+ typename Point,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, Box, Strategy,
+ point_tag, box_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+template
+<
+ typename Point,
+ typename MultiPoint,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, MultiPoint, Strategy,
+ point_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, MultiPoint, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& p,
+ MultiPoint const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(p, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename Point,
+ typename MultiPolygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Point, MultiPolygon, Strategy,
+ point_tag, multi_polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Point, MultiPolygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Point const& p,
+ MultiPolygon const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Point,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(p, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+//=======================================================================
+
+template
+<
+ typename Linear,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, Segment, Strategy,
+ linear_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(segment,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+
+template
+<
+ typename Linear1,
+ typename Linear2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear1, Linear2, Strategy,
+ linear_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear1, Linear2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear1 const& linear1,
+ Linear2 const& linear2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear1,
+ typename std::iterator_traits
+ <
+ segment_iterator<Linear2 const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(linear1,
+ geometry::segments_begin(linear2),
+ geometry::segments_end(linear2),
+ strategy);
+ }
+};
+
+template
+<
+ typename Linear,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, Ring, Strategy,
+ linear_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(linear,
+ geometry::segments_begin(ring),
+ geometry::segments_end(ring),
+ strategy);
+ }
+};
+
+template
+<
+ typename Linear,
+ typename Polygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, Polygon, Strategy,
+ linear_tag, polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, Polygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ Polygon const& polygon,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Polygon,
+ typename std::iterator_traits
+ <
+ segment_iterator<Linear const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(polygon,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+
+template
+<
+ typename Linear,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, Box, Strategy,
+ linear_tag, box_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, Box, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(box,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+template
+<
+ typename Linear,
+ typename MultiPoint,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, MultiPoint, Strategy,
+ linear_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, MultiPoint, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ MultiPoint const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear,
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
+ >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename Linear,
+ typename MultiPolygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Linear, MultiPolygon, Strategy,
+ linear_tag, multi_polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Linear, MultiPolygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Linear const& linear,
+ MultiPolygon const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Linear,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+//=================================================================
+
+template
+<
+ typename Polygon,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, Segment, Strategy,
+ polygon_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& polygon,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return geometry::distance(segment, polygon, strategy);
+ }
+};
+
+template
+<
+ typename Polygon,
+ typename Linear,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, Linear, Strategy,
+ polygon_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, Linear, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& polygon,
+ Linear const& linear,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Polygon,
+ typename std::iterator_traits
+ <
+ segment_iterator<Linear const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(polygon,
+ geometry::segments_begin(linear),
+ geometry::segments_end(linear),
+ strategy);
+ }
+};
+
+template
+<
+ typename Polygon1,
+ typename Polygon2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon1, Polygon2, Strategy,
+ polygon_tag, polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon1, Polygon2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon1 const& polygon1,
+ Polygon2 const& polygon2,
+ Strategy const& strategy)
+ {
+ return geometry::distance(polygon1, polygon2, strategy);
+ }
+};
+
+
+template
+<
+ typename Polygon,
+ typename MultiPoint,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, MultiPoint, Strategy,
+ polygon_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, MultiPoint, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& polygon,
+ MultiPoint const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Polygon,
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
+ >::apply(polygon, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename Polygon,
+ typename MultiPolygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, MultiPolygon, Strategy,
+ polygon_tag, multi_polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, MultiPolygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& poly,
+ MultiPolygon const& mp,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Polygon,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(poly, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename Polygon,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, Ring, Strategy,
+ polygon_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& polygon,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+ return geometry::distance(ring, polygon, strategy);
+ }
+};
+
+template
+<
+ typename Polygon,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Polygon, Box, Strategy,
+ polygon_tag, box_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Polygon, Box, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Polygon const& polygon,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ return geometry::distance(box, polygon, strategy);
+ }
+};
+
+//========================================================================
+
+template
+<
+ typename MultiPoint1,
+ typename MultiPoint2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint1, MultiPoint2, Strategy,
+ multi_point_tag, multi_point_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint1, MultiPoint2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint1 const& mp1,
+ MultiPoint2 const& mp2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPoint1,
+ typename boost::range_value<MultiPoint2>::type,
+ Strategy
+ >
+ >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint,
+ typename Linear,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Linear, Strategy,
+ multi_point_tag, linear_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Linear, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Linear const& l,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPoint,
+ typename boost::range_value<Linear>::type,
+ Strategy
+ >
+ >::apply(mp, boost::begin(l), boost::end(l), strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint,
+ typename MultiPolygon,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, MultiPolygon, Strategy,
+ multi_point_tag, multi_polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, MultiPolygon, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ MultiPolygon const& mpl,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPoint,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(mp, boost::begin(mpl), boost::end(mpl), strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Segment, Strategy,
+ multi_point_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ detail::distance_brute_force::distance_from_bg
+ >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Ring, Strategy,
+ multi_point_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+
+
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPoint,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(mp,
+ geometry::segments_begin(ring),
+ geometry::segments_end(ring),
+ strategy);
+ }
+};
+
+template
+<
+ typename MultiPoint,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPoint, Box, Strategy,
+ multi_point_tag, box_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPoint, Box, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPoint const& mp,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Box,
+ typename boost::range_value<MultiPoint>::type,
+ Strategy
+ >
+ >::apply(box, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+//=====================================================================
+
+template
+<
+ typename MultiPolygon1,
+ typename MultiPolygon2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPolygon1, MultiPolygon2, Strategy,
+ multi_polygon_tag, multi_polygon_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPolygon1, MultiPolygon2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPolygon1 const& mp1,
+ MultiPolygon2 const& mp2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ MultiPolygon1,
+ typename boost::range_value<MultiPolygon2>::type,
+ Strategy
+ >
+ >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
+ }
+};
+
+template
+<
+ typename MultiPolygon,
+ typename Segment,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPolygon, Segment, Strategy,
+ multi_polygon_tag, segment_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPolygon, Segment, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPolygon const& mp,
+ Segment const& segment,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Segment,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename MultiPolygon,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPolygon, Ring, Strategy,
+ multi_polygon_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPolygon, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPolygon const& mp,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Ring,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(ring, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+template
+<
+ typename MultiPolygon,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ MultiPolygon, Box, Strategy,
+ multi_polygon_tag, box_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ MultiPolygon, Box, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(MultiPolygon const& mp,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Box,
+ typename boost::range_value<MultiPolygon>::type,
+ Strategy
+ >
+ >::apply(box, boost::begin(mp), boost::end(mp), strategy);
+ }
+};
+
+
+//========================================================================
+
+template
+<
+ typename Ring,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Ring, Box, Strategy,
+ ring_tag, box_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Ring, Box, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Ring const& ring,
+ Box const& box,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Box,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(box,
+ geometry::segments_begin(ring),
+ geometry::segments_end(ring),
+ strategy);
+ }
+};
+
+template
+<
+ typename Ring1,
+ typename Ring2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Ring1, Ring2, Strategy,
+ ring_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Ring1, Ring2, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Ring1 const& ring1,
+ Ring2 const& ring2,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Ring1,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring2 const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(ring1,
+ geometry::segments_begin(ring2),
+ geometry::segments_end(ring2),
+ strategy);
+ }
+};
+
+//========================================================================
+
+template
+<
+ typename Segment1,
+ typename Segment2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Segment1, Segment2, Strategy,
+ segment_tag, segment_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+template
+<
+ typename Segment,
+ typename Ring,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Segment, Ring, Strategy,
+ segment_tag, ring_tag, false
+>
+{
+ typedef typename distance_result
+ <
+ Segment, Ring, Strategy
+ >::type distance_type;
+
+ static inline distance_type apply(Segment const& segment,
+ Ring const& ring,
+ Strategy const& strategy)
+ {
+ return detail::distance_brute_force::one_to_many
+ <
+ distance_brute_force
+ <
+ Segment,
+ typename std::iterator_traits
+ <
+ segment_iterator<Ring const>
+ >::value_type,
+ Strategy
+ >
+ >::apply(segment,
+ geometry::segments_begin(ring),
+ geometry::segments_end(ring),
+ strategy);
+ }
+};
+
+template
+<
+ typename Segment,
+ typename Box,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Segment, Box, Strategy,
+ segment_tag, box_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+//====================================================================
+
+template
+<
+ typename Box1,
+ typename Box2,
+ typename Strategy
+>
+struct distance_brute_force
+<
+ Box1, Box2, Strategy,
+ box_tag, box_tag, false
+> : detail::distance_brute_force::distance_from_bg
+{};
+
+} // namespace dispatch
+
+
+
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+inline typename distance_result<Geometry1, Geometry2, Strategy>::type
+distance_brute_force(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ return dispatch::distance_brute_force
+ <
+ Geometry1, Geometry2, Strategy
+ >::apply(geometry1, geometry2, strategy);
+}
+
+} // namespace unit_test
+
+
+}} // namespace boost::geometry
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_ar_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_ar_ar.cpp
new file mode 100644
index 00000000..1971d8c3
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_ar_ar.cpp
@@ -0,0 +1,437 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_areal_areal
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+
+
+typedef bg::model::point<int,2,bg::cs::cartesian> int_point_type;
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::polygon<point_type, false> polygon_type;
+typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+typedef bg::model::ring<point_type, false> ring_type;
+typedef bg::model::box<int_point_type> int_box_type;
+typedef bg::model::box<point_type> box_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::projected_point<> point_segment_strategy;
+typedef bg::strategy::distance::pythagoras_box_box<> box_box_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_polygon_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<polygon_type, polygon_type> tester;
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,5 20,5 25,-5 25,-5 20))",
+ 10, 100, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 5,5 5,5 20,-5 20))",
+ 0, 0, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 -20,5 -20,5 20,-5 20))",
+ 0, 0, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10),\
+ (-5 -5,-5 5,5 5,5 -5,-5 -5))",
+ "polygon((-1 -1,0 0,-1 0,-1 -1))",
+ 4, 16, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_polygon_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ polygon_type, multi_polygon_type
+ > tester;
+
+ tester::apply("polygon((12 0,14 0,19 0,19.9 -1,12 0))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0.1, 0.01, strategy);
+
+ tester::apply("polygon((19 0,19.9 -1,12 0,20.5 0.5,19 0))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_polygon_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<polygon_type, ring_type> tester;
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,5 20,5 25,-5 25,-5 20))",
+ 10, 100, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 5,5 5,5 20,-5 20))",
+ 0, 0, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 -20,5 -20,5 20,-5 20))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipolygon_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipolygon/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_polygon_type, multi_polygon_type
+ > tester;
+
+ tester::apply("multipolygon(((12 0,14 0,14 1,12 0)),\
+ ((18 0,19 0,19.9 -1,18 0)))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0.1, 0.01, strategy);
+
+ tester::apply("multipolygon(((18 0,19 0,19.9 -1,18 0)),\
+ ((12 0,14 0,20.5 0.5,12 0)))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipolygon_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipolygon/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_polygon_type, ring_type
+ > tester;
+
+ tester::apply("multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ "polygon((12 0,14 0,19 0,19.9 -1,12 0))",
+ 0.1, 0.01, strategy);
+
+ tester::apply("multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ "polygon((19 0,19.9 -1,12 0,20.5 0.5,19 0))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_ring_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<ring_type, ring_type> tester;
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,5 20,5 25,-5 25,-5 20))",
+ 10, 100, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 5,5 5,5 20,-5 20))",
+ 0, 0, strategy);
+
+ tester::apply("polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ "polygon((-5 20,-5 -20,5 -20,5 20,-5 20))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_box_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "box/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<int_box_type, int_box_type> int_tester;
+ typedef test_distance_of_geometries<box_type, box_type> tester;
+
+ int_tester::apply("box(5 5,10 10)",
+ "box(0 0,1 1)",
+ sqrt(32.0), 32, strategy);
+
+ tester::apply("box(5 5,10 10)",
+ "box(0 0,1 1)",
+ sqrt(32.0), 32, strategy);
+
+ tester::apply("box(3 8,13 18)",
+ "box(0 0,5 5)",
+ 3, 9, strategy);
+
+ tester::apply("box(5 5,10 10)",
+ "box(0 0,5 5)",
+ 0, 0, strategy);
+
+ tester::apply("box(5 5,10 10)",
+ "box(0 0,6 6)",
+ 0, 0, strategy);
+
+ tester::apply("box(3 5,13 15)",
+ "box(0 0,5 5)",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_polygon_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<polygon_type, box_type> tester;
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,1 1)",
+ sqrt(32.0), 32, strategy);
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,5 5)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,6 6)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,15 5,10 0,5 5,10 10))",
+ "box(5 0,7.5 2.5)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,15 5,10 0,5 5,10 10))",
+ "box(5 0,6 1)",
+ sqrt(4.5), 4.5, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipolygon_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipolygon/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_polygon_type, box_type> tester;
+
+ tester::apply("multipolygon(((-10 -10,-10 -9,-9 -9,-9 -10,-10 -10)),\
+ ((2 2,2 3,3 3,3 2,2 2)))",
+ "box(0 0,1 1)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("multipolygon(((-10 -10,-10 -9,-9 -9,-9 -10,-10 -10)),\
+ ((2 2,2 3,3 3,3 2,2 2)))",
+ "box(0 0,2 2)",
+ 0, 0, strategy);
+
+ tester::apply("multipolygon(((-10 -10,-10 -9,-9 -9,-9 -10,-10 -10)),\
+ ((2 2,2 3,3 3,3 2,2 2)))",
+ "box(0 0,2.5 2)",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_ring_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<ring_type, box_type> tester;
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,1 1)",
+ sqrt(32.0), 32, strategy);
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,5 5)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,10 5,5 5,5 10,10 10))",
+ "box(0 0,6 6)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,15 5,10 0,5 5,10 10))",
+ "box(5 0,7.5 2.5)",
+ 0, 0, strategy);
+
+ tester::apply("polygon((10 10,15 5,10 0,5 5,10 10))",
+ "box(5 0,6 1)",
+ sqrt(4.5), 4.5, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_areal_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+ bg::model::ring<Point> ring_empty;
+
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("polygon((0 0,1 0,0 1))");
+
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon =
+ from_wkt
+ <
+ bg::model::multi_polygon<bg::model::polygon<Point> >
+ >("multipolygon(((0 0,1 0,0 1)))");
+
+ bg::model::ring<Point> ring =
+ from_wkt<bg::model::ring<Point> >("polygon((0 0,1 0,0 1))");
+
+ // 1st geometry is empty
+ test_empty_input(polygon_empty, polygon, strategy);
+ test_empty_input(polygon_empty, multipolygon, strategy);
+ test_empty_input(polygon_empty, ring, strategy);
+ test_empty_input(multipolygon_empty, polygon, strategy);
+ test_empty_input(multipolygon_empty, multipolygon, strategy);
+ test_empty_input(multipolygon_empty, ring, strategy);
+ test_empty_input(ring_empty, polygon, strategy);
+ test_empty_input(ring_empty, multipolygon, strategy);
+ test_empty_input(ring_empty, ring, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(polygon, polygon_empty, strategy);
+ test_empty_input(polygon, multipolygon_empty, strategy);
+ test_empty_input(polygon, ring_empty, strategy);
+ test_empty_input(multipolygon, polygon_empty, strategy);
+ test_empty_input(multipolygon, multipolygon_empty, strategy);
+ test_empty_input(multipolygon, ring_empty, strategy);
+ test_empty_input(ring, polygon_empty, strategy);
+ test_empty_input(ring, multipolygon_empty, strategy);
+ test_empty_input(ring, ring_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(polygon_empty, polygon_empty, strategy);
+ test_empty_input(polygon_empty, multipolygon_empty, strategy);
+ test_empty_input(polygon_empty, ring_empty, strategy);
+ test_empty_input(multipolygon_empty, polygon_empty, strategy);
+ test_empty_input(multipolygon_empty, multipolygon_empty, strategy);
+ test_empty_input(multipolygon_empty, ring_empty, strategy);
+ test_empty_input(ring_empty, polygon_empty, strategy);
+ test_empty_input(ring_empty, multipolygon_empty, strategy);
+ test_empty_input(ring_empty, ring_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_polygon_polygon )
+{
+ test_distance_polygon_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_polygon_multipolygon )
+{
+ test_distance_polygon_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_polygon_ring )
+{
+ test_distance_polygon_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipolygon_multipolygon )
+{
+ test_distance_multipolygon_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipolygon_ring )
+{
+ test_distance_multipolygon_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_ring_ring )
+{
+ test_distance_ring_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_box_box )
+{
+ test_distance_box_box(box_box_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_polygon_box )
+{
+ test_distance_polygon_box(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipolygon_box )
+{
+ test_distance_multipolygon_box(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_ring_box )
+{
+ test_distance_ring_box(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_areal_areal )
+{
+ test_more_empty_input_areal_areal<point_type>(point_segment_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_ar.cpp
new file mode 100644
index 00000000..60a1e1c5
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_ar.cpp
@@ -0,0 +1,972 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_linear_areal
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::point<int,2,bg::cs::cartesian> int_point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::segment<int_point_type> int_segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+typedef bg::model::polygon<point_type, false> polygon_type;
+typedef bg::model::polygon<point_type, false, false> open_polygon_type;
+typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+typedef bg::model::multi_polygon<open_polygon_type> open_multipolygon_type;
+typedef bg::model::ring<point_type, false> ring_type;
+typedef bg::model::box<point_type> box_type;
+typedef bg::model::box<int_point_type> int_box_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::pythagoras<> point_point_strategy;
+typedef bg::strategy::distance::projected_point<> point_segment_strategy;
+typedef bg::strategy::distance::cartesian_segment_box<> segment_box_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<segment_type, polygon_type> tester;
+
+ tester::apply("segment(-1 20,1 20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("segment(1 20,2 40)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("segment(-1 20,-1 5)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("segment(-1 20,-1 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("segment(0 0,1 1)",
+ "polygon((2 2))",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<linestring_type, polygon_type> tester;
+
+ tester::apply("linestring(-1 20,1 20,1 30)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("linestring(-5 1,-2 1)",
+ "polygon((0 0,10 0,10 10,0 10,0 0))",
+ 2, 4, strategy);
+
+ tester::apply("linestring(-1 20,1 20,1 5)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("linestring(-1 20,1 20,1 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("linestring(-2 1)",
+ "polygon((0 0,10 0,10 10,0 10,0 0))",
+ 2, 4, strategy);
+
+ tester::apply("linestring(-5 1,-2 1)",
+ "polygon((0 0))",
+ sqrt(5.0), 5, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_open_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/open polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, open_polygon_type
+ > tester;
+
+ tester::apply("linestring(-5 1,-2 1)",
+ "polygon((0 0,10 0,10 10,0 10))",
+ 2, 4, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multilinestring_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_linestring_type, polygon_type
+ > tester;
+
+ tester::apply("multilinestring((-100 -100,-90 -90),(-1 20,1 20,1 30))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("multilinestring((-1 20,1 20,1 30),(-1 20,1 20,1 5))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("multilinestring((-1 20,1 20,1 30),(-1 20,1 20,1 -20))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("multilinestring((-100 -100,-90 -90),(1 20))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("multilinestring((-100 -100,-90 -90),(-1 20,1 20,1 30))",
+ "polygon((-110 -110))",
+ sqrt(200.0), 200, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ segment_type, multi_polygon_type
+ > tester;
+
+ tester::apply("segment(-1 20,1 20)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((0 22,-1 30, 2 40,0 22)))",
+ 2, 4, strategy);
+
+ tester::apply("segment(12 0,14 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 2, 4, strategy);
+
+ tester::apply("segment(12 0,20.5 0.5)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+
+ tester::apply("segment(12 0,50 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_polygon_type
+ > tester;
+
+ tester::apply("linestring(-1 20,1 20)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((0 22,-1 30, 2 40,0 22)))",
+ 2, 4, strategy);
+
+ tester::apply("linestring(12 0,14 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 2, 4, strategy);
+
+ tester::apply("linestring(12 0,20.5 0.5)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+
+ tester::apply("linestring(12 0,50 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_open_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/open multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, open_multipolygon_type
+ > tester;
+
+ tester::apply("linestring(-5 1,-2 1)",
+ "multipolygon(((0 0,10 0,10 10,0 10)))",
+ 2, 4, strategy);
+
+ tester::apply("linestring(-5 1,-3 1)",
+ "multipolygon(((20 20,21 20,21 21,20 21)),((0 0,10 0,10 10,0 10)))",
+ 3, 9, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multilinestring_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_linestring_type, multi_polygon_type
+ > tester;
+
+ tester::apply("multilinestring((12 0,14 0),(19 0,19.9 -1))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10)))",
+ 0.1, 0.01, strategy);
+
+ tester::apply("multilinestring((19 0,19.9 -1),(12 0,20.5 0.5))",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<segment_type, ring_type> tester;
+
+ tester::apply("segment(-1 20,1 20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("segment(1 20,2 40)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("segment(-1 20,-1 5)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("segment(-1 20,-1 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<linestring_type, ring_type> tester;
+
+ tester::apply("linestring(-1 20,1 20,1 30)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("linestring(-1 20,1 20,1 5)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("linestring(-1 20,1 20,1 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multilinestring_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_linestring_type, ring_type
+ > tester;
+
+ tester::apply("multilinestring((-100 -100,-90 -90),(-1 20,1 20,1 30))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("multilinestring((-1 20,1 20,1 30),(-1 20,1 20,1 5))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("multilinestring((-1 20,1 20,1 30),(-1 20,1 20,1 -20))",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "2D segment/box distance tests" << std::endl;
+#endif
+ typedef int_box_type B;
+ typedef segment_type S;
+ typedef int_segment_type IS;
+
+ typedef test_distance_of_geometries<B, S> tester;
+ typedef test_distance_of_geometries<B, IS> itester;
+
+ // 1st example by Adam Wulkiewicz
+ tester::apply("BOX(5 51,42 96)",
+ "SEGMENT(6.6799994 95.260002,35.119999 56.340004)",
+ 0, 0, strategy);
+
+ // 2nd example by Adam Wulkiewicz
+ tester::apply("BOX(51 55,94 100)",
+ "SEGMENT(92.439995 50.130001,59.959999 80.870003)",
+ 0, 0, strategy);
+
+ // segments that intersect the box
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0.5,0.5 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0.5,1.5 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -1,0.5 2)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 1,1.5 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 0,0 2)",
+ 0, 0, strategy);
+
+ // segment that has closest point on box boundary
+ tester::apply("box(0 0,1 1)",
+ "segment(4 0.5,5 0.75)",
+ 3, 9, strategy);
+
+ // segment that has closest point on box corner
+ tester::apply("box(0 0,1 1)",
+ "segment(4 0,0 4)",
+ sqrt(2.0), 2, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(-4 0,0 -4)",
+ sqrt(8.0), 8, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(-8 4,4 -8)",
+ sqrt(8.0), 8, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-4 0,0 4)",
+ 1.5 * sqrt(2.0), 4.5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-4 0,1 5)",
+ 1.5 * sqrt(2.0), 4.5, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(0 -2,3 1)",
+ 0.5 * sqrt(2.0), 0.5, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(0 -2,2 2)",
+ 0, 0, strategy);
+
+ // horizontal segments
+ itester::apply("box(0 0,1 1)",
+ "segment(-2 -1,-1 -1)",
+ sqrt(2.0), 2, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(-1 -1,0 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-0.5 -1,0.5 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -1,0.75 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -1,1.25 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 -1,2 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 -1,3 -1)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -1,2 -1)",
+ 1, 1, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 0,-1 0)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0,0 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-0.5 0,0.5 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0,0.75 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0,1.25 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 0,2 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 0,3 0)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 0,2 0)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 0.5,-1 0.5)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0.5,0 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-0.5 0.5,0.5 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0.5,0.75 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0.5,1.25 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 0.5,2 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 0.5,3 0.5)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 0.5,2 0.5)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 1,-1 1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 1,0 1)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-0.5 1,0.5 1)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 1,0.75 1)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 1,1.25 1)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 1,2 1)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 1,3 1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 1,2 1)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 3,-1 3)",
+ sqrt(5.0), 5, strategy);
+ itester::apply("box(0 0,1 1)",
+ "segment(-1 3,0 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-0.5 3,0.5 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 3,0.75 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 3,1.25 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 3,2 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(2 3,3 3)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 3,2 3)",
+ 2, 4, strategy);
+
+ // vertical segments
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -2,-1 -1)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -1,-1 0)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -0.5,-1 0.5)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0.5,-1 0.75)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 0.5,-1 1.25)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 1,-1 2)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 2,-1 3)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -2,-1 2)",
+ 1, 1, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(0 -2,0 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 -1,0 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 -0.5,0 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 0.5,0 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 0.5,0 1.25)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 1,0 2)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 2,0 3)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 -2,0 2)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -2,0.5 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -1,0.5 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -0.5,0.5 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0.5,0.5 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 0.5,0.5 1.25)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 1,0.5 2)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 2,0.5 3)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -2,0.5 2)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(1 -2,1 -1)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 -1,1 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 -0.5,1 0.5)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 0.5,1 0.75)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 0.5,1 1.25)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 1,1 2)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 2,1 3)",
+ 1, 1, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 -2,1 2)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,1 1)",
+ "segment(3 -2,3 -1)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 -1,3 0)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 -0.5,3 0.5)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 0.5,3 0.75)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 0.5,3 1.25)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 1,3 2)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 2,3 3)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 -2,3 2)",
+ 2, 4, strategy);
+
+ // positive slope
+ itester::apply("box(0 0,1 1)",
+ "segment(-2 -2,-1 -1)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,0 -0.5)",
+ 0.5, 0.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,0.5 -0.5)",
+ 0.5, 0.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,1 -0.5)",
+ 0.5, 0.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,2 0)",
+ sqrt(0.2), 0.2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,4 1)",
+ sqrt(0.2), 0.2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,-1.5 0)",
+ 1.5, 2.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,-1.5 0.5)",
+ 1.5, 2.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,-1.5 1)",
+ 1.5, 2.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,0 2)",
+ sqrt(0.2), 0.2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,1 4)",
+ sqrt(0.2), 0.2, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,4 2)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,2 4)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,4 3)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,3 4)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,3 3)",
+ 0, 0, strategy);
+
+ // negative slope
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 -2,-1 -3)",
+ sqrt(8.0), 8, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-3 -1,0 -4)",
+ sqrt(8.0), 8, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 0.75,-1.5 0.5)",
+ 1.5, 2.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 1.5,-1.5 0.5)",
+ 1.5, 2.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 2,0.75 1.5)",
+ 0.5, 0.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 2,0.75 1.5)",
+ 0.5, 0.25, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 2,2 0)",
+ 0, 0, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0 3,3 0)",
+ sqrt(0.5), 0.5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 4,4 -1)",
+ sqrt(0.5), 0.5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 4,0 3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-2 5,-1 4)",
+ sqrt(10.0), 10, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(3 -1,4 -4)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(1 2,2 1)",
+ sqrt(0.5), 0.5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 -2,2 -3)",
+ 2, 4, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -2,0 -3)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -2,0.5 -3.5)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(-1 -2,0.5 -3.5)",
+ sqrt(5.0), 5, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 3,2.5 2)",
+ sqrt(2.45), 2.45, strategy);
+ tester::apply("box(0 0,1 1)",
+ "segment(0.5 1.5,1.5 -1.5)",
+ 0, 0, strategy);
+
+ // test degenerate segment
+ tester::apply("box(0 0,2 2)",
+ "segment(4 1,4 1)",
+ 2, 4, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<linestring_type, box_type> tester;
+
+ // linestrings that intersect the box
+ tester::apply("linestring(-1 0.5,0.5 0.75)",
+ "box(0 0,1 1)",
+ 0, 0, strategy);
+ tester::apply("linestring(-1 0.5,1.5 0.75)",
+ "box(0 0,1 1)",
+ 0, 0, strategy);
+
+ // linestring that has closest point on box boundary
+ tester::apply("linestring(4 0.5,5 0.75)",
+ "box(0 0,1 1)",
+ 3, 9, strategy);
+
+ // linestring that has closest point on box corner
+ tester::apply("linestring(4 0,0 4)",
+ "box(0 0,1 1)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multilinestring_box(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_linestring_type, box_type> tester;
+
+ // multilinestring that intersects the box
+ tester::apply("multilinestring((-1 0.5,0.5 0.75),(4 0.5,5 0.75))",
+ "box(0 0,1 1)",
+ 0, 0, strategy);
+
+ // multilinestring that has closest point on box boundary
+ tester::apply("multilinestring((4 0.5,5 0.75))",
+ "box(0 0,1 1)",
+ 3, 9, strategy);
+
+ // multilinestring that has closest point on box corner
+ tester::apply("multilinestring((5 0,0 5),(4 0,0 4))",
+ "box(0 0,1 1)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_linear_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::linestring<Point> line_empty;
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+ bg::model::ring<Point> ring_empty;
+
+ bg::model::linestring<Point> line =
+ from_wkt<bg::model::linestring<Point> >("linestring(0 0,1 1)");
+
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("polygon((0 0,1 0,0 1))");
+
+ bg::model::ring<Point> ring =
+ from_wkt<bg::model::ring<Point> >("polygon((0 0,1 0,0 1))");
+
+ // 1st geometry is empty
+ test_empty_input(line_empty, polygon, strategy);
+ test_empty_input(line_empty, ring, strategy);
+ test_empty_input(multiline_empty, polygon, strategy);
+ test_empty_input(multiline_empty, ring, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(line, polygon_empty, strategy);
+ test_empty_input(line, multipolygon_empty, strategy);
+ test_empty_input(line, ring_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(line_empty, polygon_empty, strategy);
+ test_empty_input(line_empty, multipolygon_empty, strategy);
+ test_empty_input(line_empty, ring_empty, strategy);
+ test_empty_input(multiline_empty, polygon_empty, strategy);
+ test_empty_input(multiline_empty, multipolygon_empty, strategy);
+ test_empty_input(multiline_empty, ring_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_segment_polygon )
+{
+ test_distance_segment_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_polygon )
+{
+ test_distance_linestring_polygon(point_segment_strategy());
+ test_distance_linestring_open_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multilinestring_polygon )
+{
+ test_distance_multilinestring_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_segment_multipolygon )
+{
+ test_distance_segment_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_multipolygon )
+{
+ test_distance_linestring_multipolygon(point_segment_strategy());
+ test_distance_linestring_open_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multilinestring_multipolygon )
+{
+ test_distance_multilinestring_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_segment_ring )
+{
+ test_distance_segment_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_ring )
+{
+ test_distance_linestring_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multilinestring_ring )
+{
+ test_distance_multilinestring_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_segment_box )
+{
+ test_distance_segment_box(segment_box_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_box )
+{
+ test_distance_linestring_box(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multilinestring_box )
+{
+ test_distance_multilinestring_box(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_linear_areal )
+{
+ test_more_empty_input_linear_areal<point_type>(point_segment_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_l.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_l.cpp
new file mode 100644
index 00000000..62a5de86
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_l_l.cpp
@@ -0,0 +1,321 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_linear_linear
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::projected_point<> point_segment_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_segment(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<segment_type, segment_type> tester;
+
+ tester::apply("segment(0 0,10 0)",
+ "segment(4 2,4 0.5)",
+ return_type(0.5), return_type(0.25), strategy);
+
+ tester::apply("segment(0 0,10 0)",
+ "segment(4 2,4 -0.5)",
+ return_type(0), return_type(0), strategy);
+
+ tester::apply("segment(0 0,10 0)",
+ "segment(4 2,0 0)",
+ return_type(0), return_type(0), strategy);
+
+ tester::apply("segment(0 0,10 0)",
+ "segment(-2 3,1 2)",
+ return_type(2), return_type(4), strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_linestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/linestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<segment_type, linestring_type> tester;
+
+ tester::apply("segment(-1 -1,-2 -2)",
+ "linestring(2 1,1 2,4 0)",
+ sqrt(12.5), 12.5, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "linestring(2 1,1 2,4 0)",
+ 0, 0, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "linestring(3 3,3 3)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "linestring(3 3)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_linestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/linestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, linestring_type
+ > tester;
+
+ // It is not obvious that linestrings with only one point are valid
+ tester::apply("linestring(1 1)", "linestring(2 1)",
+ 1, 1, strategy);
+
+ tester::apply("linestring(1 1,3 1)", "linestring(2 1)",
+ 0, 0, strategy);
+
+ tester::apply("linestring(1 1)", "linestring(0 0,-2 0,2 -2,2 0)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(1 1,1 1)", "linestring(2 1,2 1)",
+ 1, 1, strategy);
+
+ tester::apply("linestring(1 1,1 1,1 1)", "linestring(2 1,2 1,2 1,2 1)",
+ 1, 1, strategy);
+
+ tester::apply("linestring(1 1,3 1)", "linestring(2 1,2 1)",
+ 0, 0, strategy);
+
+ tester::apply("linestring(1 1,1 1)", "linestring(0 0,-2 0,2 -2,2 0)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(1 1,3 1)", "linestring(2 1, 4 1)",
+ 0, 0, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3)", "linestring(2 1,1 2,4 0)",
+ 0, 0, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3)", "linestring(1 0,2 -1,4 0)",
+ 1, 1, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3)",
+ "linestring(1 -10,2 0,2.1 -10,4 0)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3)",
+ "linestring(1 -10,2 1.9,2.1 -10,4 0)",
+ sqrt(0.005), 0.005, strategy);
+
+ tester::apply("linestring(1 1,1 2)", "linestring(0 0,-2 0,2 -2,2 0)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_segment_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ segment_type, multi_linestring_type
+ > tester;
+
+ tester::apply("segment(-1 -1,-2 -2)",
+ "multilinestring((2 1,1 2),(4 0,4 10))",
+ sqrt(12.5), 12.5, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "multilinestring((2 1,1 2),(4 0,4 10))",
+ 0, 0, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "multilinestring((2.5 0),(3 3,3 3))",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("segment(1 1,2 2)",
+ "multilinestring((2.5 0,4 0,5 0),(3 3))",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multilinestring distance tests" << std::endl;
+#endif
+
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_linestring_type
+ > tester;
+
+ tester::apply("linestring(1 1,2 2,3 3)",
+ "multilinestring((2 1,1 2,4 0),(1 -10,2 1.9,2.1 -10,4 0))",
+ 0, 0, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3)",
+ "multilinestring((1 -10,2 0,2.1 -10,4 0),(1 -10,2 1.9,2.1 -10,4 0))",
+ sqrt(0.005), 0.005, strategy);
+
+ tester::apply("linestring(1 1,2 2)",
+ "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(2 2)",
+ "multilinestring((2.5 0,4 0,5 0),(3 3,3 3))",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(1 1,2 2)",
+ "multilinestring((2.5 0,4 0,5 0),(3 3))",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("linestring(1 1,2 2,3 3,4 4,5 5,6 6,7 7,8 8,9 9)",
+ "multilinestring((2.5 0,4 0,5 0),(10 10,10 10))",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multilinestring_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/multilinestring distance tests" << std::endl;
+#endif
+
+ typedef test_distance_of_geometries
+ <
+ multi_linestring_type, multi_linestring_type
+ > tester;
+
+ tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
+ "multilinestring((0.5 0.5,0.75 0.75),(11 0,11 7))",
+ 0, 0, strategy);
+
+ tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
+ "multilinestring((0.5 0.5,0.75 0.75),(11 0,11 0.9))",
+ sqrt(0.005), 0.005, strategy);
+
+ tester::apply("multilinestring((0 0,0 1,1 1),(10 0,11 1,12 2))",
+ "multilinestring((0.5 0.5,0.75 0.75),(11.1 0,11.1 0.9))",
+ sqrt(0.02), 0.02, strategy);
+
+ tester::apply("multilinestring((0 0),(1 1))",
+ "multilinestring((2 2),(3 3))",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_linear_linear(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::linestring<Point> line_empty;
+ bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
+
+ bg::model::linestring<Point> line =
+ from_wkt<bg::model::linestring<Point> >("linestring(0 0,1 1)");
+
+ // 1st geometry is empty
+ test_empty_input(line_empty, line, strategy);
+ test_empty_input(multiline_empty, line, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(line, line_empty, strategy);
+ test_empty_input(line, multiline_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(line_empty, line_empty, strategy);
+ test_empty_input(line_empty, multiline_empty, strategy);
+ test_empty_input(multiline_empty, multiline_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_segment_segment )
+{
+ test_distance_segment_segment(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_segment_linestring )
+{
+ test_distance_segment_linestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_linestring )
+{
+ test_distance_linestring_linestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_segment_multilinestring )
+{
+ test_distance_segment_multilinestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_multilinestring )
+{
+ test_distance_linestring_multilinestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multilinestring_multilinestring )
+{
+ test_distance_multilinestring_multilinestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_linear_linear )
+{
+ test_more_empty_input_linear_linear<point_type>(point_segment_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_ar.cpp
new file mode 100644
index 00000000..2eb132bc
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_ar.cpp
@@ -0,0 +1,671 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_pointlike_areal
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+typedef bg::model::point<double,3,bg::cs::cartesian> point_type_3d;
+typedef bg::model::multi_point<point_type_3d> multi_point_type_3d;
+typedef bg::model::polygon<point_type, false> polygon_type;
+typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+typedef bg::model::ring<point_type, false> ring_type;
+typedef bg::model::box<point_type> box_type;
+typedef bg::model::box<point_type_3d> box_type_3d;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::pythagoras<> point_point_strategy;
+typedef bg::strategy::distance::projected_point<> point_segment_strategy;
+typedef bg::strategy::distance::pythagoras_point_box<> point_box_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, polygon_type> tester;
+
+ tester::apply("point(0 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("point(12 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 2, 4, strategy);
+
+ tester::apply("point(0 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("point(0 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10),\
+ (-5 -5,-5 5,5 5,5 -5,-5 -5))",
+ 5, 25, strategy);
+
+ // polygons with single-point rings
+ tester::apply("point(0 0)",
+ "polygon((-5 5))",
+ sqrt(50.0), 50, strategy);
+
+ tester::apply("point(0 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10),(-5 5))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, ring_type> tester;
+
+ tester::apply("point(0 -20)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 10, 100, strategy);
+
+ tester::apply("point(12 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 2, 4, strategy);
+
+ tester::apply("point(0 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ // single-point rings
+ tester::apply("point(0 0)",
+ "polygon((-10 -10))",
+ sqrt(200.0), 200, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, multi_polygon_type> tester;
+
+ tester::apply("point(0 -20)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((0 22,-1 30,2 40,0 22)))",
+ 10, 100, strategy);
+
+ tester::apply("point(12 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 2, 4, strategy);
+
+ tester::apply("point(0 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+
+ tester::apply("point(0 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10),\
+ (-5 -5,-5 5,5 5,5 -5,-5 -5)),\
+ ((100 0,101 0,101 1,100 1,100 0)))",
+ 5, 25, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_polygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/polygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_point_type, polygon_type> tester;
+
+ tester::apply("multipoint(0 -20,0 -15)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 5, 25, strategy);
+
+ tester::apply("multipoint(16 0,12 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 2, 4, strategy);
+
+ tester::apply("multipoint(0 0,5 5,4 4)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ tester::apply("multipoint(0 0,2 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10),\
+ (-5 -5,-5 5,5 5,5 -5,-5 -5))",
+ 3, 9, strategy);
+
+ tester::apply("multipoint(4 4,11 11)",
+ "polygon((0 0,0 10,10 10,10 0,0 0))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_ring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/ring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_point_type, ring_type> tester;
+
+ tester::apply("multipoint(0 -20,0 -15)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 5, 25, strategy);
+
+ tester::apply("multipoint(16 0,12 0)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 2, 4, strategy);
+
+ tester::apply("multipoint(0 0,5 5,4 4)",
+ "polygon((-10 -10,10 -10,10 10,-10 10,-10 -10))",
+ 0, 0, strategy);
+
+ // single-point ring
+ tester::apply("multipoint(0 0,5 5,4 4)",
+ "polygon((10 10))",
+ sqrt(50.0), 50, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_multipolygon(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multipolygon distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_polygon_type
+ > tester;
+
+ tester::apply("multipoint(0 -20,0 -15)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((0 22,-1 30,2 40,0 22)))",
+ 5, 25, strategy);
+
+ tester::apply("multipoint(16 0,12 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 2, 4, strategy);
+
+ tester::apply("multipoint(0 0,4 4,5 5)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10)),\
+ ((20 -1,21 2,30 -10,20 -1)))",
+ 0, 0, strategy);
+
+ tester::apply("multipoint(0 0,2 0)",
+ "multipolygon(((-10 -10,10 -10,10 10,-10 10,-10 -10),\
+ (-5 -5,-5 5,5 5,5 -5,-5 -5)),\
+ ((100 0,101 0,101 1,100 1,100 0)))",
+ 3, 9, strategy);
+
+ tester::apply("MULTIPOINT(19 19,100 100)",
+ "MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0),\
+ (4 4,4 6,6 6,6 4,4 4)), ((10 10,10 20,20 20,20 10,10 10),\
+ (14 14,14 16,16 16,16 14,14 14)))",
+ 0, 0, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_box_2d(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "2D point/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<box_type, point_type> tester;
+
+ // point inside box
+ tester::apply("box(-1 -1,1 1)",
+ "point(0 0)", 0, 0, strategy);
+
+ // points on box corners
+ tester::apply("box(-1 -1,1 1)",
+ "point(-1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-1 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(1 1)", 0, 0, strategy);
+
+ // points on box boundary edges
+ tester::apply("box(-1 -1,1 1)",
+ "point(0 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(0 1)", 0, 0, strategy);
+
+ // points outside box
+ tester::apply("box(-1 -1,1 1)",
+ "point(0 4)", 3, 9, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(0.5 4)", 3, 9, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-0.5 5)", 4, 16, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(3 0.25)", 2, 4, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-3 -0.25)", 2, 4, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(3 5)", sqrt(20.0), 20, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-5 -4)", 5, 25, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(2 -2)", sqrt(2.0), 2, strategy);
+ tester::apply("box(-1 -1,1 1)",
+ "point(-3 4)", sqrt(13.0), 13, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_box_different_point_types(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "2D point/box distance tests with different points"
+ << std::endl;
+#endif
+ typedef point_type double_point;
+ typedef box_type double_box;
+ typedef bg::model::point<int,2,bg::cs::cartesian> int_point;
+ typedef bg::model::box<int_point> int_box;
+
+ test_distance_of_geometries
+ <
+ int_point, int_box
+ >::apply("point(0 0)",
+ "box(1 1, 2 2)",
+ sqrt(2.0), 2, strategy);
+
+ test_distance_of_geometries
+ <
+ double_point, int_box
+ >::apply("point(0.5 0)",
+ "box(1 -1,2 1)",
+ 0.5, 0.25, strategy);
+
+ test_distance_of_geometries
+ <
+ double_point, double_box
+ >::apply("point(1.5 0)",
+ "box(1 -1,2 1)",
+ 0, 0, strategy);
+
+ test_distance_of_geometries
+ <
+ double_point, int_box
+ >::apply("point(1.5 0)",
+ "box(1 -1,2 1)",
+ 0, 0, strategy);
+
+ test_distance_of_geometries
+ <
+ int_point, double_box
+ >::apply("point(1 0)",
+ "box(0.5 -1,1.5 1)",
+ 0, 0, strategy);
+
+ test_distance_of_geometries
+ <
+ int_point, double_box
+ >::apply("point(0 0)",
+ "box(0.5, -1,1.5, 1)",
+ 0.5, 0.25, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_box_3d(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "3D point/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<box_type_3d, point_type_3d> tester;
+
+ // point inside box
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 0 0)", 0, 0, strategy);
+
+ // points on box corners
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 -1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 -1 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 1 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 -1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 -1 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 1 1)", 0, 0, strategy);
+
+ // points on box boundary edges
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -1 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 1 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 1 1)", 0, 0, strategy);
+
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 0 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 0 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 0 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 0 1)", 0, 0, strategy);
+
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 -1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 -1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 1 0)", 0, 0, strategy);
+
+ // point on box faces
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 0 -1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 0 1)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 1 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-1 0 0)", 0, 0, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(1 0 0)", 0, 0, strategy);
+
+ // points outside box -- closer to box corners
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-2 -3 -4)", sqrt(14.0), 14, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-2 -3 3)", 3, 9, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-2 5 -2)", sqrt(18.0), 18, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-2 5 3)", sqrt(21.0), 21, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(4 -6 -3)", sqrt(38.0), 38, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(4 -6 4)", sqrt(43.0), 43, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(4 7 -2)", sqrt(46.0), 46, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(4 7 8)", sqrt(94.0), 94, strategy);
+
+
+ // points closer to box facets
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 0 10)", 9, 81, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 0 -5)", 4, 16, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 7 0)", 6, 36, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -6 0)", 5, 25, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(4 0 0)", 3, 9, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-3 0 0)", 2, 4, strategy);
+
+ // points closer to box edges
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -4 -5)", 5, 25, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 -3 6)", sqrt(29.0), 29, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 2 -7)", sqrt(37.0), 37, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(0 8 7)", sqrt(85.0), 85, strategy);
+
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-4 0 -4)", sqrt(18.0), 18, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-3 0 5)", sqrt(20.0), 20, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(2 0 -6)", sqrt(26.0), 26, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(8 0 6)", sqrt(74.0), 74, strategy);
+
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-5 -5 0)", sqrt(32.0), 32, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(-4 6 0)", sqrt(34.0), 34, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(3 -7 0)", sqrt(40.0), 40, strategy);
+ tester::apply("box(-1 -1 -1,1 1 1)",
+ "point(9 7 0)", 10, 100, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_box_2d(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "2D multipoint/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<box_type, multi_point_type> tester;
+
+ // at least one point inside the box
+ tester::apply("box(0 0,10 10)",
+ "multipoint(0 0,-1 -1,20 20)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,10 10)",
+ "multipoint(1 1,-1 -1,20 20)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0,10 10)",
+ "multipoint(1 1,2 2,3 3)",
+ 0, 0, strategy);
+
+ // all points outside the box
+ tester::apply("box(0 0,10 10)",
+ "multipoint(-1 -1,20 20)",
+ sqrt(2.0), 2, strategy);
+
+ tester::apply("box(0 0,10 10)",
+ "multipoint(5 13, 50 50)",
+ 3, 9, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_box_3d(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "3D multipoint/box distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ box_type_3d, multi_point_type_3d
+ > tester;
+
+ // at least one point inside the box
+ tester::apply("box(0 0 0,10 10 10)",
+ "multipoint(0 0 0,-1 -1 -1,20 20 20)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0 0,10 10 10)",
+ "multipoint(1 1 1,-1 -1 -1,20 20 20)",
+ 0, 0, strategy);
+
+ tester::apply("box(0 0 0,10 10 10)",
+ "multipoint(1 1 1,2 2 2,3 3 3)",
+ 0, 0, strategy);
+
+ // all points outside the box
+ tester::apply("box(0 0 0,10 10 10)",
+ "multipoint(-1 -1 -1,20 20 20)",
+ sqrt(3.0), 3, strategy);
+
+ tester::apply("box(0 0 0,10 10 10)",
+ "multipoint(5 5 13,50 50 50)",
+ 3, 9, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_pointlike_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::multi_point<Point> multipoint_empty;
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+ bg::model::ring<Point> ring_empty;
+
+ Point point = from_wkt<Point>("point(0 0)");
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("polygon((0 0,1 0,0 1))");
+ bg::model::ring<Point> ring =
+ from_wkt<bg::model::ring<Point> >("polygon((0 0,1 0,0 1))");
+
+ // 1st geometry is empty
+ test_empty_input(multipoint_empty, polygon, strategy);
+ test_empty_input(multipoint_empty, ring, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(point, polygon_empty, strategy);
+ test_empty_input(point, multipolygon_empty, strategy);
+ test_empty_input(point, ring_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(multipoint_empty, polygon_empty, strategy);
+ test_empty_input(multipoint_empty, multipolygon_empty, strategy);
+ test_empty_input(multipoint_empty, ring_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_polygon )
+{
+ test_distance_point_polygon(point_point_strategy()); // back-compatibility
+ test_distance_point_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_multipolygon )
+{
+ test_distance_point_multipolygon(point_point_strategy()); // back-compatibility
+ test_distance_point_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_ring )
+{
+ test_distance_point_ring(point_point_strategy()); // back-compatibility
+ test_distance_point_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_polygon )
+{
+ test_distance_multipoint_polygon(point_point_strategy()); // back-compatibility
+ test_distance_multipoint_polygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_multipolygon )
+{
+ test_distance_multipoint_multipolygon(point_point_strategy()); // back-compatibility
+ test_distance_multipoint_multipolygon(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_ring )
+{
+ test_distance_multipoint_ring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_box_2d )
+{
+ point_box_strategy pb_strategy;
+
+ test_distance_point_box_2d(pb_strategy);
+ test_distance_point_box_different_point_types(pb_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_box_3d )
+{
+ test_distance_point_box_3d(point_box_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_box_2d )
+{
+ test_distance_multipoint_box_2d(point_box_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_box_3d )
+{
+ test_distance_multipoint_box_3d(point_box_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_areal )
+{
+ test_more_empty_input_pointlike_areal
+ <
+ point_type
+ >(point_segment_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_l.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_l.cpp
new file mode 100644
index 00000000..bd505fca
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_l.cpp
@@ -0,0 +1,318 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_pointlike_linear
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+#include "test_empty_geometry.hpp"
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::pythagoras<> point_point_strategy;
+typedef bg::strategy::distance::projected_point<> point_segment_strategy;
+
+
+//===========================================================================
+
+
+template <typename Strategy>
+void test_distance_point_segment(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, segment_type> tester;
+
+ tester::apply("point(0 0)", "segment(2 0,3 0)", 2, 4, strategy);
+ tester::apply("point(2.5 3)", "segment(2 0,3 0)", 3, 9, strategy);
+ tester::apply("point(2 0)", "segment(2 0,3 0)", 0, 0, strategy);
+ tester::apply("point(3 0)", "segment(2 0,3 0)", 0, 0, strategy);
+ tester::apply("point(2.5 0)", "segment(2 0,3 0)", 0, 0, strategy);
+
+ // distance is a NaN
+ tester::apply("POINT(4.297374e+307 8.433875e+307)",
+ "SEGMENT(26 87,13 95)",
+ 0, 0, strategy, false);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_linestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/linestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, linestring_type> tester;
+
+ tester::apply("point(0 0)", "linestring(2 0,3 0)", 2, 4, strategy);
+ tester::apply("point(2.5 3)", "linestring(2 0,3 0)", 3, 9, strategy);
+ tester::apply("point(2 0)", "linestring(2 0,3 0)", 0, 0, strategy);
+ tester::apply("point(3 0)", "linestring(2 0,3 0)", 0, 0, strategy);
+ tester::apply("point(2.5 0)", "linestring(2 0,3 0)", 0, 0, strategy);
+
+ // linestring with a single point
+ tester::apply("point(0 0)", "linestring(2 0)", 2, 4, strategy);
+
+ // distance is a NaN
+ tester::apply("POINT(4.297374e+307 8.433875e+307)",
+ "LINESTRING(26 87,13 95)",
+ 0, 0, strategy, false);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ point_type, multi_linestring_type
+ > tester;
+
+ tester::apply("point(0 0)",
+ "multilinestring((-5 0,-3 0),(2 0,3 0))",
+ 2, 4, strategy);
+ tester::apply("point(2.5 3)",
+ "multilinestring((-5 0,-3 0),(2 0,3 0))",
+ 3, 9, strategy);
+ tester::apply("point(2 0)",
+ "multilinestring((-5 0,-3 0),(2 0,3 0))",
+ 0, 0, strategy);
+ tester::apply("point(3 0)",
+ "multilinestring((-5 0,-3 0),(2 0,3 0))",
+ 0, 0, strategy);
+ tester::apply("point(2.5 0)",
+ "multilinestring((-5 0,-3 0),(2 0,3 0))",
+ 0, 0, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((10 10,10 0),(0.0 -0.0,0.0 -0.0))",
+ 0, 0, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((10 10,10 0),(1 1,1 1))",
+ sqrt(2.0), 2, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((10 10,10 0),(1 1,2 2))",
+ sqrt(2.0), 2, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((10 10,10 0),(20 20,20 20))",
+ 10, 100, strategy);
+
+ // multilinestrings containing an empty linestring
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((),(10 0),(20 20,20 20))",
+ 10, 100, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((),(10 0),(),(20 20,20 20))",
+ 10, 100, strategy);
+
+ // multilinestrings containing a linestring with a single point
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((10 0),(20 20,20 20))",
+ 10, 100, strategy);
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((20 20,20 20),(10 0))",
+ 10, 100, strategy);
+
+ // multilinestring with a single-point linestring and empty linestrings
+ tester::apply("POINT(0 0)",
+ "MULTILINESTRING((),(20 20,20 20),(),(10 0))",
+ 10, 100, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_point_type
+ > tester;
+
+ tester::apply("linestring(2 0,0 2,100 100)",
+ "multipoint(0 0,1 0,0 1,1 1)",
+ 0, 0, strategy);
+ tester::apply("linestring(4 0,0 4,100 100)",
+ "multipoint(0 0,1 0,0 1,1 1)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("linestring(1 1,2 2,100 100)",
+ "multipoint(0 0,1 0,0 1,1 1)",
+ 0, 0, strategy);
+ tester::apply("linestring(3 3,4 4,100 100)",
+ "multipoint(0 0,1 0,0 1,1 1)",
+ sqrt(8.0), 8, strategy);
+
+ // linestring with a single point
+ tester::apply("linestring(1 8)",
+ "multipoint(0 0,3 0,4 -7,10 100)",
+ sqrt(65.0), 65, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_linestring_type
+ > tester;
+
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((2 0,0 2),(2 2,3 3))",
+ 0, 0, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((3 0,0 3),(4 4,5 5))",
+ 0.5 * sqrt(2.0), 0.5, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((4 4,5 5),(1 1,2 2))",
+ 0, 0, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((3 3,4 4),(4 4,5 5))",
+ sqrt(8.0), 8, strategy);
+
+ // multilinestring with empty linestring
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((),(3 3,4 4),(4 4,5 5))",
+ sqrt(8.0), 8, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((3 3,4 4),(),(4 4,5 5))",
+ sqrt(8.0), 8, strategy);
+
+ // multilinestrings with a single-point linestrings
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((3 3),(4 4,5 5))",
+ sqrt(8.0), 8, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((4 4,5 5),(3 3))",
+ sqrt(8.0), 8, strategy);
+
+ // multilinestring with a single-point linestring and empty linestring
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multilinestring((4 4,5 5),(),(3 3))",
+ sqrt(8.0), 8, strategy);
+
+ // 21890717 - assertion failure in distance(Pt, Box)
+ {
+ multi_point_type mpt;
+ bg::read_wkt("multipoint(1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1,1 1)", mpt);
+ multi_linestring_type mls;
+ linestring_type ls;
+ point_type pt(std::numeric_limits<double>::quiet_NaN(), 1.0);
+ ls.push_back(pt);
+ ls.push_back(pt);
+ mls.push_back(ls);
+ bg::distance(mpt, mls);
+ }
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_segment(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
+
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "segment(2 0,0 2)",
+ 0, 0, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "segment(4 0,0 4)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "segment(1 1,2 2)",
+ 0, 0, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "segment(3 3,4 4)",
+ sqrt(8.0), 8, strategy);
+ tester::apply("multipoint(4 4,5 5,2 2,3 3)",
+ "segment(0 0,1 1)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_point_segment )
+{
+ test_distance_point_segment(point_point_strategy()); // back-compatibility
+ test_distance_point_segment(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_linestring )
+{
+ test_distance_point_linestring(point_point_strategy()); // back-compatibility
+ test_distance_point_linestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_multilinestring )
+{
+ test_distance_point_multilinestring(point_point_strategy()); // back-compatibility
+ test_distance_point_multilinestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_multipoint )
+{
+ test_distance_linestring_multipoint(point_point_strategy()); // back-compatibility
+ test_distance_linestring_multipoint(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_multilinestring )
+{
+ test_distance_multipoint_multilinestring(point_point_strategy()); // back-compatibility
+ test_distance_multipoint_multilinestring(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_segment )
+{
+ test_distance_multipoint_segment(point_segment_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_linear )
+{
+ test_more_empty_input_pointlike_linear
+ <
+ point_type
+ >(point_segment_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_pl.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_pl.cpp
new file mode 100644
index 00000000..8726562a
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_ca_pl_pl.cpp
@@ -0,0 +1,123 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_cartesian_pointlike_pointlike
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_common.hpp"
+#include "test_empty_geometry.hpp"
+
+
+typedef bg::model::point<double,2,bg::cs::cartesian> point_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::pythagoras<> point_point_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_point(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/point distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, point_type> tester;
+
+ tester::apply("point(1 1)",
+ "point(0 0)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("point(1 1)",
+ "point(1 1)",
+ 0, 0, strategy);
+
+ // distance overflows
+ tester::apply("point(0 0)",
+ "point(4.297374e+307 8.433875e+307)",
+ 0, 0, strategy, false);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, multi_point_type> tester;
+
+ tester::apply("point(1 1)",
+ "multipoint(1 1,2 1,2 2,1 2)",
+ 0, 0, strategy);
+ tester::apply("point(1 1)",
+ "multipoint(2 2,2 3,3 2,3 3)",
+ sqrt(2.0), 2, strategy);
+ tester::apply("point(3 0)",
+ "multipoint(2 2,2 4,4 2,4 4)",
+ sqrt(5.0), 5, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_point_type
+ > tester;
+
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multipoint(1 1,2 1,2 2,1 2)",
+ 0, 0, strategy);
+ tester::apply("multipoint(0 0,1 0,0 1,1 1)",
+ "multipoint(2 2,2 3,3 2,3 3)",
+ sqrt(2.0), 2, strategy);
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_point_point )
+{
+ test_distance_point_point(point_point_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_multipoint )
+{
+ test_distance_point_multipoint(point_point_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_multipoint )
+{
+ test_distance_multipoint_multipoint(point_point_strategy());
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike )
+{
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(point_point_strategy());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_geo_linear_box.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_geo_linear_box.cpp
new file mode 100644
index 00000000..4b6aacf3
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_geo_linear_box.cpp
@@ -0,0 +1,567 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2017, 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_linear_areal
+#endif
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_geo_common.hpp"
+//#include "test_empty_geometry.hpp"
+
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_segment_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<segment_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("s-r-1", "SEGMENT(0 0, 0 10)", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<linestring_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("l-r-1", "LINESTRING(0 0, 0 10)", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_linestring_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<multi_linestring_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("ml-r-1", "MULTILINESTRING((0 0, 0 10)(0 0, 10 0))", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+//=====================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_segment_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<segment_type, multi_polygon_type> tester;
+
+ std::string const mp = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("s-r-1", "SEGMENT(0 0, 0 10)", mp,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<linestring_type, multi_polygon_type> tester;
+
+ std::string const mp = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("l-r-1", "LINESTRING(0 0, 0 10)", mp,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_linestring_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<multi_linestring_type, multi_polygon_type> tester;
+
+ std::string const polygon = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("ml-r-1", "MULTILINESTRING((0 0, 0 10)(0 0, 10 0))", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+//=====================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_segment_ring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<segment_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("s-r-1", "SEGMENT(0 0, 0 10)", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_ring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<linestring_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("l-r-1", "LINESTRING(0 0, 0 10)", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_linestring_ring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<multi_linestring_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("ml-r-1", "MULTILINESTRING((0 0, 0 10)(0 0, 10 0))", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+//======================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps, typename Strategy_sb>
+void test_distance_segment_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/box distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<segment_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sb1-1a", "SEGMENT(0 0, 0 20)", box_north,
+ pp_distance<Point>("POINT(0 20)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+ //segment with slope
+ tester::apply("sb1-1b", "SEGMENT(10 5, 20 6)", box_north,
+ pp_distance<Point>("POINT(20 6)", "POINT(20 10)", strategy_pp),
+ strategy_sb);
+ tester::apply("sb1-2", "SEGMENT(0 0, 0 10)", box_north,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-3", "SEGMENT(0 0, 0 15)", box_north,
+ ps_distance<Point>("POINT(0 15)", "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-4", "SEGMENT(0 0, 0 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 0,0 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-5", "SEGMENT(0 10, 0 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 0,0 25)", strategy_ps),
+ strategy_sb);
+
+ tester::apply("sb2-2", "SEGMENT(0 5, 15 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,15 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb2-3a", "SEGMENT(0 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,20 5)", strategy_ps),
+ strategy_sb);
+
+ // Test segments below box
+ tester::apply("test_b1", "SEGMENT(0 5, 9 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 9 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b2", "SEGMENT(0 5, 10 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 10 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b3", "SEGMENT(0 5, 11 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 11 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b4", "SEGMENT(0 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,20 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b5", "SEGMENT(0 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(11 10)", "SEGMENT(0 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b6", "SEGMENT(10 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(15 10)", "SEGMENT(10 5,20 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b7", "SEGMENT(10 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(16 10)", "SEGMENT(10 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b8", "SEGMENT(12 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(17 10)", "SEGMENT(12 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b9", "SEGMENT(18 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(18 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b10", "SEGMENT(18 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(18 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b11", "SEGMENT(20 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(20 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b12", "SEGMENT(22 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(22 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b13", "SEGMENT(0 5, 125 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(0 5, 125 5)", strategy_ps),
+ strategy_sb);
+
+ // Test segments above box
+ tester::apply("test_a1", "SEGMENT(0 25, 9 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 25, 9 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a2", "SEGMENT(0 25, 10 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 25, 10 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a3", "SEGMENT(0 25, 11 25)", box_north,
+ ps_distance<Point>("POINT(11 20)", "SEGMENT(0 25, 11 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a4", "SEGMENT(0 25, 20 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(0 25, 20 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a5", "SEGMENT(0 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(0 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a6", "SEGMENT(10 25, 20 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(10 25, 20 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a7", "SEGMENT(10 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(10 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a8", "SEGMENT(12 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(12 20)", "SEGMENT(12 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a9", "SEGMENT(18 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(18 20)", "SEGMENT(18 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a10", "SEGMENT(18 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(18 20)", "SEGMENT(18 25, 24 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a11", "SEGMENT(20 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(20 25, 24 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a12", "SEGMENT(22 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(22 25, 24 25)", strategy_ps),
+ strategy_sb);
+
+ // Segments left-right of box
+ tester::apply("test_l1", "SEGMENT(0 5, 9 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 9 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l2", "SEGMENT(0 10, 9 10)", box_north,
+ ps_distance<Point>("POINT(9 10)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l3", "SEGMENT(0 10, 9 15)", box_north,
+ ps_distance<Point>("POINT(9 15)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l4", "SEGMENT(0 10, 0 15)", box_north,
+ ps_distance<Point>("POINT(0 15)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l5", "SEGMENT(1 10, 0 15)", box_north,
+ ps_distance<Point>("POINT(1 10)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l6", "SEGMENT(0 20, 9 21)", box_north,
+ ps_distance<Point>("POINT(9 21)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r1", "SEGMENT(21 5, 29 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(21 5, 29 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r2", "SEGMENT(21 10, 29 10)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r3", "SEGMENT(21 10, 29 15)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r4", "SEGMENT(21 10, 21 15)", box_north,
+ ps_distance<Point>("POINT(21 15)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r5", "SEGMENT(21 10, 22 15)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r6", "SEGMENT(29 20, 21 21)", box_north,
+ ps_distance<Point>("POINT(21 21)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+
+ //Segments on corners of box
+ //left-top corner
+ //generic
+ tester::apply("test_c1", "SEGMENT(9 19.5, 11 21)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(9 19.5, 11 21)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c2", "SEGMENT(9 19, 11 21)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(9 19, 11 21)", strategy_ps),
+ strategy_sb);
+ //left-bottom corner
+ //generic
+ tester::apply("test_c3", "SEGMENT(8.5 11, 11 9)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(8.5 11, 11 9)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c4", "SEGMENT(9 11, 11 9)", box_north,
+ 0,
+ strategy_sb);
+ //right-top corner
+ //generic
+ tester::apply("test_c5", "SEGMENT(19 21, 21 19.5)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(19 21, 21 19.5)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c6", "SEGMENT(19 21, 21 19)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(19 21, 21 19)", strategy_ps),
+ strategy_sb);
+ //right-bottom corner
+ //generic
+ tester::apply("test_c7", "SEGMENT(19 9, 21 10.5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(19 9, 21 10.5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_c7", "SEGMENT(19 9, 21 11)", box_north,
+ 0,
+ strategy_sb);
+
+ //Segment and box on different hemispheres
+ std::string const box_south = "BOX(10 -20,20 -10)";
+
+ tester::apply("test_ns1", "SEGMENT(10 20, 15 30)", box_south,
+ ps_distance<Point>("POINT(10 -10)", "SEGMENT(10 20, 15 30)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_ns2", "SEGMENT(0 10, 12 10)", box_south,
+ pp_distance<Point>("POINT(12 10)", "POINT(12 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns3", "SEGMENT(10 10, 20 10)", box_south,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns4", "SEGMENT(0 -10, 12 -10)", box_north,
+ pp_distance<Point>("POINT(12 10)", "POINT(12 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns5", "SEGMENT(10 -10, 20 -10)", box_north,
+ pp_distance<Point>("POINT(10 -10)", "POINT(10 10)", strategy_pp),
+ strategy_sb);
+
+ //Box crossing equator
+ std::string const box_crossing_eq = "BOX(10 -10,20 10)";
+
+ tester::apply("test_cr1", "SEGMENT(10 20, 15 30)", box_crossing_eq,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr2", "SEGMENT(10 -20, 15 -30)", box_crossing_eq,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+
+ //Box crossing prime meridian
+
+ std::string const box_crossing_mer = "BOX(-10 10,15 20)";
+
+ tester::apply("test_cr3", "SEGMENT(-5 25, 10 30)", box_crossing_mer,
+ pp_distance<Point>("POINT(-5 25)", "POINT(-5 20)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr4", "SEGMENT(-5 5, 10 7)", box_crossing_mer,
+ pp_distance<Point>("POINT(10 7)", "POINT(10 10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr5", "SEGMENT(-5 5, 10 5)", box_crossing_mer,
+ ps_distance<Point>("POINT(2.5 10)", "SEGMENT(-5 5, 10 5)", strategy_ps),
+ strategy_sb);
+
+
+ //Geometries in south hemisphere
+ tester::apply("test_south1", "SEGMENT(10 -30, 15 -30)", box_south,
+ ps_distance<Point>("POINT(10 -20)", "SEGMENT(10 -30, 15 -30)", strategy_ps),
+ strategy_sb);
+
+ //Segments in boxes corner
+ tester::apply("corner1", "SEGMENT(17 21, 25 20)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(17 21, 25 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner2", "SEGMENT(17 21, 0 20)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(17 21, 0 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner3", "SEGMENT(17 5, 0 10)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(17 5, 0 10)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner4", "SEGMENT(17 5, 25 9)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(17 5, 25 9)", strategy_ps),
+ strategy_sb);
+}
+
+template <typename Point, typename Strategy_ps, typename Strategy_sb>
+void test_distance_linestring_box(Strategy_ps const& strategy_ps, Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/box distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<linestring_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sl1", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 0 10)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(15 21, 25 19.9)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("sl2", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 15 15)", box_north,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("sl3", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 2 20)", box_north,
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_ps, typename Strategy_sb>
+void test_distance_multi_linestring_box(Strategy_ps const& strategy_ps, Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multi_linestring/box distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<multi_linestring_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sl1", "MULTILINESTRING((0 20, 15 21, 25 19.9, 21 5, 15 5, 0 10)(25 20, 22 4, 0 0))", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(15 21, 25 19.9)", strategy_ps),
+ strategy_sb, true, false, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps, typename Strategy_sb>
+void test_all_l_ar(Strategy_pp pp_strategy, Strategy_ps ps_strategy, Strategy_sb sb_strategy)
+{
+ test_distance_segment_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_linestring_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_linestring_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_segment_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_linestring_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_linestring_multi_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_segment_ring<Point>(pp_strategy, ps_strategy);
+ test_distance_linestring_ring<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_linestring_ring<Point>(pp_strategy, ps_strategy);
+
+ test_distance_segment_box<Point>(pp_strategy, ps_strategy, sb_strategy);
+ //test_distance_linestring_box<Point>(ps_strategy, sb_strategy);
+ //test_distance_multi_linestring_box<Point>(ps_strategy, sb_strategy);
+
+ //test_more_empty_input_linear_areal<Point>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linear_areal )
+{
+ typedef bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >
+ sph_point;
+ test_all_l_ar<sph_point>(spherical_pp(), spherical_ps(), spherical_sb());
+
+ typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree> > geo_point;
+
+ test_all_l_ar<geo_point>(vincenty_pp(), vincenty_ps(), vincenty_sb());
+ test_all_l_ar<geo_point>(thomas_pp(), thomas_ps(), thomas_sb());
+ test_all_l_ar<geo_point>(andoyer_pp(), andoyer_ps(), andoyer_sb());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_geo_pl_l.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_geo_pl_l.cpp
new file mode 100644
index 00000000..76e300e6
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_geo_pl_l.cpp
@@ -0,0 +1,728 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_pointlike_linear
+#endif
+
+#include <sstream>
+
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+typedef bg::cs::geographic<bg::degree> cs_type;
+typedef bg::model::point<double, 2, cs_type> point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+typedef bg::cs::geographic<bg::radian> cs_type_rad;
+typedef bg::model::point<double, 2, cs_type_rad> point_type_rad;
+typedef bg::model::segment<point_type_rad> segment_type_rad;
+
+//===========================================================================
+
+template <typename Strategy>
+inline bg::default_distance_result<point_type>::type
+pp_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::distance(p1, p2, strategy);
+}
+
+template <typename Strategy>
+inline bg::default_distance_result<point_type>::type
+ps_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p;
+ segment_type s;
+ bg::read_wkt(wkt1, p);
+ bg::read_wkt(wkt2, s);
+ return bg::distance(p, s, strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_point_segment(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ bool WGS84)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, segment_type> tester;
+
+ tester::apply("p-s-01",
+ "POINT(0 0)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-02",
+ "POINT(2.5 3)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-03",
+ "POINT(2 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy_ps, true, true);
+ tester::apply("p-s-04",
+ "POINT(3 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy_ps, true, true);
+ tester::apply("p-s-05",
+ "POINT(2.5 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy_ps, true, true);
+ tester::apply("p-s-06",
+ "POINT(3.5 3)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy_pp),
+ strategy_ps, true, true);
+ if(WGS84)
+ {
+ tester::apply("p-s-07",
+ "POINT(15 80)",
+ "SEGMENT(10 15,30 15)",
+ 7204174.8264546748,
+ strategy_ps, true, true);
+ tester::apply("p-s-08",
+ "POINT(15 10)",
+ "SEGMENT(10 15,30 15)",
+ 571412.71247283253,
+ strategy_ps, true, true);
+ }
+ tester::apply("p-s-09",
+ "POINT(5 10)",
+ "SEGMENT(10 15,30 15)",
+ pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-10",
+ "POINT(35 10)",
+ "SEGMENT(10 15,30 15)",
+ pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-11",
+ "POINT(5 10)",
+ "SEGMENT(30 15,10 15)",
+ pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-12",
+ "POINT(35 10)",
+ "SEGMENT(30 15,10 15)",
+ pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-right-up",
+ "POINT(3.5 3)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3.5 3)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-left-up",
+ "POINT(1.5 3)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(2 2)", "POINT(1.5 3)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-up-1",
+ "POINT(2 3)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(2.0003 2)", "POINT(2 3)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-up-2",
+ "POINT(3 3)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(2.9997 2)", "POINT(3 3)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-right-down",
+ "POINT(3.5 1)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3.5 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-left-down",
+ "POINT(1.5 1)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(2 2)", "POINT(1.5 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-down-1",
+ "POINT(2 1)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(2 2)", "POINT(2 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-down-2",
+ "POINT(3 1)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-south",
+ "POINT(3 -1)",
+ "SEGMENT(2 -2,3 -2)",
+ pp_distance("POINT(3 -2)", "POINT(3 -1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-antimeridian-1",
+ "POINT(3 1)",
+ "SEGMENT(220 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-antimeridian-2",
+ "POINT(220 1)",
+ "SEGMENT(220 2,3 2)",
+ pp_distance("POINT(220 2)", "POINT(220 1)", strategy_pp),
+ strategy_ps, true, true);
+
+ // equator special case
+ tester::apply("p-s-eq1",
+ "POINT(2.5 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy_ps, true, true);
+ tester::apply("p-s-eq2",
+ "POINT(2.5 2)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(2.5 0)", "POINT(2.5 2)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-eq3",
+ "POINT(2 2)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(2 0)", "POINT(2 2)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-eq4",
+ "POINT(3 2)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(3 0)", "POINT(3 2)", strategy_pp),
+ strategy_ps, true, true);
+
+ // meridian special case
+ tester::apply("p-s-mer1",
+ "POINT(2.5 2)",
+ "SEGMENT(2 2,2 4)",
+ pp_distance("POINT(2.5 2)", "POINT(2 2.000076608014728)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-mer3",
+ "POINT(2.5 5)",
+ "SEGMENT(2 2,2 4)",
+ pp_distance("POINT(2.5 5)", "POINT(2 4)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-mer4",
+ "POINT(0 20)",
+ "SEGMENT(0 40,180 80)",
+ pp_distance("POINT(0 20)", "POINT(0 40)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-mer5",
+ "POINT(0 20)",
+ "SEGMENT(0 40,0 80)",
+ pp_distance("POINT(0 20)", "POINT(0 40)", strategy_pp),
+ strategy_ps, true, true);
+
+ //degenerate segment
+ tester::apply("p-s-deg",
+ "POINT(1 80)",
+ "SEGMENT(0 0,0 0)",
+ pp_distance("POINT(0 0)", "POINT(1 80)", strategy_pp),
+ strategy_ps, true, true);
+
+ //point on segment
+ tester::apply("p-s-deg",
+ "POINT(0 80)",
+ "SEGMENT(0 0,0 90)",
+ 0,
+ strategy_ps, true, true);
+
+ // very small distances to segment
+ tester::apply("p-s-07",
+ "POINT(90 1e-3)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-3)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-08",
+ "POINT(90 1e-4)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-4)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-09",
+ "POINT(90 1e-5)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-5)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-10",
+ "POINT(90 1e-6)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-6)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-11",
+ "POINT(90 1e-7)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-7)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-12",
+ "POINT(90 1e-8)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 1e-8)", strategy_pp),
+ strategy_ps, true, true);
+
+ // very large distance to segment
+ tester::apply("p-s-13",
+ "POINT(90 90)",
+ "SEGMENT(0.5 0,175.5 0)",
+ pp_distance("POINT(90 0)", "POINT(90 90)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-14",
+ "POINT(90 90)",
+ "SEGMENT(0.5 -89,175.5 -89)",
+ pp_distance("POINT(90 -89)", "POINT(90 90)", strategy_pp),
+ strategy_ps, true, true);
+ // degenerate segment
+ tester::apply("p-s-15",
+ "POINT(90 90)",
+ "SEGMENT(0.5 -90,175.5 -90)",
+ pp_distance("POINT(0.5 -90)", "POINT(90 90)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-16",
+ "POINT(90 90)",
+ "SEGMENT(0.5 -90,175.5 -90)",
+ pp_distance("POINT(90 -90)", "POINT(90 90)", strategy_pp),
+ strategy_ps, true, true);
+ // equatorial segment
+ tester::apply("p-s-17",
+ "POINT(90 90)",
+ "SEGMENT(0 0,175.5 0)",
+ pp_distance("POINT(90 90)", "POINT(0 0)", strategy_pp),
+ strategy_ps, true, true);
+ // segment pass by pole
+ tester::apply("p-s-18",
+ "POINT(90 90)",
+ "SEGMENT(0 0,180 0)",
+ 0,
+ strategy_ps, true, true);
+
+ tester::apply("p-s-20",
+ "POINT(80 89)",
+ "SEGMENT(0 0,180 0)",
+ pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-21",
+ "POINT(80 89)",
+ "SEGMENT(0 -1,180 1)",
+ pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp),
+ strategy_ps, true, true);
+
+ // meridian special case
+ tester::apply("p-s-mer1",
+ "POINT(2.5 3)",
+ "SEGMENT(2 2,2 4)",
+ pp_distance("POINT(2.5 3)", "POINT(2 3.000114792872075)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-mer2",
+ "POINT(1 80)",
+ "SEGMENT(0 0,0 90)",
+ pp_distance("POINT(1 80)", "POINT(0 80.00149225834545)", strategy_pp),
+ strategy_ps, true, true);
+ tester::apply("p-s-mer3",
+ "POINT(2 0)",
+ "SEGMENT(1 -1,1 0)",
+ pp_distance("POINT(2 0)", "POINT(1 0)", strategy_pp),
+ strategy_ps, true, true);
+
+ tester::apply("p-s-acos",
+ "POINT(0 90)",
+ "SEGMENT(90 0,0 1.000005)",
+ pp_distance("POINT(0 90)", "POINT(0.3017072304435489 1.000018955050697)",
+ strategy_pp),
+ strategy_ps, true, true);
+}
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_point_segment_no_thomas(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, segment_type> tester;
+
+ // thomas strategy is failing for those test cases
+ // this is because of inaccurate results for points close to poles
+
+ tester::apply("p-s-19",
+ "POINT(90 89)",
+ "SEGMENT(0 0,180 0)",
+ pp_distance("POINT(90 89)", "POINT(90 90)", strategy_pp),
+ strategy_ps, true, true);
+}
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_point_segment_rad_mix(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, segment_type> tester1;
+ typedef test_distance_of_geometries<point_type_rad, segment_type> tester2;
+ typedef test_distance_of_geometries<point_type, segment_type_rad> tester3;
+ typedef test_distance_of_geometries<point_type_rad, segment_type_rad> tester4;
+
+ const double d2r = bg::math::d2r<double>();
+
+ std::ostringstream s1;
+ s1 << 1*d2r;
+ std::ostringstream s2;
+ s2 << 2*d2r;
+ std::ostringstream s3;
+ s3 << 3*d2r;
+
+ tester1::apply("p-s-mix1",
+ "POINT(3 1)",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+ tester2::apply("p-s-mix2",
+ "POINT(" + s3.str() + " " + s1.str() + ")",
+ "SEGMENT(2 2,3 2)",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+ tester3::apply("p-s-mix3",
+ "POINT(3 1)",
+ "SEGMENT(" + s2.str() + " " + s2.str() + ","
+ + s3.str() + " " + s2.str() + ")",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+ tester4::apply("p-s-mix4",
+ "POINT(" + s3.str() + " " + s1.str() + ")",
+ "SEGMENT(" + s2.str() + " " + s2.str() + ","
+ + s3.str() + " " + s2.str() + ")",
+ pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp),
+ strategy_ps, true, true);
+}
+
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_point_linestring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/linestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, linestring_type> tester;
+
+ tester::apply("p-l-01",
+ "POINT(0 0)",
+ "LINESTRING(2 0,2 0)",
+ pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("p-l-02",
+ "POINT(0 0)",
+ "LINESTRING(2 0,3 0)",
+ pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("p-l-03",
+ "POINT(2.5 3)",
+ "LINESTRING(2 0,3 0)",
+ pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("p-l-04",
+ "POINT(2 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-l-05",
+ "POINT(3 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-l-06",
+ "POINT(2.5 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-l-07",
+ "POINT(7.5 10)",
+ "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)",
+ ps_distance("POINT(7.5 10)", "SEGMENT(7 0,8 0)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("p-l-08",
+ "POINT(7.5 10)",
+ "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)",
+ ps_distance("POINT(7.5 10)", "SEGMENT(7 1,20 2)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+void test_distance_point_linestring_strategies()
+{
+ typedef test_distance_of_geometries<point_type, linestring_type> tester;
+
+ tester::apply("p-l-s-01",
+ "POINT(2.5 3)",
+ "LINESTRING(2 1,3 1)",
+ 221147.24332788656,
+ vincenty_ps(),
+ true, false, false);
+
+ tester::apply("p-l-s-02",
+ "POINT(2.5 3)",
+ "LINESTRING(2 1,3 1)",
+ 221147.36682199029,
+ thomas_ps(),
+ true, false, false);
+
+ tester::apply("p-l-s-03",
+ "POINT(2.5 3)",
+ "LINESTRING(2 1,3 1)",
+ 221144.76527049288,
+ andoyer_ps(),
+ true, false, false);
+}
+
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_point_multilinestring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ point_type, multi_linestring_type
+ > tester;
+
+ tester::apply("p-ml-01",
+ "POINT(0 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-02",
+ "POINT(2.5 3)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ pp_distance("POINT(2.5 3)", "POINT(2.5 0)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-03",
+ "POINT(2 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-04",
+ "POINT(3 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-05",
+ "POINT(2.5 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-06",
+ "POINT(7.5 10)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))",
+ ps_distance("POINT(7.5 10)", "SEGMENT(6 0,20 1)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("p-ml-07",
+ "POINT(-8 10)",
+ "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))",
+ ps_distance("POINT(-8 10)", "SEGMENT(-6 0,-18 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_multipoint(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_point_type
+ > tester;
+
+ tester::apply("l-mp-01",
+ "LINESTRING(2 0,0 2,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("l-mp-02",
+ "LINESTRING(4 0,0 4,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ ps_distance("POINT(1 1)", "SEGMENT(0 4,4 0)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("l-mp-03",
+ "LINESTRING(1 1,2 2,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("l-mp-04",
+ "LINESTRING(3 3,4 4,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("l-mp-05",
+ "LINESTRING(0 0,10 0,10 10,0 10,0 0)",
+ "MULTIPOINT(1 -1,80 80,5 0,150 90)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("l-mp-06",
+ "LINESTRING(90 0,0 1.00005)",
+ "MULTIPOINT((0 0),(0 0),(0 0),(0 0),(0 0),(0 0),(0 0 ),(0 0),\
+ (0 0),(0 0 ),(0 0),(0 0),(69.35235 155.0205),\
+ (75.72081 37.97683),(0 0),(0 0),(0 0))",
+ pp_distance("POINT(0 0)", "POINT(0 1.00005)", strategy_pp),
+ strategy_ps, true, false, false);
+}
+
+//===========================================================================
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_multipoint_multilinestring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_linestring_type
+ > tester;
+
+ tester::apply("mp-ml-01",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((2 0,0 2),(2 2,3 3))",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("mp-ml-02",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((3 0,0 3),(4 4,5 5))",
+ ps_distance("POINT(1 1)", "SEGMENT(3 0,0 3)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("mp-ml-03",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((4 4,5 5),(1 1,2 2))",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("mp-ml-04",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((4 4,3 3),(4 4,5 5))",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
+ strategy_ps, true, false, false);
+}
+
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_distance_multipoint_segment(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
+
+ tester::apply("mp-s-01",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(2 0,0 2)",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy_ps),
+ strategy_ps, true, false, false);
+ tester::apply("mp-s-02",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(0 -3,1 -10)",
+ pp_distance("POINT(0 0)", "POINT(0 -3)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("mp-s-03",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(1 1,2 2)",
+ 0,
+ strategy_ps, true, false, false);
+ tester::apply("mp-s-04",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(3 3,4 4)",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy_pp),
+ strategy_ps, true, false, false);
+ tester::apply("mp-s-05",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(0.5 -3,1 -10)",
+ pp_distance("POINT(1 0)", "POINT(0.5 -3)", strategy_pp),
+ strategy_ps, true, false, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+template <typename Strategy_pp, typename Strategy_ps>
+void test_all_pl_l(Strategy_pp pp_strategy, Strategy_ps ps_strategy,
+ bool WGS84 = true)
+{
+ test_distance_point_segment(pp_strategy, ps_strategy, WGS84);
+ test_distance_point_linestring(pp_strategy, ps_strategy);
+ test_distance_point_multilinestring(pp_strategy, ps_strategy);
+ test_distance_linestring_multipoint(pp_strategy, ps_strategy);
+ test_distance_multipoint_multilinestring(pp_strategy, ps_strategy);
+ test_distance_multipoint_segment(pp_strategy, ps_strategy);
+
+ test_more_empty_input_pointlike_linear<point_type>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_linear )
+{
+ test_all_pl_l(vincenty_pp(), vincenty_ps_bisection());
+ test_all_pl_l(vincenty_pp(), vincenty_ps());
+ test_all_pl_l(thomas_pp(), thomas_ps());
+ test_all_pl_l(andoyer_pp(), andoyer_ps());
+
+ // test with different spheroid
+ stype spheroid(6372000, 6370000);
+ test_all_pl_l(andoyer_pp(spheroid), andoyer_ps(spheroid), false);
+
+ test_distance_point_segment_no_thomas(vincenty_pp(), vincenty_ps());
+ //test_distance_point_segment_no_thomas(thomas_pp(), thomas_ps());
+ test_distance_point_segment_no_thomas(andoyer_pp(), andoyer_ps());
+
+ test_distance_point_segment_rad_mix(vincenty_pp(), vincenty_ps());
+ test_distance_point_segment_rad_mix(thomas_pp(), thomas_ps());
+ test_distance_point_segment_rad_mix(andoyer_pp(), andoyer_ps());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_ar_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_ar_ar.cpp
new file mode 100644
index 00000000..4e25d7ea
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_ar_ar.cpp
@@ -0,0 +1,943 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2017, 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_areal_areal
+#endif
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_ring_ring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::ring<Point> ring_type;
+
+ typedef test_distance_of_geometries<ring_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("rr1", ring, "POLYGON((16 0,13 0,15 1,16 0))",
+ ps_distance<Point>("POINT(13 1)",
+ "SEGMENT(13 0,15 1)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("rr2", ring, "POLYGON((16 0,14 1,15 1,16 0))",
+ pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("rr3", ring, ring,
+ 0, strategy_ps, true, false, false);
+
+}
+
+//============================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_ring_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::ring<Point> ring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+
+ typedef test_distance_of_geometries<ring_type, polygon_type> tester;
+
+ std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("rp1", ring, "POLYGON((16 0,13 0,15 1,16 0))",
+ ps_distance<Point>("POINT(13 1)",
+ "SEGMENT(13 0,15 1)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("rp2", ring, "POLYGON((16 0,14 1,15 1,16 0))",
+ pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("rp3", ring, "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))",
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_polygon_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+
+ typedef test_distance_of_geometries<polygon_type, polygon_type> tester;
+
+ std::string const poly = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("pp1", poly, "POLYGON((16 0,13 0,15 1,16 0))",
+ ps_distance<Point>("POINT(13 1)",
+ "SEGMENT(13 0,15 1)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("pp2", poly, "POLYGON((16 0,14 1,15 1,16 0))",
+ pp_distance<Point>("POINT(13 1)", "POINT(14 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("pp3", poly, "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))",
+ 0, strategy_ps, true, false, false);
+
+}
+
+//============================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_ring_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::ring<Point> ring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+
+ typedef test_distance_of_geometries<ring_type, multi_polygon_type> tester;
+
+ std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("rmp1", ring, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
+ strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("rmp2", ring, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("rmp3", ring, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("rmp4", ring, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_polygon_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+
+ typedef test_distance_of_geometries<polygon_type, multi_polygon_type> tester;
+
+ std::string const poly = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("pmp1", poly, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
+ strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("pmp2", poly, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("pmp3", poly, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("pmp4", poly, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+ // w/ interior ring
+ std::string const poly_interior = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0),\
+ (12 1,11 1,12 2,12 1))";
+
+ tester::apply("pmp1", poly_interior, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
+ strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("pmp2", poly_interior, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("pmp3", poly_interior, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("pmp4", poly_interior, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+}
+
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_polygon_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multi_polygon/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+
+ typedef test_distance_of_geometries<multi_polygon_type, multi_polygon_type>
+ tester;
+
+ std::string const mpoly = "MULTIPOLYGON(((11 0,10 1,11 2,12 3,13 1,11 0)),\
+ ((0 0,0 1,1 1,1 0,0 0)))";
+
+ tester::apply("mpmp1", mpoly, "MULTIPOLYGON(((16 0,13 0,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ ps_distance<Point>("POINT(12.5 2.5)", "SEGMENT(12 3,13 1)",
+ strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("mpmp2", mpoly, "MULTIPOLYGON(((16 0,13.1 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ pp_distance<Point>("POINT(13 1)", "POINT(13.1 1)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("mpmp3", mpoly, "MULTIPOLYGON(((16 0,13 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("mpmp4", mpoly, "MULTIPOLYGON(((16 0,12 1,15 1,16 0)),\
+ ((12.5 2.5,12.5 4,14 2.5,12.5 2.5)))",
+ 0, strategy_ps, true, false, false);
+
+}
+
+//============================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_sb
+>
+void test_distance_ring_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "ring/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+ typedef bg::model::ring<Point> ring_type;
+
+ typedef test_distance_of_geometries<ring_type, box_type> tester;
+
+ std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("rb1", ring, "BOX(10 10,20 20)",
+ sb_distance<Point>("SEGMENT(11 2,12 3)",
+ "BOX(10 10,20 20)", strategy_sb),
+ strategy_sb, true, false, false);
+
+ tester::apply("rb2", ring, "BOX(17 0,20 3)",
+ ps_distance<Point>("POINT(13 1)",
+ "SEGMENT(17 0,17 3)", strategy_ps),
+ strategy_sb, true, false, false);
+
+ tester::apply("rb3", ring, "BOX(17 0,20 1)",
+ pp_distance<Point>("POINT(17 1)", "POINT(13 1)", strategy_pp),
+ strategy_sb, true, false, false);
+
+ tester::apply("rb4", ring, "BOX(12 0,20 1)",
+ 0, strategy_sb, true, false, false);
+}
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_sb
+>
+void test_distance_polygon_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "polygon/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+ typedef bg::model::polygon<Point> polygon_type;
+
+ typedef test_distance_of_geometries<polygon_type, box_type> tester;
+
+ std::string const polygon = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))";
+
+ tester::apply("pb1", polygon, "BOX(10 10,20 20)",
+ sb_distance<Point>("SEGMENT(11 2,12 3)",
+ "BOX(10 10,20 20)", strategy_sb),
+ strategy_sb, true, false, false);
+
+ tester::apply("pb2", polygon, "BOX(17 0,20 3)",
+ ps_distance<Point>("POINT(13 1)",
+ "SEGMENT(17 0,17 3)", strategy_ps),
+ strategy_sb, true, false, false);
+
+ tester::apply("pb3", polygon, "BOX(17 0,20 1)",
+ pp_distance<Point>("POINT(17 1)", "POINT(13 1)", strategy_pp),
+ strategy_sb, true, false, false);
+
+ tester::apply("pb4", polygon, "BOX(12 0,20 1)",
+ 0, strategy_sb, true, false, false);
+
+ // w/ interior ring
+ std::string const poly_interior = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0),\
+ (12 1,11 1,12 2,12 1))";
+
+ tester::apply("pb5", poly_interior, "BOX(10 10,20 20)",
+ sb_distance<Point>("SEGMENT(11 2,12 3)",
+ "BOX(10 10,20 20)", strategy_sb),
+ strategy_sb, true, false, false);
+}
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_sb
+>
+void test_distance_multi_polygon_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multi_polygon/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+
+ typedef test_distance_of_geometries<multi_polygon_type, box_type> tester;
+
+ std::string const multi_polygon = "MULTIPOLYGON(((20 20,20 30,30 40,20 20)),\
+ ((10 10,0 20,15 30,20 15,15 10,10 10)))";
+
+ tester::apply("mpb1", multi_polygon, "BOX(0 0,5 5)",
+ sb_distance<Point>("SEGMENT(10 10,0 20)",
+ "BOX(0 0,5 5)", strategy_sb),
+ strategy_sb, true, false, false);
+
+ tester::apply("mpb2", multi_polygon, "BOX(27 0,30 16)",
+ ps_distance<Point>("POINT(20 15)",
+ "SEGMENT(27 0,27 16)", strategy_ps),
+ strategy_sb, true, false, false);
+
+ tester::apply("mpb3", multi_polygon, "BOX(27 0,30 15)",
+ pp_distance<Point>("POINT(20 15)",
+ "POINT(27 15)", strategy_pp),
+ strategy_sb, true, false, false);
+
+ tester::apply("mpb4", multi_polygon, "BOX(17 0,20 14)",
+ 0, strategy_sb, true, false, false);
+}
+
+
+//===========================================================================
+// Cases for relative location of box2 wrt to box1
+//
+// | |
+// 11 | 7 | 4
+// | |
+// --10---+---------+---3---
+// | |
+// 9 | 6 | 2
+// | |
+// -------+---------+-------
+// | |
+// 8 | 5 | 1
+// | |
+//
+// case 6 includes all possible intersections
+// The picture assumes northern hemisphere location
+// southern hemisphere picture is mirrored wrt the equator
+
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_bb
+>
+void test_distance_box_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_bb const& strategy_bb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "box/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+
+ typedef test_distance_of_geometries<box_type, box_type> tester;
+
+ std::string const box1 = "BOX(10 10,20 20)";
+
+ // case 1
+ tester::apply("bb1", box1, "BOX(30 0,40 5)",
+ pp_distance<Point>("POINT(20 10)", "POINT(30 5)", strategy_pp),
+ strategy_bb);
+
+ // case 2
+ tester::apply("bb2-a", box1, "BOX(30 12, 40 17)",
+ ps_distance<Point>("POINT(30 17)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb2-b", box1, "BOX(30 10, 40 17)",
+ ps_distance<Point>("POINT(30 17)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb2-c", box1, "BOX(30 8, 40 17)",
+ ps_distance<Point>("POINT(30 17)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_bb);
+
+
+ // case 3
+ tester::apply("bb3-a", box1, "BOX(30 15, 40 25)",
+ ps_distance<Point>("POINT(20 20)",
+ "SEGMENT(30 15,30 25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb3-b", box1, "BOX(30 20, 40 40)",
+ ps_distance<Point>("POINT(20 20)",
+ "SEGMENT(30 20,30 40)", strategy_ps),
+ strategy_bb);
+
+ // case 4
+ tester::apply("bb4", box1, "BOX(30 25, 40 40)",
+ pp_distance<Point>("POINT(20 20)",
+ "POINT(30 25)", strategy_pp),
+ strategy_bb);
+
+ // case 5
+ tester::apply("bb5", box1, "BOX(12 2, 17 7)",
+ pp_distance<Point>("POINT(17 7)", "POINT(17 10)", strategy_pp),
+ strategy_bb);
+
+ // case 6, boxes intersect thus distance is 0
+ tester::apply("bb6-a", box1, "BOX(12 2, 17 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-b", box1, "BOX(12 2, 17 17)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-c", box1, "BOX(20 2, 30 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-d", box1, "BOX(20 11, 30 15)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-e", box1, "BOX(20 20, 30 30)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-f", box1, "BOX(15 20, 17 30)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-g", box1, "BOX(8 20, 10 25)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-h", box1, "BOX(8 15 , 10 17)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-i", box1, "BOX(8 8, 10 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-j", box1, "BOX(15 8, 17 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ // case 7
+ tester::apply("bb7", box1, "BOX(12 22, 17 27)",
+ pp_distance<Point>("POINT(17 20)",
+ "POINT(17 22)", strategy_pp),
+ strategy_bb);
+
+ // case 8
+ tester::apply("bb8", box1, "BOX(4 4, 8 8)",
+ pp_distance<Point>("POINT(8 8)", "POINT(10 10)", strategy_pp),
+ strategy_bb);
+
+ // case 9
+ tester::apply("bb9-a", box1, "BOX(4 14, 8 18)",
+ ps_distance<Point>("POINT(8 18)",
+ "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb9-b", box1, "BOX(4 10, 8 18)",
+ ps_distance<Point>("POINT(8 18)",
+ "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb9-c", box1, "BOX(4 8, 8 18)",
+ ps_distance<Point>("POINT(8 18)",
+ "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_bb);
+
+ // case 10
+ tester::apply("bb10a", box1, "BOX(4 18, 8 22)",
+ ps_distance<Point>("POINT(10 20)",
+ "SEGMENT(8 18, 8 22)", strategy_ps),
+ strategy_bb);
+
+ std::string const box1m = "BOX(10 -20,20 -10)";
+ tester::apply("bb10am", box1m, "BOX(4 -22, 8 -18)",
+ ps_distance<Point>("POINT(10 20)",
+ "SEGMENT(8 18, 8 22)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb10b", box1, "BOX(4 20, 8 22)",
+ ps_distance<Point>("POINT(10 20)",
+ "SEGMENT(8 20, 8 22)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb10bm", box1m, "BOX(4 -22, 8 -20)",
+ ps_distance<Point>("POINT(10 20)",
+ "SEGMENT(8 22, 8 20)", strategy_ps),
+ strategy_bb);
+
+ // case 11
+ tester::apply("bb11", box1, "BOX(4 22, 8 24)",
+ pp_distance<Point>("POINT(8 22)", "POINT(10 20)", strategy_pp),
+ strategy_bb);
+
+ // far away boxes
+ tester::apply("bb-far", "BOX(150 15, 170 25)", box1,
+ ps_distance<Point>("POINT(20 20)",
+ "SEGMENT(150 15, 150 25)", strategy_ps),
+ strategy_bb);
+
+ // crosses antimeridian
+ tester::apply("bb-anti1", "BOX(170 15, -160 25)", box1,
+ ps_distance<Point>("POINT(20 20)",
+ "SEGMENT(170 15, 170 25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-anti2", "BOX(170 15, -160 25)", "BOX(160 10, -170 20)",
+ pp_distance<Point>("POINT(20 20)",
+ "POINT(20 20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-anti3", "BOX(170 15, -160 25)", "BOX(160 10, 170 20)",
+ pp_distance<Point>("POINT(20 20)",
+ "POINT(20 20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-anti4", "BOX(170 10, -160 20)", "BOX(160 30, -170 40)",
+ pp_distance<Point>("POINT(180 20)",
+ "POINT(180 30)", strategy_pp),
+ strategy_bb);
+
+ // South hemisphere
+
+ tester::apply("bb-south1", "BOX(10 -20, 20 -10)", "BOX(30 -15, 40 -12)",
+ ps_distance<Point>("POINT(30 -15)",
+ "SEGMENT(20 -10, 20 -20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-south2", "BOX(10 -20, 20 -10)", "BOX(30 -30, 40 -25)",
+ pp_distance<Point>("POINT(30 -25)",
+ "POINT(20 -20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-south3", "BOX(10 -20, 20 -10)", "BOX(30 -25, 40 -15)",
+ ps_distance<Point>("POINT(20 -20)",
+ "SEGMENT(30 -15, 30 -25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -30, 30 -25)",
+ pp_distance<Point>("POINT(10 -25)",
+ "POINT(10 -20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -7, 30 -5)",
+ pp_distance<Point>("POINT(10 -7)",
+ "POINT(10 -10)", strategy_pp),
+ strategy_bb);
+
+
+ // Crosses equator
+
+ tester::apply("bb-eq1", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 25)",
+ ps_distance<Point>("POINT(20 25)",
+ "SEGMENT(30 -15, 30 30)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-eq1b", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 10)",
+ ps_distance<Point>("POINT(30 -15)",
+ "SEGMENT(20 10, 20 -20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-eq1bm", "BOX(30 -30, 40 15)", "BOX(10 -10, 20 20)",
+ ps_distance<Point>("POINT(30 15)",
+ "SEGMENT(20 -10, 20 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-eq2", "BOX(30 -15, 40 20)", "BOX(10 -20, 20 25)",
+ ps_distance<Point>("POINT(30 20)",
+ "SEGMENT(20 -20, 20 25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-eq3", "BOX(30 5, 40 20)", "BOX(10 -20, 20 25)",
+ ps_distance<Point>("POINT(30 20)",
+ "SEGMENT(20 -20, 20 25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb-eq4", "BOX(5 -30, 40 -25)", "BOX(10 -20, 20 25)",
+ pp_distance<Point>("POINT(10 -25)",
+ "POINT(10 -20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-eq5", "BOX(30 5, 40 20)", "BOX(10 -20, 50 25)",
+ pp_distance<Point>("POINT(30 20)",
+ "POINT(30 20)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-eq6", "BOX(30 5, 40 20)", "BOX(10 -20, 35 25)",
+ pp_distance<Point>("POINT(30 20)",
+ "POINT(30 20)", strategy_pp),
+ strategy_bb);
+
+ // One box in the north and one in the south hemisphere
+
+ tester::apply("bb-ns1", "BOX(30 15, 40 20)", "BOX(10 -20, 20 -15)",
+ pp_distance<Point>("POINT(30 15)",
+ "POINT(20 -15)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb-ns2", "BOX(30 15, 40 20)", "BOX(25 -20, 50 -15)",
+ pp_distance<Point>("POINT(30 15)",
+ "POINT(30 -15)", strategy_pp),
+ strategy_bb);
+
+ //negative coordinates
+
+ std::string const box1neg = "BOX(-20 10,-10 20)";
+
+ // case 1
+ tester::apply("bb1", box1neg, "BOX(-40 0,-30 5)",
+ pp_distance<Point>("POINT(-20 10)",
+ "POINT(-30 5)", strategy_pp),
+ strategy_bb);
+
+ // case 2
+ tester::apply("bb2-a", box1neg, "BOX(-40 12, -30 17)",
+ ps_distance<Point>("POINT(-30 17)",
+ "SEGMENT(-20 10,-20 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb2-b", box1neg, "BOX(-40 10, -30 17)",
+ ps_distance<Point>("POINT(-30 17)",
+ "SEGMENT(-20 10,-20 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb2-c", box1neg, "BOX(-40 8, -30 17)",
+ ps_distance<Point>("POINT(-30 17)",
+ "SEGMENT(-20 10,-20 20)", strategy_ps),
+ strategy_bb);
+
+
+ // case 3
+ tester::apply("bb3-a", box1neg, "BOX(-40 15, -30 25)",
+ ps_distance<Point>("POINT(-20 20)",
+ "SEGMENT(-30 15,-30 25)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb3-b", box1neg, "BOX(-40 20, -30 40)",
+ ps_distance<Point>("POINT(-20 20)",
+ "SEGMENT(-30 20,-30 40)", strategy_ps),
+ strategy_bb);
+
+ // case 4
+ tester::apply("bb4", box1neg, "BOX(-40 25, -30 40)",
+ pp_distance<Point>("POINT(-20 20)",
+ "POINT(-30 25)", strategy_pp),
+ strategy_bb);
+
+ // case 5
+ tester::apply("bb5", box1neg, "BOX(-17 2,-12 7)",
+ pp_distance<Point>("POINT(-17 7)",
+ "POINT(-17 10)", strategy_pp),
+ strategy_bb);
+
+ // case 6, boxes intersect thus distance is 0
+ tester::apply("bb6-a", box1neg, "BOX(-17 2, -12 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-b", box1neg, "BOX(-17 2, -12 17)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-c", box1neg, "BOX(-30 2, -20 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-d", box1neg, "BOX(-30 11, -20 15)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-e", box1neg, "BOX(-30 20, -20 30)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-f", box1neg, "BOX(-17 20, -15 30)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-g", box1neg, "BOX(-10 20, -8 25)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-h", box1neg, "BOX(-10 15 , -8 17)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-i", box1neg, "BOX(-10 8, -8 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ tester::apply("bb6-j", box1neg, "BOX(-17 8, -15 10)",
+ pp_distance<Point>("POINT(0 0)", "POINT(0 0)", strategy_pp),
+ strategy_bb);
+
+ // case 7
+ tester::apply("bb7", box1neg, "BOX(-17 22, -12 27)",
+ pp_distance<Point>("POINT(-17 20)",
+ "POINT(-17 22)", strategy_pp),
+ strategy_bb);
+
+ // case 8
+ tester::apply("bb8", box1neg, "BOX(-8 4, -4 8)",
+ pp_distance<Point>("POINT(-8 8)",
+ "POINT(-10 10)", strategy_pp),
+ strategy_bb);
+
+ // case 9
+ tester::apply("bb9-a", box1neg, "BOX(-8 14, -4 18)",
+ ps_distance<Point>("POINT(-8 18)",
+ "SEGMENT(-10 10, -10 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb9-b", box1neg, "BOX(-8 10, -4 18)",
+ ps_distance<Point>("POINT(-8 18)",
+ "SEGMENT(-10 10, -10 20)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb9-c", box1neg, "BOX(-8 8, -4 18)",
+ ps_distance<Point>("POINT(-8 18)",
+ "SEGMENT(-10 10, -10 20)", strategy_ps),
+ strategy_bb);
+
+ // case 10
+ tester::apply("bb10", box1neg, "BOX(-8 18, -4 22)",
+ ps_distance<Point>("POINT(-10 20)",
+ "SEGMENT(-8 18, -8 22)", strategy_ps),
+ strategy_bb);
+
+ tester::apply("bb10", box1neg, "BOX(-8 20, -4 22)",
+ ps_distance<Point>("POINT(-10 20)",
+ "SEGMENT(-8 20, -8 22)", strategy_ps),
+ strategy_bb);
+
+ // case 11
+ tester::apply("bb11", box1neg, "BOX(-8 22, -4 24)",
+ pp_distance<Point>("POINT(-8 22)",
+ "POINT(-10 20)", strategy_pp),
+ strategy_bb);
+
+
+ //Degenerate cases
+
+ //1st box degenerates to a meridian segment
+ std::string const box1deg = "BOX(0 10,0 20)";
+
+ //2nd box generic
+ tester::apply("pbd1", box1deg, "BOX(1 15, 2 25)",
+ ps_distance<Point>("POINT(0 20)",
+ "SEGMENT(1 15, 1 25)", strategy_ps),
+ strategy_bb);
+
+ //2nd box degenerates to a meridian segment
+ tester::apply("pbd2", box1deg, "BOX(1 15, 1 25)",
+ ps_distance<Point>("POINT(0 20)",
+ "SEGMENT(1 15, 1 25)", strategy_ps),
+ strategy_bb);
+
+ //2nd box degenerates to a horizontal line
+ //test fails for thomas strategy; test only for andoyer
+ tester::apply("pbd3", box1deg, "BOX(1 15, 2 15)",
+ pp_distance<Point>("POINT(1 15)",
+ "POINT(0 15)", andoyer_pp()),
+ andoyer_bb());
+
+ //2nd box degenerates to a point
+ tester::apply("pbd4", box1deg, "BOX(1 15, 1 15)",
+ ps_distance<Point>("POINT(1 15)",
+ "SEGMENT(0 10, 0 20)", strategy_ps),
+ strategy_bb);
+
+ //---
+ //1st box degenerates to a horizontal line; that is not a geodesic segment
+ std::string const box2deg = "BOX(10 10,20 10)";
+
+ //2nd box generic
+ tester::apply("pbd5", box2deg, "BOX(15 15, 25 20)",
+ pp_distance<Point>("POINT(15 15)",
+ "POINT(15 10)", strategy_pp),
+ strategy_bb);
+
+ //2nd box degenerates to a horizontal line
+ tester::apply("pbd6", box2deg, "BOX(15 15, 25 15)",
+ pp_distance<Point>("POINT(15 15)",
+ "POINT(15 10)", strategy_pp),
+ strategy_bb);
+
+ //2nd box degenerates to a point
+ tester::apply("pbd7", box2deg, "BOX(15 15, 15 15)",
+ pp_distance<Point>("POINT(15 15)",
+ "POINT(15 10)", strategy_pp),
+ strategy_bb);
+
+ //---
+ //1st box degenerates to a point
+ std::string const box3deg = "BOX(0 6,0 6)";
+
+ //2nd box generic
+ tester::apply("pbd8", box3deg, "BOX(15 15, 25 20)",
+ ps_distance<Point>("POINT(0 6)",
+ "SEGMENT(15 15, 15 20)", strategy_ps),
+ strategy_bb);
+
+ //2nd box degenerates to a point
+ tester::apply("pbd9", box3deg, "BOX(15 15, 15 15)",
+ pp_distance<Point>("POINT(0 6)",
+ "POINT(15 15)", strategy_pp),
+ strategy_bb);
+}
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_bb,
+ typename Strategy_sb
+>
+void test_all_ar_ar(Strategy_pp pp_strategy,
+ Strategy_ps ps_strategy,
+ Strategy_bb bb_strategy,
+ Strategy_sb sb_strategy)
+{
+ test_distance_ring_ring<Point>(pp_strategy, ps_strategy);
+
+ test_distance_ring_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_polygon_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_ring_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_polygon_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_polygon_multi_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_polygon_box<Point>(pp_strategy, ps_strategy, sb_strategy);
+ test_distance_multi_polygon_box<Point>(pp_strategy, ps_strategy, sb_strategy);
+ test_distance_ring_box<Point>(pp_strategy, ps_strategy, sb_strategy);
+ test_distance_box_box<Point>(pp_strategy, ps_strategy, bb_strategy);
+
+ test_more_empty_input_areal_areal<Point>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_areal_areal )
+{
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::spherical_equatorial<bg::degree>
+ > sph_point;
+
+ test_all_ar_ar<sph_point>(spherical_pp(), spherical_ps(), spherical_bb(), spherical_sb());
+
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::geographic<bg::degree>
+ > geo_point;
+
+ test_all_ar_ar<geo_point>(vincenty_pp(), vincenty_ps(), vincenty_bb(), vincenty_sb());
+ test_all_ar_ar<geo_point>(thomas_pp(), thomas_ps(), thomas_bb(), thomas_sb());
+ test_all_ar_ar<geo_point>(andoyer_pp(), andoyer_ps(), andoyer_bb(), andoyer_sb());
+
+ // test with different spheroid
+ stype spheroid(6372000, 6370000);
+ test_all_ar_ar<geo_point>(andoyer_pp(spheroid), andoyer_ps(spheroid),
+ andoyer_bb(spheroid), andoyer_sb(spheroid));
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_ar.cpp
new file mode 100644
index 00000000..ae332a0d
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_ar.cpp
@@ -0,0 +1,651 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2017, 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_linear_areal
+#endif
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_segment_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<segment_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20,15 30,20 15,15 10,10 10))";
+
+ tester::apply("s-p-1", "SEGMENT(0 0, 0 10)", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("s-p-2", "SEGMENT(9 0, 10 9)", polygon,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("s-p-3", "SEGMENT(9 0, 10 10)", polygon,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("s-p-4", "SEGMENT(9 0, 10 11)", polygon,
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<linestring_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("l-p-1", "LINESTRING(0 0,0 10)", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("l-p-2", "LINESTRING(9 0,10 9,11 8,15 8,20 9)", polygon,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("l-p-3", "LINESTRING(9 0,10 1,10 10,11 9)", polygon,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("l-p-4", "LINESTRING(9 0,10 11,10 9,11 9)", polygon,
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_linestring_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<multi_linestring_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("ml-p-1", "MULTILINESTRING((0 0,0 10)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", polygon,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("ml-p-2", "MULTILINESTRING((9 0,10 9,11 8,15 8,20 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", polygon,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("ml-p-3", "MULTILINESTRING((9 0,10 1,10 10,11 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", polygon,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("ml-p-4", "MULTILINESTRING((9 0,10 11,10 9,11 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", polygon,
+ 0, strategy_ps, true, false, false);
+}
+
+//=====================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_segment_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<segment_type, multi_polygon_type> tester;
+
+ std::string const mp = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("s-mp-1", "SEGMENT(0 0, 0 10)", mp,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("s-mp-2", "SEGMENT(9 0, 10 9)", mp,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("s-mp-3", "SEGMENT(9 0, 10 10)", mp,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("s-mp-4", "SEGMENT(9 0, 10 11)", mp,
+ 0, strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_linestring_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<linestring_type, multi_polygon_type> tester;
+
+ std::string const mp = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("l-mp-1", "LINESTRING(0 0, 0 10)", mp,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("l-mp-2", "LINESTRING(9 0,10 9,11 8,15 8,20 9)", mp,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("l-mp-3", "LINESTRING(9 0,10 1,10 10,11 9)", mp,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("l-mp-4", "LINESTRING(9 0,10 11,10 9,11 9)", mp,
+ 0, strategy_ps, true, false, false);
+
+}
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps>
+void test_distance_multi_linestring_multi_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/multi_polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multi_polygon_type;
+ typedef test_distance_of_geometries<multi_linestring_type, multi_polygon_type> tester;
+
+ std::string const mp = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("ml-mp-1", "MULTILINESTRING((0 0, 0 10)(0 0, 10 0))", mp,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+
+ tester::apply("ml-mp-2", "MULTILINESTRING((9 0,10 9,11 8,15 8,20 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", mp,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 9)", strategy_pp),
+ strategy_ps, true, false, false);
+
+ tester::apply("ml-mp-3", "MULTILINESTRING((9 0,10 1,10 10,11 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", mp,
+ 0, strategy_ps, true, false, false);
+
+ tester::apply("ml-mp-4", "MULTILINESTRING((9 0,10 11,10 9,11 9)\
+ (0 0,1 0,2 0,3 0,4 0,10 0,15 0,20 0))", mp,
+ 0, strategy_ps, true, false, false);
+}
+
+//=====================================================================
+
+template <typename Point, typename Strategy_ps>
+void test_distance_segment_ring(Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<segment_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("s-r-1", "SEGMENT(0 0, 0 10)", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_ps>
+void test_distance_linestring_ring(Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<linestring_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("l-r-1", "LINESTRING(0 0, 0 10)", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+template <typename Point, typename Strategy_ps>
+void test_distance_multi_linestring_ring(Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<multi_linestring_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("ml-r-1", "MULTILINESTRING((0 0, 0 10)(0 0, 10 0))", ring,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, false, false);
+}
+
+//======================================================================
+
+template <typename Point, typename Strategy_pp, typename Strategy_ps, typename Strategy_sb>
+void test_distance_segment_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/box distance tests" << std::endl;
+#endif
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<segment_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sb1-1a", "SEGMENT(0 0, 0 20)", box_north,
+ pp_distance<Point>("POINT(0 20)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+ //segment with slope
+ tester::apply("sb1-1b", "SEGMENT(10 5, 20 6)", box_north,
+ pp_distance<Point>("POINT(20 6)", "POINT(20 10)", strategy_pp),
+ strategy_sb);
+ tester::apply("sb1-2", "SEGMENT(0 0, 0 10)", box_north,
+ ps_distance<Point>("POINT(0 10)", "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-3", "SEGMENT(0 0, 0 15)", box_north,
+ ps_distance<Point>("POINT(0 15)", "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-4", "SEGMENT(0 0, 0 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 0,0 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb1-5", "SEGMENT(0 10, 0 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 0,0 25)", strategy_ps),
+ strategy_sb);
+
+ tester::apply("sb2-2", "SEGMENT(0 5, 15 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,15 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("sb2-3a", "SEGMENT(0 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,20 5)", strategy_ps),
+ strategy_sb);
+
+ // Test segments below box
+ tester::apply("test_b1", "SEGMENT(0 5, 9 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 9 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b2", "SEGMENT(0 5, 10 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 10 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b3", "SEGMENT(0 5, 11 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 11 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b4", "SEGMENT(0 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5,20 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b5", "SEGMENT(0 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(11 10)", "SEGMENT(0 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b6", "SEGMENT(10 5, 20 5)", box_north,
+ ps_distance<Point>("POINT(15 10)", "SEGMENT(10 5,20 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b7", "SEGMENT(10 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(16 10)", "SEGMENT(10 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b8", "SEGMENT(12 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(17 10)", "SEGMENT(12 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b9", "SEGMENT(18 5, 22 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(18 5,22 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b10", "SEGMENT(18 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(18 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b11", "SEGMENT(20 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(20 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b12", "SEGMENT(22 5, 24 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(22 5,24 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_b13", "SEGMENT(0 5, 125 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(0 5, 125 5)", strategy_ps),
+ strategy_sb);
+
+ // Test segments above box
+ tester::apply("test_a1", "SEGMENT(0 25, 9 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 25, 9 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a2", "SEGMENT(0 25, 10 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(0 25, 10 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a3", "SEGMENT(0 25, 11 25)", box_north,
+ ps_distance<Point>("POINT(11 20)", "SEGMENT(0 25, 11 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a4", "SEGMENT(0 25, 20 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(0 25, 20 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a5", "SEGMENT(0 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(0 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a6", "SEGMENT(10 25, 20 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(10 25, 20 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a7", "SEGMENT(10 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(10 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a8", "SEGMENT(12 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(12 20)", "SEGMENT(12 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a9", "SEGMENT(18 25, 22 25)", box_north,
+ ps_distance<Point>("POINT(18 20)", "SEGMENT(18 25, 22 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a10", "SEGMENT(18 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(18 20)", "SEGMENT(18 25, 24 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a11", "SEGMENT(20 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(20 25, 24 25)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_a12", "SEGMENT(22 25, 24 25)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(22 25, 24 25)", strategy_ps),
+ strategy_sb);
+
+ // Segments left-right of box
+ tester::apply("test_l1", "SEGMENT(0 5, 9 5)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(0 5, 9 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l2", "SEGMENT(0 10, 9 10)", box_north,
+ ps_distance<Point>("POINT(9 10)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l3", "SEGMENT(0 10, 9 15)", box_north,
+ ps_distance<Point>("POINT(9 15)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l4", "SEGMENT(0 10, 0 15)", box_north,
+ ps_distance<Point>("POINT(0 15)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l5", "SEGMENT(1 10, 0 15)", box_north,
+ ps_distance<Point>("POINT(1 10)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_l6", "SEGMENT(0 20, 9 21)", box_north,
+ ps_distance<Point>("POINT(9 21)", "SEGMENT(10 10, 10 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r1", "SEGMENT(21 5, 29 5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(21 5, 29 5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r2", "SEGMENT(21 10, 29 10)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r3", "SEGMENT(21 10, 29 15)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r4", "SEGMENT(21 10, 21 15)", box_north,
+ ps_distance<Point>("POINT(21 15)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r5", "SEGMENT(21 10, 22 15)", box_north,
+ ps_distance<Point>("POINT(21 10)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_r6", "SEGMENT(29 20, 21 21)", box_north,
+ ps_distance<Point>("POINT(21 21)", "SEGMENT(20 10, 20 20)", strategy_ps),
+ strategy_sb);
+
+ //Segments on corners of box
+ //left-top corner
+ //generic
+ tester::apply("test_c1", "SEGMENT(9 19.5, 11 21)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(9 19.5, 11 21)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c2", "SEGMENT(9 19, 11 21)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(9 19, 11 21)", strategy_ps),
+ strategy_sb);
+ //left-bottom corner
+ //generic
+ tester::apply("test_c3", "SEGMENT(8.5 11, 11 9)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(8.5 11, 11 9)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c4", "SEGMENT(9 11, 11 9)", box_north,
+ 0,
+ strategy_sb);
+ //right-top corner
+ //generic
+ tester::apply("test_c5", "SEGMENT(19 21, 21 19.5)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(19 21, 21 19.5)", strategy_ps),
+ strategy_sb);
+ //degenerate
+ tester::apply("test_c6", "SEGMENT(19 21, 21 19)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(19 21, 21 19)", strategy_ps),
+ strategy_sb);
+ //right-bottom corner
+ //generic
+ tester::apply("test_c7", "SEGMENT(19 9, 21 10.5)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(19 9, 21 10.5)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_c7", "SEGMENT(19 9, 21 11)", box_north,
+ 0,
+ strategy_sb);
+
+ //Segment and box on different hemispheres
+ std::string const box_south = "BOX(10 -20,20 -10)";
+
+ tester::apply("test_ns1", "SEGMENT(10 20, 15 30)", box_south,
+ ps_distance<Point>("POINT(10 -10)", "SEGMENT(10 20, 15 30)", strategy_ps),
+ strategy_sb);
+ tester::apply("test_ns2", "SEGMENT(0 10, 12 10)", box_south,
+ pp_distance<Point>("POINT(12 10)", "POINT(12 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns3", "SEGMENT(10 10, 20 10)", box_south,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns4", "SEGMENT(0 -10, 12 -10)", box_north,
+ pp_distance<Point>("POINT(12 10)", "POINT(12 -10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_ns5", "SEGMENT(10 -10, 20 -10)", box_north,
+ pp_distance<Point>("POINT(10 -10)", "POINT(10 10)", strategy_pp),
+ strategy_sb);
+
+ //Box crossing equator
+ std::string const box_crossing_eq = "BOX(10 -10,20 10)";
+
+ tester::apply("test_cr1", "SEGMENT(10 20, 15 30)", box_crossing_eq,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr2", "SEGMENT(10 -20, 15 -30)", box_crossing_eq,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 20)", strategy_pp),
+ strategy_sb);
+
+ //Box crossing prime meridian
+
+ std::string const box_crossing_mer = "BOX(-10 10,15 20)";
+
+ tester::apply("test_cr3", "SEGMENT(-5 25, 10 30)", box_crossing_mer,
+ pp_distance<Point>("POINT(-5 25)", "POINT(-5 20)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr4", "SEGMENT(-5 5, 10 7)", box_crossing_mer,
+ pp_distance<Point>("POINT(10 7)", "POINT(10 10)", strategy_pp),
+ strategy_sb);
+ tester::apply("test_cr5", "SEGMENT(-5 5, 10 5)", box_crossing_mer,
+ ps_distance<Point>("POINT(2.5 10)", "SEGMENT(-5 5, 10 5)", strategy_ps),
+ strategy_sb);
+
+
+ //Geometries in south hemisphere
+ tester::apply("test_south1", "SEGMENT(10 -30, 15 -30)", box_south,
+ ps_distance<Point>("POINT(10 -20)", "SEGMENT(10 -30, 15 -30)", strategy_ps),
+ strategy_sb);
+
+ //Segments in boxes corner
+ tester::apply("corner1", "SEGMENT(17 21, 25 20)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(17 21, 25 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner2", "SEGMENT(17 21, 0 20)", box_north,
+ ps_distance<Point>("POINT(10 20)", "SEGMENT(17 21, 0 20)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner3", "SEGMENT(17 5, 0 10)", box_north,
+ ps_distance<Point>("POINT(10 10)", "SEGMENT(17 5, 0 10)", strategy_ps),
+ strategy_sb);
+ tester::apply("corner4", "SEGMENT(17 5, 25 9)", box_north,
+ ps_distance<Point>("POINT(20 10)", "SEGMENT(17 5, 25 9)", strategy_ps),
+ strategy_sb);
+}
+
+template <typename Point, typename Strategy_ps, typename Strategy_sb>
+void test_distance_linestring_box(Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/box distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<linestring_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sl1", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 0 10)", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(15 21, 25 19.9)", strategy_ps),
+ strategy_sb, true, false, false);
+
+ tester::apply("sl2", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 15 15)", box_north,
+ 0, strategy_sb, true, false, false);
+
+ tester::apply("sl3", "LINESTRING(0 20, 15 21, 25 19.9, 21 5, 15 5, 2 20)", box_north,
+ 0, strategy_sb, true, false, false);
+}
+
+template <typename Point, typename Strategy_ps, typename Strategy_sb>
+void test_distance_multi_linestring_box(Strategy_ps const& strategy_ps,
+ Strategy_sb const& strategy_sb)
+{
+
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multi_linestring/box distance tests" << std::endl;
+#endif
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<multi_linestring_type, box_type> tester;
+
+ std::string const box_north = "BOX(10 10,20 20)";
+
+ tester::apply("sl1", "MULTILINESTRING((0 20, 15 21, 25 19.9, 21 5, 15 5, 0 10)(25 20, 22 4, 0 0))", box_north,
+ ps_distance<Point>("POINT(20 20)", "SEGMENT(15 21, 25 19.9)", strategy_ps),
+ strategy_sb, true, false, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_sb
+>
+void test_all_l_ar(Strategy_pp pp_strategy,
+ Strategy_ps ps_strategy,
+ Strategy_sb sb_strategy)
+{
+ test_distance_segment_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_linestring_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_linestring_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_segment_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_linestring_multi_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multi_linestring_multi_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_segment_ring<Point>(ps_strategy);
+ test_distance_linestring_ring<Point>(ps_strategy);
+ test_distance_multi_linestring_ring<Point>(ps_strategy);
+
+ test_distance_segment_box<Point>(pp_strategy, ps_strategy, sb_strategy);
+ test_distance_linestring_box<Point>(ps_strategy, sb_strategy);
+ test_distance_multi_linestring_box<Point>(ps_strategy, sb_strategy);
+
+ test_more_empty_input_linear_areal<Point>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linear_areal )
+{
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::spherical_equatorial<bg::degree>
+ > sph_point;
+
+ test_all_l_ar<sph_point>(spherical_pp(), spherical_ps(), spherical_sb());
+
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::geographic<bg::degree>
+ > geo_point;
+
+ test_all_l_ar<geo_point>(vincenty_pp(), vincenty_ps(), vincenty_sb());
+ test_all_l_ar<geo_point>(thomas_pp(), thomas_ps(), thomas_sb());
+ test_all_l_ar<geo_point>(andoyer_pp(), andoyer_ps(), andoyer_sb());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_l.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_l.cpp
new file mode 100644
index 00000000..f287f526
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_l_l.cpp
@@ -0,0 +1,286 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_linear_linear
+#endif
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_segment_segment(Strategy const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/segment distance tests" << std::endl;
+#endif
+
+ typedef bg::model::segment<Point> segment_type;
+
+ typedef test_distance_of_geometries<segment_type, segment_type> tester;
+
+ tester::apply("s-s-01",
+ "SEGMENT(0 0,1 1)",
+ "SEGMENT(2 0,3 0)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-s-02",
+ "SEGMENT(2 1,3 1)",
+ "SEGMENT(2 0,3 0)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(2 1,3 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-s-03",
+ "SEGMENT(2.5 1,3.5 1)",
+ "SEGMENT(2 0,3 0)",
+ ps_distance<Point>("POINT(2.5 0)",
+ "SEGMENT(2.5 1,3.5 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-s-04",
+ "SEGMENT(2.5 1,3.5 1)",
+ "SEGMENT(2 2,3 2)",
+ ps_distance<Point>("POINT(3 2)",
+ "SEGMENT(2.5 1,3.5 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-s-05",
+ "SEGMENT(2.5 2.1,3.5 1)",
+ "SEGMENT(2 2,3 2)",
+ 0, strategy_ps, true, true, false);
+ tester::apply("s-s-06",
+ "SEGMENT(2.5 2.1,3.5 1)",
+ "SEGMENT(2 2,3.5 1)",
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_segment_linestring(Strategy const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/linestring distance tests" << std::endl;
+#endif
+
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::linestring<Point> linestring_type;
+
+ typedef test_distance_of_geometries<segment_type, linestring_type> tester;
+
+ tester::apply("s-l-01",
+ "SEGMENT(0 0,1 1)",
+ "LINESTRING(2 0,3 0)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-l-02",
+ "SEGMENT(0 0,1 1)",
+ "LINESTRING(2 0,3 0,2 2,0.5 0.7)",
+ ps_distance<Point>("POINT(1 1)",
+ "SEGMENT(0.5 0.7,2 2)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-l-03",
+ "SEGMENT(0 0,2 2)",
+ "LINESTRING(2 0,3 0,2 2,0.5 0.7)",
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_linestring_linestring(Strategy const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/linestring distance tests" << std::endl;
+#endif
+
+ typedef bg::model::linestring<Point> linestring_type;
+
+ typedef test_distance_of_geometries
+ <
+ linestring_type, linestring_type
+ > tester;
+
+ tester::apply("l-l-01",
+ "LINESTRING(0 0,1 1)",
+ "LINESTRING(2 0,3 0)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("l-l-02",
+ "LINESTRING(0 0,1 1,2 2)",
+ "LINESTRING(2 0,3 0,4 1)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(1 1,2 2)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("l-l-03",
+ "LINESTRING(0 0,1 1,2 2)",
+ "LINESTRING(2 0)",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(1 1,2 2)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("l-l-04",
+ "LINESTRING(0 0,1 1,2 2)",
+ "LINESTRING(3 3,1 1)",
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_segment_multilinestring(Strategy const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "segment/multilinestring distance tests" << std::endl;
+#endif
+
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+ typedef test_distance_of_geometries
+ <
+ segment_type, multi_linestring_type
+ > tester;
+
+ tester::apply("s-ml-01",
+ "SEGMENT(0 0,1 1)",
+ "MULTILINESTRING((2 0,3 0)(2 5, 5 5, 2 -1))",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-ml-02",
+ "SEGMENT(0 0,1 1)",
+ "MULTILINESTRING((2 0,3 0))",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-ml-03",
+ "SEGMENT(0 0,2 0)",
+ "MULTILINESTRING((2 0,3 0)(2 5, 5 5, 2 -1))",
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_linestring_multilinestring(Strategy const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multilinestring distance tests" << std::endl;
+#endif
+
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_linestring_type
+ > tester;
+
+ tester::apply("l-ml-01",
+ "LINESTRING(0 0,1 1,2 2,3 3,4 4,6 6)",
+ "MULTILINESTRING((2 0,3 0)(2 1, 5 5))",
+ ps_distance<Point>("POINT(5 5)",
+ "SEGMENT(4 4,6 6)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("l-ml-02",
+ "LINESTRING(0 0,1 1,2 2,3 3,4 4,6 6)",
+ "MULTILINESTRING((2 0,3 0)(2 5, 5 5))",
+ 0,
+ strategy_ps, true, true, false);
+
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_multilinestring_multilinestring(Strategy const& strategy_ps)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multilinestring/multilinestring distance tests" << std::endl;
+#endif
+
+ typedef bg::model::linestring<Point> linestring_type;
+ typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+ typedef test_distance_of_geometries
+ <
+ multi_linestring_type, multi_linestring_type
+ > tester;
+
+ tester::apply("s-ml-01",
+ "MULTILINESTRING((0 0,1 1)(-1 0, -1 -1))",
+ "MULTILINESTRING((2 0,3 0)(2 5, 5 5))",
+ ps_distance<Point>("POINT(2 0)",
+ "SEGMENT(0 0,1 1)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("s-ml-02",
+ "MULTILINESTRING((0 0,1 1)(-1 0, -1 -1)(5 0, 5 6))",
+ "MULTILINESTRING((2 0,3 0)(2 5, 5 5))",
+ 0,
+ strategy_ps, true, true, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_all_l_l(Strategy ps_strategy)
+{
+ test_distance_segment_segment<Point>(ps_strategy);
+ test_distance_segment_linestring<Point>(ps_strategy);
+ test_distance_linestring_linestring<Point>(ps_strategy);
+ test_distance_segment_multilinestring<Point>(ps_strategy);
+ test_distance_linestring_multilinestring<Point>(ps_strategy);
+ test_distance_multilinestring_multilinestring<Point>(ps_strategy);
+
+ test_more_empty_input_linear_linear<Point>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linear_linear )
+{
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::spherical_equatorial<bg::degree>
+ > sph_point;
+
+ test_all_l_l<sph_point>(spherical_ps());
+
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::geographic<bg::degree>
+ > geo_point;
+
+ test_all_l_l<geo_point>(vincenty_ps());
+ test_all_l_l<geo_point>(thomas_ps());
+ test_all_l_l<geo_point>(andoyer_ps());
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_ar.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_ar.cpp
new file mode 100644
index 00000000..3a9d5f27
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_ar.cpp
@@ -0,0 +1,687 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2017-2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#include <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_pointlike_areal
+#endif
+
+#include <boost/range.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/util/condition.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps
+>
+void test_distance_point_ring(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::ring<Point> ring_type;
+ typedef test_distance_of_geometries<Point, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("pr1", "POINT(0 10)", ring,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("pr2", "POINT(10 0)", ring,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 0)", strategy_pp),
+ strategy_ps, true, true, false);
+ tester::apply("pr3", "POINT(0 20)", ring,
+ 0, strategy_ps, true, true, false);
+ tester::apply("pr4", "POINT(10 10)", ring,
+ 0, strategy_ps, true, true, false);
+ tester::apply("pr4", "POINT(10 11)", ring,
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_ps
+>
+void test_distance_multipoint_ring(Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/ring distance tests" << std::endl;
+#endif
+ typedef bg::model::ring<Point> ring_type;
+ typedef bg::model::multi_point<Point> multi_point_type;
+ typedef test_distance_of_geometries<multi_point_type, ring_type> tester;
+
+ std::string const ring = "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("pr1", "MULTIPOINT(0 10,10 0,0 0)", ring,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+}
+
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps
+>
+void test_distance_point_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef test_distance_of_geometries<Point, polygon_type> tester;
+
+ std::string const polygon =
+ "POLYGON((10 10,0 20, 15 30, 20 15, 15 10, 10 10))";
+
+ tester::apply("pr1", "POINT(0 10)", polygon,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+ tester::apply("pr2", "POINT(10 0)", polygon,
+ pp_distance<Point>("POINT(10 10)", "POINT(10 0)", strategy_pp),
+ strategy_ps, true, true, false);
+ tester::apply("pr3", "POINT(0 20)", polygon,
+ 0, strategy_ps, true, true, false);
+ tester::apply("pr4", "POINT(10 10)", polygon,
+ 0, strategy_ps, true, true, false);
+ tester::apply("pr5", "POINT(10 10.1)", polygon,
+ 0, strategy_ps, false, false, false);
+}
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps
+>
+void test_distance_multipoint_polygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/polygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_point<Point> multi_point_type;
+ typedef test_distance_of_geometries<multi_point_type, polygon_type> tester;
+
+ std::string const polygon = "POLYGON((10 10,0 20,15 30,20 15,15 10,10 10))";
+
+ tester::apply("mpp1", "MULTIPOINT(0 10,10 0,0 0)", polygon,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+
+ tester::apply("mpp2", "MULTIPOINT(0 10,10 0,0 0,20.1 15)", polygon,
+ pp_distance<Point>("POINT(20 15)",
+ "POINT(20.1 15)", strategy_pp),
+ strategy_ps, true, true, false);
+
+ tester::apply("mpp3", "MULTIPOINT(0 10,10 0,0 0,20.1 15,10 10)", polygon,
+ 0, strategy_ps, true, true, false);
+
+ tester::apply("mpp4", "MULTIPOINT(0 10,10 0,0 0,20.1 15,10 11)", polygon,
+ 0, strategy_ps, true, true, false);
+}
+
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps
+>
+void test_distance_point_multipolygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multipolygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multipolygon_type;
+ typedef test_distance_of_geometries<Point, multipolygon_type> tester;
+
+ std::string const mpoly = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("pmp1", "POINT(0 10)", mpoly,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+
+
+ tester::apply("pmp2", "POINT(10 9.9)", mpoly,
+ pp_distance<Point>("POINT(10 9.9)",
+ "POINT(10 10)", strategy_pp),
+ strategy_ps, true, true, false);
+
+ tester::apply("pmp3", "POINT(10 11)", mpoly,
+ 0, strategy_ps, true, true, false);
+}
+
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps
+>
+void test_distance_multipoint_multipolygon(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multipolygon distance tests" << std::endl;
+#endif
+ typedef bg::model::polygon<Point> polygon_type;
+ typedef bg::model::multi_polygon<polygon_type> multipolygon_type;
+ typedef bg::model::multi_point<Point> multi_point_type;
+ typedef test_distance_of_geometries<multi_point_type, multipolygon_type> tester;
+
+ std::string const mpoly = "MULTIPOLYGON(((20 20, 20 30, 30 40, 20 20)),\
+ ((10 10,0 20, 15 30, 20 15, 15 10, 10 10)))";
+
+ tester::apply("pr1", "MULTIPOINT(0 10,10 0,0 0)", mpoly,
+ ps_distance<Point>("POINT(0 10)",
+ "SEGMENT(0 20, 10 10)", strategy_ps),
+ strategy_ps, true, true, false);
+
+ tester::apply("pmp2", "MULTIPOINT(0 10,10 0,0 0,10 9.9)", mpoly,
+ pp_distance<Point>("POINT(10 9.9)",
+ "POINT(10 10)", strategy_pp),
+ strategy_ps, true, true, false);
+
+ tester::apply("pmp3", "MULTIPOINT(0 10,10 0,0 0,10 9.9,10 11)", mpoly,
+ 0, strategy_ps, true, true, false);
+}
+
+
+//===========================================================================
+// Cases for relative location of a point wrt to a box
+//
+// | |
+// | 3 |
+// | |
+// +---------+
+// | |
+// 1 | 5 | 2
+// | |
+// +---------+
+// | |
+// | 4 |
+// | |
+//
+// and also the following cases
+//
+// | |
+// A B
+// | |
+// +----C----+
+// | |
+// D E
+// | |
+// +----F----+
+// | |
+// G H
+// | |
+//
+// and finally we have the corners
+//
+// | |
+// | |
+// | |
+// a---------b
+// | |
+// | |
+// | |
+// c---------d
+// | |
+// | |
+// | |
+//
+// for each relative position we also have to test the shifted point
+// (this is due to the fact that boxes have longitudes in the
+// range [-180, 540)
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_pb
+>
+void test_distance_point_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_pb const& strategy_pb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+ typedef test_distance_of_geometries<Point, box_type> tester;
+
+ std::string const box1 = "BOX(10 10,20 20)";
+
+ // case 1
+ tester::apply("pb1-1a", "POINT(5 25)", box1,
+ pp_distance<Point>("POINT(5 25)", "POINT(10 20)", strategy_pp),
+ strategy_pb);
+
+ // case 1
+ tester::apply("pb1-1b", "POINT(3 12)", box1,
+ ps_distance<Point>("POINT(3 12)",
+ "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_pb);
+
+ // case 1
+ tester::apply("pb1-1c", "POINT(3 17)", box1,
+ ps_distance<Point>("POINT(3 17)",
+ "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_pb);
+
+ // case 1
+ tester::apply("pb1-1d", "POINT(5 4)", box1,
+ pp_distance<Point>("POINT(5 4)", "POINT(10 10)", strategy_pp),
+ strategy_pb);
+
+ // case 1
+ tester::apply("pb1-1e", "POINT(-100 20)", box1,
+ pp_distance<Point>("POINT(-100 20)",
+ "POINT(10 20)", strategy_pp),
+ strategy_pb);
+
+ // case 1
+ tester::apply("pb1-1g", "POINT(-100 10)", box1,
+ ps_distance<Point>("POINT(-100 10)",
+ "SEGMENT(10 10,10 20)", strategy_ps),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2a", "POINT(31 25)", box1,
+ pp_distance<Point>("POINT(31 25)",
+ "POINT(20 20)", strategy_pp),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2b", "POINT(23 17)", box1,
+ ps_distance<Point>("POINT(23 17)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2c", "POINT(29 3)", box1,
+ pp_distance<Point>("POINT(29 3)",
+ "POINT(20 10)", strategy_pp),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2d", "POINT(131 65)", box1,
+ pp_distance<Point>("POINT(131 65)",
+ "POINT(20 20)", strategy_pp),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2e", "POINT(110 10)", box1,
+ ps_distance<Point>("POINT(110 10)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_pb);
+
+ // case 2
+ tester::apply("pb1-2f", "POINT(150 20)", box1,
+ pp_distance<Point>("POINT(150 20)",
+ "POINT(20 20)", strategy_pp),
+ strategy_pb);
+
+ // case 3
+ tester::apply("pb1-3a", "POINT(11 25)", box1,
+ pp_distance<Point>("POINT(11 25)",
+ "POINT(11 20)", strategy_pp),
+ strategy_pb);
+
+ // case 3
+ tester::apply("pb1-3b", "POINT(15 25)", box1,
+ pp_distance<Point>("POINT(15 25)",
+ "POINT(15 20)", strategy_pp),
+ strategy_pb);
+
+ // case 3
+ tester::apply("pb1-3c", "POINT(18 25)", box1,
+ pp_distance<Point>("POINT(18 25)",
+ "POINT(18 20)", strategy_pp),
+ strategy_pb);
+
+ // case 4
+ tester::apply("pb1-4a", "POINT(13 4)", box1,
+ pp_distance<Point>("POINT(13 4)",
+ "POINT(13 10)", strategy_pp),
+ strategy_pb);
+
+ // case 4
+ tester::apply("pb1-4b", "POINT(19 4)", box1,
+ pp_distance<Point>("POINT(19 4)",
+ "POINT(19 10)", strategy_pp),
+ strategy_pb);
+
+ // case 5
+ tester::apply("pb1-5", "POINT(15 14)", box1, 0, strategy_pb);
+
+ // case A
+ tester::apply("pb1-A", "POINT(10 28)", box1,
+ pp_distance<Point>("POINT(10 28)",
+ "POINT(10 20)", strategy_pp),
+ strategy_pb);
+
+ // case B
+ tester::apply("pb1-B", "POINT(20 28)", box1,
+ pp_distance<Point>("POINT(20 28)",
+ "POINT(20 20)", strategy_pp),
+ strategy_pb);
+
+
+ // case C
+ tester::apply("pb1-C", "POINT(14 20)", box1, 0, strategy_pb);
+
+ // case D
+ tester::apply("pb1-D", "POINT(10 17)", box1, 0, strategy_pb);
+
+ // case E
+ tester::apply("pb1-E", "POINT(20 11)", box1, 0, strategy_pb);
+
+ // case F
+ tester::apply("pb1-F", "POINT(19 10)", box1, 0, strategy_pb);
+
+ // case G
+ tester::apply("pb1-G", "POINT(10 -40)", box1,
+ pp_distance<Point>("POINT(10 -40)",
+ "POINT(10 10)", strategy_pp),
+ strategy_pb);
+
+ // case H
+ tester::apply("pb1-H", "POINT(20 -50)", box1,
+ pp_distance<Point>("POINT(20 -50)",
+ "POINT(20 10)", strategy_pp),
+ strategy_pb);
+
+ // case a
+ tester::apply("pb1-a", "POINT(10 20)", box1, 0, strategy_pb);
+ // case b
+ tester::apply("pb1-b", "POINT(20 20)", box1, 0, strategy_pb);
+ // case c
+ tester::apply("pb1-c", "POINT(10 10)", box1, 0, strategy_pb);
+ // case d
+ tester::apply("pb1-d", "POINT(20 10)", box1, 0, strategy_pb);
+
+
+ std::string const box2 = "BOX(170 -60,400 80)";
+
+ // case 1 - point is closer to western meridian
+ tester::apply("pb2-1a", "POINT(160 0)", box2,
+ ps_distance<Point>("POINT(160 0)",
+ "SEGMENT(170 -60,170 80)", strategy_ps),
+ strategy_pb);
+
+ // case 1 - point is closer to eastern meridian
+ tester::apply("pb2-1b", "POINT(50 0)", box2,
+ ps_distance<Point>("POINT(50 0)",
+ "SEGMENT(40 -60,40 80)", strategy_ps),
+ strategy_pb);
+
+ // case 3 - equivalent point POINT(390 85) is above the box
+ tester::apply("pb2-3", "POINT(30 85)", box2,
+ pp_distance<Point>("POINT(30 85)",
+ "POINT(30 80)", strategy_pp),
+ strategy_pb);
+
+ // case 4 - equivalent point POINT(390 -75) is below the box
+ tester::apply("pb2-4", "POINT(30 -75)", box2,
+ pp_distance<Point>("POINT(30 -75)",
+ "POINT(30 -60)", strategy_pp),
+ strategy_pb);
+
+ // case 5 - equivalent point POINT(390 0) is inside box
+ tester::apply("pb2-5", "POINT(30 0)", box2, 0, strategy_pb);
+
+
+ std::string const box3 = "BOX(-150 -50,-40 70)";
+
+ // case 1 - point is closer to western meridian
+ tester::apply("pb3-1a", "POINT(-170 10)", box3,
+ ps_distance<Point>("POINT(-170 10)",
+ "SEGMENT(-150 -50,-150 70)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is closer to eastern meridian
+ tester::apply("pb3-2a", "POINT(5 10)", box3,
+ ps_distance<Point>("POINT(5 10)",
+ "SEGMENT(-40 -50,-40 70)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is closer to western meridian
+ tester::apply("pb3-2a", "POINT(160 10)", box3,
+ ps_distance<Point>("POINT(160 10)",
+ "SEGMENT(-150 -50,-150 70)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is at equal distance from eastern and western meridian
+ tester::apply("pb3-2c1", "POINT(85 20)", box3,
+ ps_distance<Point>("POINT(85 20)",
+ "SEGMENT(-150 -50,-150 70)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is at equal distance from eastern and western meridian
+ tester::apply("pb3-2c2", "POINT(85 20)", box3,
+ ps_distance<Point>("POINT(85 20)",
+ "SEGMENT(-40 -50,-40 70)", strategy_ps),
+ strategy_pb);
+
+ // box that is symmetric wrt the prime meridian
+ std::string const box4 = "BOX(-75 -45,75 65)";
+
+ // case 1 - point is closer to western meridian
+ tester::apply("pb4-1a", "POINT(-100 10)", box4,
+ ps_distance<Point>("POINT(-100 10)",
+ "SEGMENT(-75 -45,-75 65)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is closer to eastern meridian
+ tester::apply("pb4-2a", "POINT(90 15)", box4,
+ ps_distance<Point>("POINT(90 15)",
+ "SEGMENT(75 -45,75 65)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is at equal distance from eastern and western meridian
+ tester::apply("pb4-2c1", "POINT(-180 20)", box4,
+ ps_distance<Point>("POINT(-180 20)",
+ "SEGMENT(-75 -45,-75 65)", strategy_ps),
+ strategy_pb);
+
+ // case 2 - point is at equal distance from eastern and western meridian
+ tester::apply("pb4-2c2", "POINT(-180 20)", box4,
+ ps_distance<Point>("POINT(-180 20)",
+ "SEGMENT(75 -45,75 65)", strategy_ps),
+ strategy_pb);
+
+
+ //box degenerates to a meridian segment
+ std::string const boxdeg1 = "BOX(0 10,0 20)";
+
+ tester::apply("pbd1", "POINT(1 10)", boxdeg1,
+ ps_distance<Point>("POINT(1 10)",
+ "SEGMENT(0 10, 0 20)", strategy_ps),
+ strategy_pb);
+ tester::apply("pbd2", "POINT(1 5)", boxdeg1,
+ ps_distance<Point>("POINT(1 5)",
+ "SEGMENT(0 10, 0 20)", strategy_ps),
+ strategy_pb);
+ tester::apply("pbd3", "POINT(1 15)", boxdeg1,
+ ps_distance<Point>("POINT(1 15)",
+ "SEGMENT(0 10, 0 20)", strategy_ps),
+ strategy_pb);
+ tester::apply("pbd4", "POINT(1 25)", boxdeg1,
+ ps_distance<Point>("POINT(1 25)",
+ "SEGMENT(0 10, 0 20)", strategy_ps),
+ strategy_pb);
+
+ //box degenerates to a horizontal line; that is not a geodesic segment
+ std::string const boxdeg2 = "BOX(10 10,20 10)";
+
+ tester::apply("pbd5", "POINT(15 15)", boxdeg2,
+ pp_distance<Point>("POINT(15 15)",
+ "POINT(15 10)", strategy_pp),
+ strategy_pb);
+ tester::apply("pbd6", "POINT(5 15)", boxdeg2,
+ pp_distance<Point>("POINT(5 15)",
+ "POINT(10 10)", strategy_pp),
+ strategy_pb);
+ tester::apply("pbd7", "POINT(25 15)", boxdeg2,
+ pp_distance<Point>("POINT(25 15)",
+ "POINT(20 10)", strategy_pp),
+ strategy_pb);
+
+ //box degenerates to a point
+ std::string const boxdeg3 = "BOX(0 10,0 10)";
+
+ tester::apply("pbd8", "POINT(1 11)", boxdeg3,
+ pp_distance<Point>("POINT(1 11)",
+ "POINT(0 10)", strategy_pp),
+ strategy_pb);
+}
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_pb
+>
+void test_distance_multipoint_box(Strategy_pp const& strategy_pp,
+ Strategy_ps const& strategy_ps,
+ Strategy_pb const& strategy_pb)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/box distance tests" << std::endl;
+#endif
+ typedef bg::model::box<Point> box_type;
+ typedef bg::model::multi_point<Point> multi_point_type;
+ typedef test_distance_of_geometries<multi_point_type, box_type> tester;
+
+ std::string const box1 = "BOX(10 10,20 20)";
+
+ tester::apply("mpb1", "MULTIPOINT(5 25,25 26)", box1,
+ pp_distance<Point>("POINT(5 25)", "POINT(10 20)", strategy_pp),
+ strategy_pb, true, false, false);
+
+ tester::apply("mpb2", "MULTIPOINT(110 10,110 9,110 0)", box1,
+ ps_distance<Point>("POINT(110 10)",
+ "SEGMENT(20 10,20 20)", strategy_ps),
+ strategy_pb, true, false, false);
+
+ tester::apply("mpb3", "MULTIPOINT(110 10,110 9,110 0,10 20)", box1,
+ 0, strategy_pb, true, false, false);
+
+ tester::apply("mpb3", "MULTIPOINT(110 10,110 9,110 0,15 15)", box1,
+ 0, strategy_pb, true, false, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+template
+<
+ typename Point,
+ typename Strategy_pp,
+ typename Strategy_ps,
+ typename Strategy_pb
+>
+void test_all_pl_ar(Strategy_pp pp_strategy,
+ Strategy_ps ps_strategy,
+ Strategy_pb pb_strategy)
+{
+ test_distance_point_ring<Point>(pp_strategy, ps_strategy);
+ test_distance_multipoint_ring<Point>(ps_strategy);
+
+ test_distance_point_polygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multipoint_polygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_point_multipolygon<Point>(pp_strategy, ps_strategy);
+ test_distance_multipoint_multipolygon<Point>(pp_strategy, ps_strategy);
+
+ test_distance_point_box<Point>(pp_strategy, ps_strategy, pb_strategy);
+ test_distance_multipoint_box<Point>(pp_strategy, ps_strategy, pb_strategy);
+
+ test_more_empty_input_pointlike_areal<Point>(ps_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_areal )
+{
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::spherical_equatorial<bg::degree>
+ > sph_point;
+
+ test_all_pl_ar<sph_point>(spherical_pp(), spherical_ps(), spherical_pb());
+
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::geographic<bg::degree>
+ > geo_point;
+
+ test_all_pl_ar<geo_point>(vincenty_pp(), vincenty_ps(), vincenty_pb());
+ test_all_pl_ar<geo_point>(thomas_pp(), thomas_ps(), thomas_pb());
+ test_all_pl_ar<geo_point>(andoyer_pp(), andoyer_ps(), andoyer_pb());
+
+ // test with different spheroid
+ stype spheroid(6372000, 6370000);
+ test_all_pl_ar<geo_point>(andoyer_pp(spheroid), andoyer_ps(spheroid), andoyer_pb(spheroid));
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_pl.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_pl.cpp
new file mode 100644
index 00000000..3027bf4d
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_geo_pl_pl.cpp
@@ -0,0 +1,122 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2017, 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_geographic_pointlike_pointlike
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_geo_common.hpp"
+#include "test_empty_geometry.hpp"
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_point_point(Strategy const& strategy)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/point distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<Point, Point> tester;
+
+ tester::apply("p-p-01",
+ "POINT(1 1)",
+ "POINT(0 0)",
+ strategy.apply(Point(1,1), Point(0,0)),
+ strategy, true, false, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_multipoint_point(Strategy const& strategy)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/point distance tests" << std::endl;
+#endif
+ typedef bg::model::multi_point<Point> multi_point_type;
+
+ typedef test_distance_of_geometries<multi_point_type, Point> tester;
+
+ tester::apply("mp-p-01",
+ "MULTIPOINT(1 1,1 2,2 3)",
+ "POINT(0 0)",
+ pp_distance<Point>("POINT(0 0)","POINT(1 1)",strategy),
+ strategy, true, false, false);
+
+ tester::apply("mp-p-01",
+ "MULTIPOINT(0 0,0 2,2 0,2 2)",
+ "POINT(1.1 1.1)",
+ pp_distance<Point>("POINT(1.1 1.1)","POINT(2 2)",strategy),
+ strategy, true, false, false);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_distance_multipoint_multipoint(Strategy const& strategy)
+{
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multipoint distance tests" << std::endl;
+#endif
+ typedef bg::model::multi_point<Point> multi_point_type;
+
+ typedef test_distance_of_geometries<multi_point_type, multi_point_type> tester;
+
+ tester::apply("mp-mp-01",
+ "MULTIPOINT(1 1,1 2,2 3)",
+ "MULTIPOINT(0 0, 0 -1)",
+ pp_distance<Point>("POINT(0 0)","POINT(1 1)",strategy),
+ strategy, true, false, false);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+template <typename Point, typename Strategy>
+void test_all_pl_pl(Strategy pp_strategy)
+{
+ test_distance_point_point<Point>(pp_strategy);
+ test_distance_multipoint_point<Point>(pp_strategy);
+ test_distance_multipoint_multipoint<Point>(pp_strategy);
+
+ test_more_empty_input_pointlike_pointlike<Point>(pp_strategy);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_pointlike )
+{
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::spherical_equatorial<bg::degree>
+ > sph_point;
+
+ test_all_pl_pl<sph_point>(spherical_pp());
+
+ typedef bg::model::point
+ <
+ double, 2,
+ bg::cs::geographic<bg::degree>
+ > geo_point;
+
+ test_all_pl_pl<geo_point>(vincenty_pp());
+ test_all_pl_pl<geo_point>(thomas_pp());
+ test_all_pl_pl<geo_point>(andoyer_pp());
+
+ test_all_pl_pl<geo_point>(andoyer_pp(stype(5000000,6000000)));
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_l.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_l.cpp
new file mode 100644
index 00000000..948e35a6
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_l.cpp
@@ -0,0 +1,556 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+// 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 <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_spherical_equatorial_pointlike_linear
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#include "test_distance_se_common.hpp"
+#include "test_empty_geometry.hpp"
+
+typedef bg::cs::spherical_equatorial<bg::degree> cs_type;
+typedef bg::model::point<double, 2, cs_type> point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+typedef bg::model::segment<point_type> segment_type;
+typedef bg::model::linestring<point_type> linestring_type;
+typedef bg::model::multi_linestring<linestring_type> multi_linestring_type;
+
+namespace services = bg::strategy::distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef bg::strategy::distance::haversine<double> point_point_strategy;
+typedef bg::strategy::distance::cross_track<> point_segment_strategy;
+
+
+//===========================================================================
+
+template <typename Strategy>
+inline bg::default_distance_result<point_type>::type
+pp_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::distance(p1, p2) * strategy.radius();
+}
+
+template <typename Strategy>
+inline bg::default_comparable_distance_result<point_type>::type
+pp_comparable_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const&)
+{
+ point_type p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::comparable_distance(p1, p2);
+}
+
+template <typename Strategy>
+inline bg::default_distance_result<point_type>::type
+ps_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p;
+ segment_type s;
+ bg::read_wkt(wkt1, p);
+ bg::read_wkt(wkt2, s);
+ return bg::distance(p, s, strategy);
+}
+
+template <typename Strategy>
+inline bg::default_comparable_distance_result<point_type>::type
+ps_comparable_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p;
+ segment_type s;
+ bg::read_wkt(wkt1, p);
+ bg::read_wkt(wkt2, s);
+ return bg::comparable_distance(p, s, strategy);
+}
+
+template <typename Strategy, typename T>
+T to_comparable(Strategy const& strategy, T const& distance)
+{
+ namespace services = bg::strategy::distance::services;
+
+ typedef typename services::comparable_type
+ <
+ Strategy
+ >::type comparable_strategy;
+
+ typedef typename services::result_from_distance
+ <
+ comparable_strategy,
+ point_type,
+ bg::point_type<segment_type>::type
+ > get_comparable_distance;
+
+ comparable_strategy cstrategy = services::get_comparable
+ <
+ Strategy
+ >::apply(strategy);
+
+ return get_comparable_distance::apply(cstrategy, distance);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_segment(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, segment_type> tester;
+
+ double const d2r = bg::math::d2r<double>();
+
+ tester::apply("p-s-01",
+ "POINT(0 0)",
+ "SEGMENT(2 0,3 0)",
+ 2.0 * d2r * strategy.radius(),
+ to_comparable(strategy, 2.0 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-02",
+ "POINT(2.5 3)",
+ "SEGMENT(2 0,3 0)",
+ 3.0 * d2r * strategy.radius(),
+ to_comparable(strategy, 3.0 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-03",
+ "POINT(2 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-s-04",
+ "POINT(3 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-s-05",
+ "POINT(2.5 0)",
+ "SEGMENT(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-s-06",
+ "POINT(3.5 3)",
+ "SEGMENT(2 0,3 0)",
+ pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy),
+ pp_comparable_distance("POINT(3 0)",
+ "POINT(3.5 3)",
+ strategy),
+ strategy);
+ tester::apply("p-s-07",
+ "POINT(0 0)",
+ "SEGMENT(0 10,10 10)",
+ ps_distance("POINT(0 0)", "SEGMENT(10 10,0 10)", strategy),
+ pp_comparable_distance("POINT(0 0)",
+ "POINT(0 10)",
+ strategy),
+ strategy);
+ // very small distances to segment
+ tester::apply("p-s-07",
+ "POINT(90 1e-3)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-3 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-3 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-08",
+ "POINT(90 1e-4)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-4 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-4 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-09",
+ "POINT(90 1e-5)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-5 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-5 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-10",
+ "POINT(90 1e-6)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-6 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-6 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-11",
+ "POINT(90 1e-7)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-7 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-7 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-s-12",
+ "POINT(90 1e-8)",
+ "SEGMENT(0.5 0,175.5 0)",
+ 1e-8 * d2r * strategy.radius(),
+ to_comparable(strategy, 1e-8 * d2r * strategy.radius()),
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_linestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/linestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, linestring_type> tester;
+
+ double const r = strategy.radius();
+ double const d2r = bg::math::d2r<double>();
+
+ tester::apply("p-l-01",
+ "POINT(0 0)",
+ "LINESTRING(2 0,2 0)",
+ 2.0 * d2r * r,
+ to_comparable(strategy, 2.0 * d2r * r),
+ strategy);
+ tester::apply("p-l-02",
+ "POINT(0 0)",
+ "LINESTRING(2 0,3 0)",
+ 2.0 * d2r * r,
+ to_comparable(strategy, 2.0 * d2r * r),
+ strategy);
+ tester::apply("p-l-03",
+ "POINT(2.5 3)",
+ "LINESTRING(2 0,3 0)",
+ 3.0 * d2r * r,
+ to_comparable(strategy, 3.0 * d2r * r),
+ strategy);
+ tester::apply("p-l-04",
+ "POINT(2 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-l-05",
+ "POINT(3 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-l-06",
+ "POINT(2.5 0)",
+ "LINESTRING(2 0,3 0)",
+ 0,
+ strategy);
+ tester::apply("p-l-07",
+ "POINT(7.5 10)",
+ "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)",
+ 10.0 * d2r * r,
+ to_comparable(strategy, 10.0 * d2r * r),
+ strategy);
+ tester::apply("p-l-08",
+ "POINT(7.5 10)",
+ "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)",
+ ps_distance("POINT(7.5 10)", "SEGMENT(7 1,20 2)", strategy),
+ ps_comparable_distance("POINT(7.5 10)",
+ "SEGMENT(7 1,20 2)",
+ strategy),
+ strategy);
+
+ // https://svn.boost.org/trac/boost/ticket/11982
+ tester::apply("p-l-09",
+ "POINT(10.4 63.43)",
+ "LINESTRING(10.733557 59.911923, 10.521812 59.887214)",
+ 0.06146397739758279 * r,
+ 0.000944156107132969,
+ strategy);
+
+ //https://github.com/boostorg/geometry/issues/557
+ tester::apply("p-l-issue557",
+ "POINT(51.99999790563572 43.71656981636763)",
+ "LINESTRING(52.0000243071011 43.716569742012496,\
+ 52.0000121532845 43.71656942616241,\
+ 52.0 43.7165690998572,\
+ 51.999987847203 43.7165687638793)",
+ 1.35062e-08 * r,
+ 4.5604e-17,
+ strategy);
+
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ point_type, multi_linestring_type
+ > tester;
+
+ double const d2r = bg::math::d2r<double>();
+
+ tester::apply("p-ml-01",
+ "POINT(0 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 2.0 * d2r * strategy.radius(),
+ to_comparable(strategy, 2.0 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-ml-02",
+ "POINT(2.5 3)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 3.0 * d2r * strategy.radius(),
+ to_comparable(strategy, 3.0 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("p-ml-03",
+ "POINT(2 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy);
+ tester::apply("p-ml-04",
+ "POINT(3 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy);
+ tester::apply("p-ml-05",
+ "POINT(2.5 0)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))",
+ 0,
+ strategy);
+ tester::apply("p-ml-06",
+ "POINT(7.5 10)",
+ "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))",
+ ps_distance("POINT(7.5 10)", "SEGMENT(6 0,20 1)", strategy),
+ ps_comparable_distance("POINT(7.5 10)",
+ "SEGMENT(6 0,20 1)",
+ strategy),
+ strategy);
+ tester::apply("p-ml-07",
+ "POINT(-8 10)",
+ "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))",
+ ps_distance("POINT(-8 10)", "SEGMENT(-6 0,-18 10)", strategy),
+ ps_comparable_distance("POINT(-8 10)",
+ "SEGMENT(-6 0,-18 10)",
+ strategy),
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_linestring_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "linestring/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ linestring_type, multi_point_type
+ > tester;
+
+ tester::apply("l-mp-01",
+ "LINESTRING(2 0,0 2,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
+ ps_comparable_distance("POINT(1 1)",
+ "SEGMENT(2 0,0 2)",
+ strategy),
+ strategy);
+ tester::apply("l-mp-02",
+ "LINESTRING(4 0,0 4,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ ps_distance("POINT(1 1)", "SEGMENT(0 4,4 0)", strategy),
+ ps_comparable_distance("POINT(1 1)",
+ "SEGMENT(0 4,4 0)",
+ strategy),
+ strategy);
+ tester::apply("l-mp-03",
+ "LINESTRING(1 1,2 2,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ 0,
+ strategy);
+ tester::apply("l-mp-04",
+ "LINESTRING(3 3,4 4,100 80)",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ strategy);
+ tester::apply("l-mp-05",
+ "LINESTRING(0 0,10 0,10 10,0 10,0 0)",
+ "MULTIPOINT(1 -1,80 80,5 0,150 90)",
+ 0,
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_multilinestring(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multilinestring distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_linestring_type
+ > tester;
+
+ tester::apply("mp-ml-01",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((2 0,0 2),(2 2,3 3))",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
+ ps_comparable_distance("POINT(1 1)",
+ "SEGMENT(2 0,0 2)",
+ strategy),
+ strategy);
+ tester::apply("mp-ml-02",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((3 0,0 3),(4 4,5 5))",
+ ps_distance("POINT(1 1)", "SEGMENT(3 0,0 3)", strategy),
+ ps_comparable_distance("POINT(1 1)",
+ "SEGMENT(3 0,0 3)",
+ strategy),
+ strategy);
+ tester::apply("mp-ml-03",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((4 4,5 5),(1 1,2 2))",
+ 0,
+ strategy);
+ tester::apply("mp-ml-04",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "MULTILINESTRING((4 4,3 3),(4 4,5 5))",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_segment(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/segment distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<multi_point_type, segment_type> tester;
+
+ double d2r = bg::math::d2r<double>();
+
+ tester::apply("mp-s-01",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(2 0,0 2)",
+ ps_distance("POINT(1 1)", "SEGMENT(2 0,0 2)", strategy),
+ ps_comparable_distance("POINT(1 1)",
+ "SEGMENT(2 0,0 2)",
+ strategy),
+ strategy);
+ tester::apply("mp-s-02",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(0 -3,1 -10)",
+ 3.0 * d2r * strategy.radius(),
+ to_comparable(strategy, 3.0 * d2r * strategy.radius()),
+ strategy);
+ tester::apply("mp-s-03",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(1 1,2 2)",
+ 0,
+ strategy);
+ tester::apply("mp-s-04",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(3 3,4 4)",
+ pp_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ pp_comparable_distance("POINT(1 1)", "POINT(3 3)", strategy),
+ strategy);
+ tester::apply("mp-s-05",
+ "MULTIPOINT(0 0,1 0,0 1,1 1)",
+ "SEGMENT(0.5 -3,1 -10)",
+ pp_distance("POINT(1 0)", "POINT(0.5 -3)", strategy),
+ pp_comparable_distance("POINT(1 0)",
+ "POINT(0.5 -3)",
+ strategy),
+ strategy);
+}
+
+//===========================================================================
+//===========================================================================
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_linear )
+{
+ test_distance_point_segment(point_segment_strategy());
+ test_distance_point_segment(point_segment_strategy(earth_radius_km));
+ test_distance_point_segment(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_linestring )
+{
+ test_distance_point_linestring(point_segment_strategy());
+ test_distance_point_linestring(point_segment_strategy(earth_radius_km));
+ test_distance_point_linestring(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_multilinestring )
+{
+ test_distance_point_multilinestring(point_segment_strategy());
+ test_distance_point_multilinestring(point_segment_strategy(earth_radius_km));
+ test_distance_point_multilinestring(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_linestring_multipoint )
+{
+ test_distance_linestring_multipoint(point_segment_strategy());
+ test_distance_linestring_multipoint(point_segment_strategy(earth_radius_km));
+ test_distance_linestring_multipoint(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_multilinestring )
+{
+ test_distance_multipoint_multilinestring(point_segment_strategy());
+ test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_km));
+ test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_segment )
+{
+ test_distance_multipoint_segment(point_segment_strategy());
+ test_distance_multipoint_segment(point_segment_strategy(earth_radius_km));
+ test_distance_multipoint_segment(point_segment_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_linear )
+{
+ test_more_empty_input_pointlike_linear
+ <
+ point_type
+ >(point_segment_strategy());
+
+ test_more_empty_input_pointlike_linear
+ <
+ point_type
+ >(point_segment_strategy(earth_radius_km));
+
+ test_more_empty_input_pointlike_linear
+ <
+ point_type
+ >(point_segment_strategy(earth_radius_miles));
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_pl.cpp b/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_pl.cpp
new file mode 100644
index 00000000..56c0a6e4
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/distance_se_pl_pl.cpp
@@ -0,0 +1,299 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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 Menelaos Karavelas, on behalf of Oracle
+// 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 <iostream>
+
+#ifndef BOOST_TEST_MODULE
+#define BOOST_TEST_MODULE test_distance_spherical_equatorial_pointlike_pointlike
+#endif
+
+#include <boost/range.hpp>
+
+#include <boost/test/included/unit_test.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include "test_distance_se_common.hpp"
+#include "test_empty_geometry.hpp"
+
+typedef bg::cs::spherical_equatorial<bg::degree> cs_type;
+typedef bg::model::point<double, 2, cs_type> point_type;
+typedef bg::model::multi_point<point_type> multi_point_type;
+
+namespace distance = bg::strategy::distance;
+namespace services = distance::services;
+typedef bg::default_distance_result<point_type>::type return_type;
+
+typedef distance::haversine<double> point_point_strategy;
+typedef distance::comparable::haversine<double> comparable_point_point_strategy;
+
+//===========================================================================
+
+template <typename Strategy>
+inline typename bg::distance_result<point_type, point_type, Strategy>::type
+distance_from_wkt(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ point_type p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::distance(p1, p2, strategy);
+}
+
+inline bg::default_comparable_distance_result<point_type>::type
+comparable_distance_from_wkt(std::string const& wkt1,
+ std::string const& wkt2)
+{
+ point_type p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::comparable_distance(p1, p2);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_point(Strategy const& strategy,
+ bool is_comparable_strategy = false)
+{
+ double pi = bg::math::pi<double>();
+ double r = strategy.radius();
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/point distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, point_type> tester;
+
+ tester::apply("p-p-01",
+ "POINT(10 10)",
+ "POINT(0 0)",
+ (is_comparable_strategy
+ ? 0.0150768448035229
+ : (0.24619691677893202 * r)),
+ 0.0150768448035229,
+ strategy);
+ tester::apply("p-p-02",
+ "POINT(10 10)",
+ "POINT(10 10)",
+ 0,
+ strategy);
+
+ // antipodal points
+ tester::apply("p-p-03",
+ "POINT(0 10)",
+ "POINT(180 -10)",
+ (is_comparable_strategy
+ ? 1.0
+ : (pi * r)),
+ 1.0,
+ strategy);
+ tester::apply("p-p-04",
+ "POINT(0 0)",
+ "POINT(180 0)",
+ (is_comparable_strategy
+ ? 1.0
+ : (pi * r)),
+ 1.0,
+ strategy);
+
+ // https://svn.boost.org/trac/boost/ticket/11982
+ tester::apply("p-p-05",
+ "POINT(10.521812 59.887214)",
+ "POINT(10.4 63.43)",
+ (is_comparable_strategy
+ ? 0.00095578716185788
+ : (0.06184146915711819 * r)),
+ 0.00095578716185788,
+ strategy);
+ tester::apply("p-p-06",
+ "POINT(10.733557 59.911923)",
+ "POINT(10.4 63.43)",
+ (is_comparable_strategy
+ ? 0.0009441561071329
+ : (0.0614639773975828 * r)),
+ 0.000944156107132969,
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_point_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "point/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries<point_type, multi_point_type> tester;
+
+ tester::apply("p-mp-01",
+ "POINT(10 10)",
+ "MULTIPOINT(10 10,20 10,20 20,10 20)",
+ 0,
+ strategy);
+ tester::apply("p-mp-02",
+ "POINT(10 10)",
+ "MULTIPOINT(20 20,20 30,30 20,30 30)",
+ distance_from_wkt("POINT(10 10)", "POINT(20 20)", strategy),
+ comparable_distance_from_wkt("POINT(10 10)", "POINT(20 20)"),
+ strategy);
+ tester::apply("p-mp-03",
+ "POINT(3 0)",
+ "MULTIPOINT(20 20,20 40,40 20,40 40)",
+ distance_from_wkt("POINT(3 0)", "POINT(20 20)", strategy),
+ comparable_distance_from_wkt("POINT(3 0)", "POINT(20 20)"),
+ strategy);
+
+ // almost antipodal points
+ tester::apply("p-mp-04",
+ "POINT(179 2)",
+ "MULTIPOINT(3 3,4 3,4 4,3 4)",
+ distance_from_wkt("POINT(179 2)", "POINT(4 4)", strategy),
+ comparable_distance_from_wkt("POINT(179 2)", "POINT(4 4)"),
+ strategy);
+
+ // minimum distance across the dateline
+ tester::apply("p-mp-05",
+ "POINT(355 5)",
+ "MULTIPOINT(10 10,20 10,20 20,10 20)",
+ distance_from_wkt("POINT(355 5)", "POINT(10 10)", strategy),
+ comparable_distance_from_wkt("POINT(355 5)", "POINT(10 10)"),
+ strategy);
+ tester::apply("p-mp-06",
+ "POINT(-5 5)",
+ "MULTIPOINT(10 10,20 10,20 20,10 20)",
+ distance_from_wkt("POINT(-5 5)", "POINT(10 10)", strategy),
+ comparable_distance_from_wkt("POINT(-5 5)", "POINT(10 10)"),
+ strategy);
+}
+
+//===========================================================================
+
+template <typename Strategy>
+void test_distance_multipoint_multipoint(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "multipoint/multipoint distance tests" << std::endl;
+#endif
+ typedef test_distance_of_geometries
+ <
+ multi_point_type, multi_point_type
+ > tester;
+
+ tester::apply("mp-mp-01",
+ "MULTIPOINT(10 10,11 10,10 11,11 11)",
+ "MULTIPOINT(11 11,12 11,12 12,11 12)",
+ 0,
+ strategy);
+ tester::apply("mp-mp-02",
+ "MULTIPOINT(10 10,11 10,10 11,11 11)",
+ "MULTIPOINT(12 12,12 13,13 12,13 13)",
+ distance_from_wkt("POINT(11 11)", "POINT(12 12)", strategy),
+ comparable_distance_from_wkt("POINT(11 11)", "POINT(12 12)"),
+ strategy);
+
+ // example with many points in each multi-point so that the r-tree
+ // does some splitting.
+ tester::apply("mp-mp-03",
+ "MULTIPOINT(1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 8,1 9,1 10,\
+ 2 1,2 2,2 3,2 4,2 5,2 6,2 7,2 8,2 9,2 10,\
+ 3 1,3 2,3 3,3 4,3 5,3 6,3 7,3 8,3 9,3 10,\
+ 10 1,10 10)",
+ "MULTIPOINT(11 11,11 12,11 13,11 14,11 15,\
+ 11 16,11 17,11 18,11 19,11 20,\
+ 12 11,12 12,12 13,12 24,12 15,\
+ 12 16,12 17,12 18,12 29,12 20,\
+ 13 11,13 12,13 13,13 24,13 15,\
+ 13 16,13 17,13 18,13 29,13 20,\
+ 20 11,20 20)",
+ distance_from_wkt("POINT(10 10)", "POINT(11 11)", strategy),
+ comparable_distance_from_wkt("POINT(10 10)", "POINT(11 11)"),
+ strategy);
+
+}
+
+//===========================================================================
+
+BOOST_AUTO_TEST_CASE( test_all_pointlike_pointlike )
+{
+ test_distance_point_point(point_point_strategy());
+ test_distance_point_point(point_point_strategy(earth_radius_km));
+ test_distance_point_point(point_point_strategy(earth_radius_miles));
+
+ test_distance_point_point(comparable_point_point_strategy(), true);
+ test_distance_point_point
+ (comparable_point_point_strategy(earth_radius_km), true);
+ test_distance_point_point
+ (comparable_point_point_strategy(earth_radius_miles), true);
+}
+
+BOOST_AUTO_TEST_CASE( test_all_point_multipoint )
+{
+ test_distance_point_multipoint(point_point_strategy());
+ test_distance_point_multipoint(point_point_strategy(earth_radius_km));
+ test_distance_point_multipoint(point_point_strategy(earth_radius_miles));
+
+ test_distance_point_multipoint(comparable_point_point_strategy());
+ test_distance_point_multipoint
+ (comparable_point_point_strategy(earth_radius_km));
+ test_distance_point_multipoint
+ (comparable_point_point_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_multipoint_multipoint )
+{
+ test_distance_multipoint_multipoint(point_point_strategy());
+ test_distance_multipoint_multipoint(point_point_strategy(earth_radius_km));
+ test_distance_multipoint_multipoint
+ (point_point_strategy(earth_radius_miles));
+
+ test_distance_multipoint_multipoint(comparable_point_point_strategy());
+ test_distance_multipoint_multipoint
+ (comparable_point_point_strategy(earth_radius_km));
+ test_distance_multipoint_multipoint
+ (comparable_point_point_strategy(earth_radius_miles));
+}
+
+BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike )
+{
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(point_point_strategy());
+
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(point_point_strategy(earth_radius_km));
+
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(point_point_strategy(earth_radius_miles));
+
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(comparable_point_point_strategy());
+
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(comparable_point_point_strategy(earth_radius_km));
+
+ test_more_empty_input_pointlike_pointlike
+ <
+ point_type
+ >(comparable_point_point_strategy(earth_radius_miles));
+}
diff --git a/src/boost/libs/geometry/test/algorithms/distance/test_distance.hpp b/src/boost/libs/geometry/test/algorithms/distance/test_distance.hpp
new file mode 100644
index 00000000..cfda00e2
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/test_distance.hpp
@@ -0,0 +1,138 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 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)
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_HPP
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/io/wkt/read.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+// Define a custom distance strategy
+// For this one, the "taxicab" distance,
+// see http://en.wikipedia.org/wiki/Taxicab_geometry
+
+// For a point-point-distance operation, one typename Point is enough.
+// For a point-segment-distance operation, there is some magic inside
+// using another point type and casting if necessary. Therefore,
+// two point-types are necessary.
+struct taxicab_distance
+{
+ template <typename P1, typename P2>
+ static inline typename bg::coordinate_type<P1>::type apply(
+ P1 const& p1, P2 const& p2)
+ {
+ using bg::get;
+ using bg::math::abs;
+ return abs(get<0>(p1) - get<1>(p2))
+ + abs(get<1>(p1) - get<1>(p2));
+ }
+};
+
+
+
+namespace boost { namespace geometry { namespace strategy { namespace distance { namespace services
+{
+
+template <>
+struct tag<taxicab_distance>
+{
+ typedef strategy_tag_distance_point_point type;
+};
+
+
+template <typename P1, typename P2>
+struct return_type<taxicab_distance, P1, P2>
+{
+ typedef typename coordinate_type<P1>::type type;
+};
+
+
+template <>
+struct comparable_type<taxicab_distance>
+{
+ typedef taxicab_distance type;
+};
+
+template <>
+struct get_comparable<taxicab_distance>
+{
+ static inline taxicab_distance apply(taxicab_distance const& input)
+ {
+ return input;
+ }
+};
+
+template <typename P1, typename P2>
+struct result_from_distance<taxicab_distance, P1, P2>
+{
+ template <typename T>
+ static inline typename coordinate_type<P1>::type apply(taxicab_distance const& , T const& value)
+ {
+ return value;
+ }
+};
+
+
+}}}}} // namespace bg::strategy::distance::services
+
+
+
+
+
+template <typename Geometry1, typename Geometry2>
+void test_distance(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ long double expected_distance)
+{
+ typename bg::default_distance_result<Geometry1>::type distance = bg::distance(geometry1, geometry2);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::ostringstream out;
+ out << typeid(typename bg::coordinate_type<Geometry1>::type).name()
+ << std::endl
+ << typeid(typename bg::default_distance_result<Geometry1>::type).name()
+ << std::endl
+ << "distance : " << bg::distance(geometry1, geometry2)
+ << std::endl;
+ std::cout << out.str();
+#endif
+
+ BOOST_CHECK_CLOSE(distance, expected_distance, 0.0001);
+}
+
+
+template <typename Geometry1, typename Geometry2>
+void test_geometry(std::string const& wkt1, std::string const& wkt2, double expected_distance)
+{
+ Geometry1 geometry1;
+ bg::read_wkt(wkt1, geometry1);
+ Geometry2 geometry2;
+ bg::read_wkt(wkt2, geometry2);
+
+ test_distance(geometry1, geometry2, expected_distance);
+}
+
+template <typename Geometry1, typename Geometry2>
+void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
+}
+
+
+#endif
diff --git a/src/boost/libs/geometry/test/algorithms/distance/test_distance_common.hpp b/src/boost/libs/geometry/test/algorithms/distance/test_distance_common.hpp
new file mode 100644
index 00000000..bed7afe5
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/test_distance_common.hpp
@@ -0,0 +1,611 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2014-2017, 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
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_COMMON_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_COMMON_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/multi_point.hpp>
+#include <boost/geometry/geometries/multi_linestring.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
+
+#include <boost/geometry/io/wkt/write.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <from_wkt.hpp>
+#include <string_from_type.hpp>
+
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP
+
+namespace bg = ::boost::geometry;
+
+// function copied from BG's test_distance.hpp
+
+template <typename Geometry1, typename Geometry2>
+void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
+}
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_HPP
+
+//========================================================================
+
+
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+// pretty print geometry -- START
+template <typename Geometry, typename GeometryTag>
+struct pretty_print_geometry_dispatch
+{
+ template <typename Stream>
+ static inline Stream& apply(Geometry const& geometry, Stream& os)
+ {
+ os << bg::wkt(geometry);
+ return os;
+ }
+};
+
+template <typename Geometry>
+struct pretty_print_geometry_dispatch<Geometry, bg::segment_tag>
+{
+ template <typename Stream>
+ static inline Stream& apply(Geometry const& geometry, Stream& os)
+ {
+ os << "SEGMENT" << bg::dsv(geometry);
+ return os;
+ }
+};
+
+template <typename Geometry>
+struct pretty_print_geometry_dispatch<Geometry, bg::box_tag>
+{
+ template <typename Stream>
+ static inline Stream& apply(Geometry const& geometry, Stream& os)
+ {
+ os << "BOX" << bg::dsv(geometry);
+ return os;
+ }
+};
+
+
+template <typename Geometry>
+struct pretty_print_geometry
+{
+ template <typename Stream>
+ static inline Stream& apply(Geometry const& geometry, Stream& os)
+ {
+ return pretty_print_geometry_dispatch
+ <
+ Geometry, typename bg::tag<Geometry>::type
+ >::apply(geometry, os);
+ }
+};
+// pretty print geometry -- END
+#endif // BOOST_GEOMETRY_TEST_DEBUG
+
+
+//========================================================================
+
+
+template <typename T>
+struct check_equal
+{
+ static inline void apply(T const& detected, T const& expected,
+ bool is_finite)
+ {
+ if (is_finite)
+ {
+ BOOST_CHECK(detected == expected);
+ }
+ else
+ {
+ BOOST_CHECK(! boost::math::isfinite(detected));
+ }
+ }
+};
+
+template <>
+struct check_equal<double>
+{
+ static inline void apply(double detected, double expected,
+ bool is_finite)
+ {
+ if (is_finite)
+ {
+ BOOST_CHECK_CLOSE(detected, expected, 0.0001);
+ }
+ else
+ {
+ BOOST_CHECK(! boost::math::isfinite(detected));
+ }
+ }
+};
+
+
+//========================================================================
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ int id1 = bg::geometry_id<Geometry1>::value,
+ int id2 = bg::geometry_id<Geometry2>::value
+>
+struct test_distance_of_geometries
+ : public test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{};
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+#define ENABLE_IF_DEBUG(ID) ID
+#else
+#define ENABLE_IF_DEBUG(ID)
+#endif
+
+template <typename Geometry1, typename Geometry2>
+class test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{
+private:
+ template
+ <
+ typename G1,
+ typename G2,
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void base_test(std::string const& ENABLE_IF_DEBUG(header),
+ G1 const& g1, G2 const& g2,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite)
+ {
+ typedef typename bg::default_distance_result
+ <
+ G1, G2
+ >::type default_distance_result;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ Strategy, G1, G2
+ >::type distance_result_from_strategy;
+
+ static const bool same_regular = boost::is_same
+ <
+ default_distance_result,
+ distance_result_from_strategy
+ >::type::value;
+
+ BOOST_CHECK( same_regular );
+
+
+ typedef typename bg::default_comparable_distance_result
+ <
+ G1, G2
+ >::type default_comparable_distance_result;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ typename bg::strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type,
+ G1,
+ G2
+ >::type comparable_distance_result_from_strategy;
+
+ static const bool same_comparable = boost::is_same
+ <
+ default_comparable_distance_result,
+ comparable_distance_result_from_strategy
+ >::type::value;
+
+ BOOST_CHECK( same_comparable );
+
+
+ // check distance with default strategy
+ default_distance_result dist_def = bg::distance(g1, g2);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(dist_def, expected_distance, is_finite);
+
+
+ // check distance with passed strategy
+ distance_result_from_strategy dist = bg::distance(g1, g2, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(dist, expected_distance, is_finite);
+
+
+ // check comparable distance with default strategy
+ default_comparable_distance_result cdist_def =
+ bg::comparable_distance(g1, g2);
+
+ check_equal
+ <
+ default_comparable_distance_result
+ >::apply(cdist_def, expected_comparable_distance, is_finite);
+
+
+ // check comparable distance with passed strategy
+ comparable_distance_result_from_strategy cdist =
+ bg::comparable_distance(g1, g2, strategy);
+
+ check_equal
+ <
+ default_comparable_distance_result
+ >::apply(cdist, expected_comparable_distance, is_finite);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << string_from_type<typename bg::coordinate_type<Geometry1>::type>::name()
+ << string_from_type<typename bg::coordinate_type<Geometry2>::type>::name()
+ << " -> "
+ << string_from_type<default_distance_result>::name()
+ << string_from_type<default_comparable_distance_result>::name()
+ << std::endl;
+
+ std::cout << "distance" << header
+ << " (def. strategy) = " << dist_def << " ; "
+ << "distance" << header
+ <<" (passed strategy) = " << dist << " ; "
+ << "comp. distance" << header <<" (def. strategy) = "
+ << cdist_def << " ; "
+ << "comp. distance" << header <<" (passed strategy) = "
+ << cdist << std::endl;
+#endif
+ }
+
+public:
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& wkt1,
+ std::string const& wkt2,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
+ Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
+
+ apply(geometry1, geometry2,
+ expected_distance, expected_comparable_distance,
+ strategy, is_finite);
+ }
+
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ typedef pretty_print_geometry<Geometry1> PPG1;
+ typedef pretty_print_geometry<Geometry2> PPG2;
+ PPG1::apply(geometry1, std::cout);
+ std::cout << " - ";
+ PPG2::apply(geometry2, std::cout);
+ std::cout << std::endl;
+#endif
+
+ base_test("", geometry1, geometry2,
+ expected_distance, expected_comparable_distance,
+ strategy, is_finite);
+
+ base_test("[reversed args]", geometry2, geometry1,
+ expected_distance, expected_comparable_distance,
+ strategy, is_finite);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+#endif
+ }
+};
+
+
+//========================================================================
+
+template <typename Segment, typename Polygon>
+struct test_distance_of_geometries
+<
+ Segment, Polygon,
+ 92 /* segment */, 3 /* polygon */
+>
+ : public test_distance_of_geometries<Segment, Polygon, 0, 0>
+{
+ typedef test_distance_of_geometries<Segment, Polygon, 0, 0> base;
+
+ typedef typename bg::ring_type<Polygon>::type ring_type;
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& wkt_segment,
+ std::string const& wkt_polygon,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ Segment segment = from_wkt<Segment>(wkt_segment);
+ Polygon polygon = from_wkt<Polygon>(wkt_polygon);
+ apply(segment,
+ polygon,
+ expected_distance,
+ expected_comparable_distance,
+ strategy,
+ is_finite);
+ }
+
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(Segment const& segment,
+ Polygon const& polygon,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ base::apply(segment, polygon, expected_distance,
+ expected_comparable_distance, strategy, is_finite);
+
+ if ( bg::num_interior_rings(polygon) == 0 ) {
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "... testing also exterior ring ..." << std::endl;
+#endif
+ test_distance_of_geometries
+ <
+ Segment, ring_type
+ >::apply(segment,
+ bg::exterior_ring(polygon),
+ expected_distance,
+ expected_comparable_distance,
+ strategy,
+ is_finite);
+ }
+ }
+};
+
+//========================================================================
+
+template <typename Box, typename Segment>
+struct test_distance_of_geometries
+<
+ Box, Segment,
+ 94 /* box */, 92 /* segment */
+>
+{
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& wkt_box,
+ std::string const& wkt_segment,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ test_distance_of_geometries
+ <
+ Segment, Box, 92, 94
+ >::apply(wkt_segment,
+ wkt_box,
+ expected_distance,
+ expected_comparable_distance,
+ strategy,
+ is_finite);
+ }
+};
+
+
+template <typename Segment, typename Box>
+struct test_distance_of_geometries
+<
+ Segment, Box,
+ 92 /* segment */, 94 /* box */
+>
+ : public test_distance_of_geometries<Segment, Box, 0, 0>
+{
+ typedef test_distance_of_geometries<Segment, Box, 0, 0> base;
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& wkt_segment,
+ std::string const& wkt_box,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ Segment segment = from_wkt<Segment>(wkt_segment);
+ Box box = from_wkt<Box>(wkt_box);
+ apply(segment,
+ box,
+ expected_distance,
+ expected_comparable_distance,
+ strategy,
+ is_finite);
+ }
+
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(Segment const& segment,
+ Box const& box,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool is_finite = true)
+ {
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ Strategy, Segment, Box
+ >::type distance_result_type;
+
+ typedef typename bg::strategy::distance::services::comparable_type
+ <
+ Strategy
+ >::type comparable_strategy;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ comparable_strategy, Segment, Box
+ >::type comparable_distance_result_type;
+
+
+ base::apply(segment, box, expected_distance,
+ expected_comparable_distance, strategy, is_finite);
+
+ comparable_strategy cstrategy =
+ bg::strategy::distance::services::get_comparable
+ <
+ Strategy
+ >::apply(strategy);
+
+ distance_result_type distance_generic =
+ bg::detail::distance::segment_to_box_2D_generic
+ <
+ Segment, Box, Strategy
+ >::apply(segment, box, strategy);
+
+ comparable_distance_result_type comparable_distance_generic =
+ bg::detail::distance::segment_to_box_2D_generic
+ <
+ Segment, Box, comparable_strategy
+ >::apply(segment, box, cstrategy);
+
+
+ check_equal
+ <
+ distance_result_type
+ >::apply(distance_generic, expected_distance, is_finite);
+
+ check_equal
+ <
+ comparable_distance_result_type
+ >::apply(comparable_distance_generic,
+ expected_comparable_distance,
+ is_finite);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "... testing with naive seg-box distance algorithm..."
+ << std::endl;
+ std::cout << "distance (generic algorithm) = "
+ << distance_generic << " ; "
+ << "comp. distance (generic algorithm) = "
+ << comparable_distance_generic
+ << std::endl;
+ std::cout << std::endl << std::endl;
+#endif
+ }
+};
+
+//========================================================================
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+void test_empty_input(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
+
+ try
+ {
+ bg::distance(geometry2, geometry1, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" );
+}
+
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_COMMON_HPP
diff --git a/src/boost/libs/geometry/test/algorithms/distance/test_distance_geo_common.hpp b/src/boost/libs/geometry/test/algorithms/distance/test_distance_geo_common.hpp
new file mode 100644
index 00000000..dfb4c7e6
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/test_distance_geo_common.hpp
@@ -0,0 +1,577 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2016-2017, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_GEO_COMMON_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_GEO_COMMON_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/multi_point.hpp>
+#include <boost/geometry/geometries/multi_linestring.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
+
+#include <boost/geometry/io/wkt/write.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <from_wkt.hpp>
+#include <string_from_type.hpp>
+
+#include "distance_brute_force.hpp"
+
+namespace bg = ::boost::geometry;
+
+typedef bg::srs::spheroid<double> stype;
+
+// Spherical strategy for point-point distance
+
+typedef bg::strategy::distance::haversine<double> spherical_pp;
+
+// Geo strategies for point-point distance
+
+typedef bg::strategy::distance::andoyer<stype> andoyer_pp;
+typedef bg::strategy::distance::thomas<stype> thomas_pp;
+typedef bg::strategy::distance::vincenty<stype> vincenty_pp;
+
+// Spherical strategy for point-segment distance
+
+typedef bg::strategy::distance::cross_track<> spherical_ps;
+
+// Geo strategies for point-segment distance
+
+typedef bg::strategy::distance::geographic_cross_track<bg::strategy::andoyer, stype, double>
+ andoyer_ps;
+
+typedef bg::strategy::distance::geographic_cross_track<bg::strategy::thomas, stype, double>
+ thomas_ps;
+
+typedef bg::strategy::distance::geographic_cross_track<bg::strategy::vincenty, stype, double>
+ vincenty_ps;
+
+typedef bg::strategy::distance::detail::geographic_cross_track<bg::strategy::vincenty, stype, double, true>
+ vincenty_ps_bisection;
+
+// Spherical strategy for point-box distance
+
+typedef bg::strategy::distance::cross_track_point_box<> spherical_pb;
+
+// Geo strategies for point-box distance
+
+typedef bg::strategy::distance::geographic_cross_track_point_box
+<
+ bg::strategy::andoyer,
+ stype,
+ double
+> andoyer_pb;
+
+typedef bg::strategy::distance::geographic_cross_track_point_box
+<
+ bg::strategy::thomas,
+ stype,
+ double
+> thomas_pb;
+
+typedef bg::strategy::distance::geographic_cross_track_point_box
+<
+ bg::strategy::vincenty,
+ stype,
+ double
+> vincenty_pb;
+
+// Spherical strategy for segment-box distance
+
+typedef bg::strategy::distance::spherical_segment_box<> spherical_sb;
+
+// Geo strategies for segment-box distance
+
+typedef bg::strategy::distance::geographic_segment_box<bg::strategy::andoyer, stype, double>
+ andoyer_sb;
+
+typedef bg::strategy::distance::geographic_segment_box<bg::strategy::thomas, stype, double>
+ thomas_sb;
+
+typedef bg::strategy::distance::geographic_segment_box<bg::strategy::vincenty, stype, double>
+ vincenty_sb;
+
+// Strategies for box-box distance
+
+typedef bg::strategy::distance::cross_track_box_box<> spherical_bb;
+
+typedef bg::strategy::distance::geographic_cross_track_box_box
+ <
+ bg::strategy::andoyer,
+ stype,
+ double
+ > andoyer_bb;
+
+typedef bg::strategy::distance::geographic_cross_track_box_box
+ <
+ bg::strategy::thomas,
+ stype,
+ double
+ > thomas_bb;
+
+typedef bg::strategy::distance::geographic_cross_track_box_box
+ <
+ bg::strategy::vincenty,
+ stype,
+ double
+ > vincenty_bb;
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+inline typename bg::default_distance_result<Point>::type
+pp_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ Point p1, p2;
+ bg::read_wkt(wkt1, p1);
+ bg::read_wkt(wkt2, p2);
+ return bg::distance(p1, p2, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+inline typename bg::default_distance_result<Point>::type
+ps_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ Point p;
+ typedef bg::model::segment<Point> segment_type;
+ segment_type s;
+ bg::read_wkt(wkt1, p);
+ bg::read_wkt(wkt2, s);
+ return bg::distance(p, s, strategy);
+}
+
+//===========================================================================
+
+template <typename Point, typename Strategy>
+inline typename bg::default_distance_result<Point>::type
+sb_distance(std::string const& wkt1,
+ std::string const& wkt2,
+ Strategy const& strategy)
+{
+ typedef bg::model::segment<Point> segment_type;
+ typedef bg::model::box<Point> box_type;
+ segment_type s;
+ box_type b;
+ bg::read_wkt(wkt1, s);
+ bg::read_wkt(wkt2, b);
+ return bg::distance(s, b, strategy);
+}
+
+//===================================================================
+
+template <typename Tag> struct dispatch
+{
+ //tag dispatching for swaping arguments in segments
+ template <typename T>
+ static inline T swap(T const& t)
+ {
+ return t;
+ }
+
+ // mirror geometry w.r.t. equator
+ template <typename T>
+ static inline T mirror(T const& t)
+ {
+ return t;
+ }
+};
+
+// Specialization for segments
+template <> struct dispatch<boost::geometry::segment_tag>
+{
+ template <typename Segment>
+ static inline Segment swap(Segment const& s)
+ {
+ Segment s_swaped;
+
+ bg::set<0, 0>(s_swaped, bg::get<1, 0>(s));
+ bg::set<0, 1>(s_swaped, bg::get<1, 1>(s));
+ bg::set<1, 0>(s_swaped, bg::get<0, 0>(s));
+ bg::set<1, 1>(s_swaped, bg::get<0, 1>(s));
+
+ return s_swaped;
+ }
+
+ template <typename Segment>
+ static inline Segment mirror(Segment const& s)
+ {
+ Segment s_mirror;
+
+ bg::set<0, 0>(s_mirror, bg::get<0, 0>(s));
+ bg::set<0, 1>(s_mirror, bg::get<0, 1>(s) * -1);
+ bg::set<1, 0>(s_mirror, bg::get<1, 0>(s));
+ bg::set<1, 1>(s_mirror, bg::get<1, 1>(s) * -1);
+
+ return s_mirror;
+ }
+};
+
+// Specialization for boxes
+template <> struct dispatch<boost::geometry::box_tag>
+{
+ template <typename T>
+ static inline T swap(T const& t)
+ {
+ return t;
+ }
+
+ template <typename Box>
+ static inline Box mirror(Box const& b)
+ {
+ Box b_mirror;
+
+ bg::set<0, 0>(b_mirror, bg::get<bg::min_corner, 0>(b));
+ bg::set<0, 1>(b_mirror, bg::get<bg::max_corner, 1>(b) * -1);
+ bg::set<1, 0>(b_mirror, bg::get<bg::max_corner, 0>(b));
+ bg::set<1, 1>(b_mirror, bg::get<bg::min_corner, 1>(b) * -1);
+
+ return b_mirror;
+ }
+};
+
+
+// Specialization for points
+template <> struct dispatch<boost::geometry::point_tag>
+{
+ template <typename T>
+ static inline T swap(T const& t)
+ {
+ return t;
+ }
+
+ template <typename Point>
+ static inline Point mirror(Point const& p)
+ {
+ Point p_mirror;
+
+ bg::set<0>(p_mirror, bg::get<0>(p));
+ bg::set<1>(p_mirror, bg::get<1>(p) * -1);
+
+ return p_mirror;
+ }
+};
+
+//========================================================================
+
+
+template <typename T>
+struct check_equal
+{
+ template <typename Value, typename = void>
+ struct equal_to
+ {
+ static inline void apply(Value const& x, Value const& y)
+ {
+ BOOST_CHECK(x == y);
+ }
+ };
+
+ template <typename Dummy>
+ struct equal_to<double, Dummy>
+ {
+ static inline void apply(double x, double y)
+ {
+ BOOST_CHECK_CLOSE(x, y, 0.001);
+ }
+ };
+
+ template <typename Geometry1, typename Geometry2>
+ static inline void apply(std::string const& /*case_id*/,
+ std::string const& /*subcase_id*/,
+ Geometry1 const& /*geometry1*/,
+ Geometry2 const& /*geometry2*/,
+ T const& detected,
+ T const& expected)
+ {
+ equal_to<T>::apply(expected, detected);
+ }
+};
+
+//========================================================================
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ int id1 = bg::geometry_id<Geometry1>::value,
+ int id2 = bg::geometry_id<Geometry2>::value
+>
+struct test_distance_of_geometries
+ : public test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{};
+
+
+template <typename Geometry1, typename Geometry2>
+struct test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{
+ template <typename DistanceType, typename Strategy>
+ static inline
+ void apply(std::string const& case_id,
+ std::string const& wkt1,
+ std::string const& wkt2,
+ DistanceType const& expected_distance,
+ Strategy const& strategy,
+ bool test_reversed = true,
+ bool swap_geometry_args = false,
+ bool mirror_geometry = true)
+ {
+ Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
+ Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
+
+ apply(case_id, geometry1, geometry2,
+ expected_distance,
+ strategy, test_reversed, swap_geometry_args,
+ mirror_geometry);
+ }
+
+
+ template
+ <
+ typename DistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& case_id,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ DistanceType const& expected_distance,
+ Strategy const& strategy,
+ bool test_reversed = true,
+ bool swap_geometry_args = false,
+ bool mirror_geometry = true)
+ {
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "case ID: " << case_id << "; "
+ << "G1: " << bg::wkt(geometry1)
+ << " - "
+ << "G2: " << bg::wkt(geometry2)
+ << std::endl;
+#endif
+ namespace services = bg::strategy::distance::services;
+
+ using bg::unit_test::distance_brute_force;
+
+ typedef typename bg::default_distance_result
+ <
+ Geometry1, Geometry2
+ >::type default_distance_result;
+
+ typedef typename services::return_type
+ <
+ Strategy, Geometry1, Geometry2
+ >::type distance_result_from_strategy;
+
+ static const bool same_regular = boost::is_same
+ <
+ default_distance_result,
+ distance_result_from_strategy
+ >::type::value;
+
+ BOOST_CHECK(same_regular);
+
+ // check distance with passed strategy
+ distance_result_from_strategy dist =
+ bg::distance(geometry1, geometry2, strategy);
+
+ check_equal
+ <
+ distance_result_from_strategy
+ >::apply(case_id, "a", geometry1, geometry2,
+ dist, expected_distance);
+
+ // check against the comparable distance computed in a
+ // brute-force manner
+ default_distance_result dist_brute_force
+ = distance_brute_force(geometry1, geometry2, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "b", geometry1, geometry2,
+ dist_brute_force, expected_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << string_from_type<typename bg::coordinate_type<Geometry1>::type>::name()
+ << string_from_type<typename bg::coordinate_type<Geometry2>::type>::name()
+ << " -> "
+ << string_from_type<default_distance_result>::name()
+ << std::endl;
+ std::cout << "expected distance = " << std::setprecision(10)
+ << expected_distance << " ; "
+ << std::endl;
+ std::cout << "distance = " << std::setprecision(10)
+ << dist << " ; "
+ << std::endl;
+
+ if ( !test_reversed )
+ {
+ std::cout << std::endl;
+ }
+#endif
+
+ if ( test_reversed )
+ {
+ // check distance with given strategy
+ dist = bg::distance(geometry2, geometry1, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "ra", geometry2, geometry1,
+ dist, expected_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "distance[reversed args] = " << std::setprecision(10)
+ << dist
+ << std::endl;
+#endif
+ }
+
+ if (swap_geometry_args)
+ {
+ Geometry1 g1 = dispatch
+ <
+ typename boost::geometry::tag<Geometry1>::type
+ >::swap(geometry1);
+
+ Geometry2 g2 = dispatch
+ <
+ typename boost::geometry::tag<Geometry2>::type
+ >::swap(geometry2);
+
+ // check distance with given strategy
+ dist = bg::distance(g1, g2, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "swap", g1, g2,
+ dist, expected_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "distance[swap geometry args] = " << std::setprecision(10)
+ << dist
+ << std::endl;
+ std::cout << std::endl;
+#endif
+ }
+ if (mirror_geometry)
+ {
+ Geometry1 g1 = dispatch
+ <
+ typename boost::geometry::tag<Geometry1>::type
+ >::mirror(geometry1);
+
+ Geometry2 g2 = dispatch
+ <
+ typename boost::geometry::tag<Geometry2>::type
+ >::mirror(geometry2);
+
+ // check distance with given strategy
+ dist = bg::distance(g1, g2, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "mirror", g1, g2,
+ dist, expected_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "distance[mirror geometries] = " << std::setprecision(10)
+ << dist
+ << std::endl;
+ std::cout << std::endl;
+#endif
+ }
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+#endif
+
+ }
+};
+
+
+//========================================================================
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+void test_empty_input(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry2, geometry1);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry1, geometry2, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry2, geometry1, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+}
+
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_GEO_COMMON_HPP
diff --git a/src/boost/libs/geometry/test/algorithms/distance/test_distance_se_common.hpp b/src/boost/libs/geometry/test/algorithms/distance/test_distance_se_common.hpp
new file mode 100644
index 00000000..1909c27f
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/test_distance_se_common.hpp
@@ -0,0 +1,381 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2014-2017, 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
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP
+
+#include <iostream>
+#include <string>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/type_traits/is_integral.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/linestring.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+#include <boost/geometry/geometries/ring.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/multi_point.hpp>
+#include <boost/geometry/geometries/multi_linestring.hpp>
+#include <boost/geometry/geometries/multi_polygon.hpp>
+
+#include <boost/geometry/io/wkt/write.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
+
+#include <boost/geometry/algorithms/num_interior_rings.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <from_wkt.hpp>
+#include <string_from_type.hpp>
+
+#include "distance_brute_force.hpp"
+
+namespace bg = ::boost::geometry;
+
+static const double earth_radius_km = 6371.0;
+static const double earth_radius_miles = 3959.0;
+
+
+//========================================================================
+
+
+template <typename T>
+struct check_equal
+{
+ template <typename Value, typename = void>
+ struct equal_to
+ {
+ static inline void apply(Value const& x, Value const& y)
+ {
+ BOOST_CHECK(x == y);
+ }
+ };
+
+ template <typename Dummy>
+ struct equal_to<double, Dummy>
+ {
+ static inline void apply(double x, double y)
+ {
+ BOOST_CHECK_CLOSE(x, y, 0.001);
+ }
+ };
+
+ template <typename Geometry1, typename Geometry2>
+ static inline void apply(std::string const& /*case_id*/,
+ std::string const& /*subcase_id*/,
+ Geometry1 const& /*geometry1*/,
+ Geometry2 const& /*geometry2*/,
+ T const& detected,
+ T const& expected)
+ {
+ equal_to<T>::apply(expected, detected);
+ /*
+ TODO:
+ Ideally we would want the following, but it does not work well
+ approximate equality test.
+
+ BOOST_CHECK_MESSAGE(equal_to<T>::apply(expected, detected),
+ "case ID: " << case_id << "-" << subcase_id << "; "
+ << "G1: " << bg::wkt(geometry1)
+ << " - "
+ << "G2: " << bg::wkt(geometry2)
+ << " -> Detected: " << detected
+ << "; Expected: " << expected);
+ */
+ }
+};
+
+//========================================================================
+
+template
+<
+ typename Geometry1, typename Geometry2,
+ int id1 = bg::geometry_id<Geometry1>::value,
+ int id2 = bg::geometry_id<Geometry2>::value
+>
+struct test_distance_of_geometries
+ : public test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{};
+
+
+template <typename Geometry1, typename Geometry2>
+struct test_distance_of_geometries<Geometry1, Geometry2, 0, 0>
+{
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& case_id,
+ std::string const& wkt1,
+ std::string const& wkt2,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool test_reversed = true)
+ {
+ Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
+ Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
+
+ apply(case_id, geometry1, geometry2,
+ expected_distance, expected_comparable_distance,
+ strategy, test_reversed);
+ }
+
+ template <typename DistanceType, typename Strategy>
+ static inline
+ void apply(std::string const& case_id,
+ std::string const& wkt1,
+ std::string const& wkt2,
+ DistanceType const& expected_distance,
+ Strategy const& strategy,
+ bool test_reversed = true)
+ {
+ Geometry1 geometry1 = from_wkt<Geometry1>(wkt1);
+ Geometry2 geometry2 = from_wkt<Geometry2>(wkt2);
+
+ apply(case_id, geometry1, geometry2,
+ expected_distance, expected_distance,
+ strategy, test_reversed);
+ }
+
+
+ template
+ <
+ typename DistanceType,
+ typename ComparableDistanceType,
+ typename Strategy
+ >
+ static inline
+ void apply(std::string const& case_id,
+ Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ DistanceType const& expected_distance,
+ ComparableDistanceType const& expected_comparable_distance,
+ Strategy const& strategy,
+ bool test_reversed = true)
+ {
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "case ID: " << case_id << "; "
+ << "G1: " << bg::wkt(geometry1)
+ << " - "
+ << "G2: " << bg::wkt(geometry2)
+ << std::endl;
+#endif
+ namespace services = bg::strategy::distance::services;
+
+ using bg::unit_test::distance_brute_force;
+
+ typedef typename bg::default_distance_result
+ <
+ Geometry1, Geometry2
+ >::type default_distance_result;
+
+ typedef typename services::return_type
+ <
+ Strategy, Geometry1, Geometry2
+ >::type distance_result_from_strategy;
+
+ static const bool same_regular = boost::is_same
+ <
+ default_distance_result,
+ distance_result_from_strategy
+ >::type::value;
+
+ BOOST_CHECK(same_regular);
+
+ typedef typename bg::default_comparable_distance_result
+ <
+ Geometry1, Geometry2
+ >::type default_comparable_distance_result;
+
+ typedef typename services::return_type
+ <
+ typename services::comparable_type<Strategy>::type,
+ Geometry1,
+ Geometry2
+ >::type comparable_distance_result_from_strategy;
+
+ static const bool same_comparable = boost::is_same
+ <
+ default_comparable_distance_result,
+ comparable_distance_result_from_strategy
+ >::type::value;
+
+ BOOST_CHECK( same_comparable );
+
+ // check distance with passed strategy
+ distance_result_from_strategy dist =
+ bg::distance(geometry1, geometry2, strategy);
+
+ check_equal
+ <
+ distance_result_from_strategy
+ >::apply(case_id, "a", geometry1, geometry2,
+ dist, expected_distance);
+
+ // check against the comparable distance computed in a
+ // brute-force manner
+ default_distance_result dist_brute_force
+ = distance_brute_force(geometry1, geometry2, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "b", geometry1, geometry2,
+ dist_brute_force, expected_distance);
+
+ // check comparable distance with passed strategy
+ comparable_distance_result_from_strategy cdist =
+ bg::comparable_distance(geometry1, geometry2, strategy);
+
+ check_equal
+ <
+ default_comparable_distance_result
+ >::apply(case_id, "c", geometry1, geometry2,
+ cdist, expected_comparable_distance);
+
+ // check against the comparable distance computed in a
+ // brute-force manner
+ default_comparable_distance_result cdist_brute_force
+ = distance_brute_force(geometry1,
+ geometry2,
+ services::get_comparable
+ <
+ Strategy
+ >::apply(strategy));
+
+ check_equal
+ <
+ default_comparable_distance_result
+ >::apply(case_id, "d", geometry1, geometry2,
+ cdist_brute_force, expected_comparable_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << string_from_type<typename bg::coordinate_type<Geometry1>::type>::name()
+ << string_from_type<typename bg::coordinate_type<Geometry2>::type>::name()
+ << " -> "
+ << string_from_type<default_distance_result>::name()
+ << string_from_type<default_comparable_distance_result>::name()
+ << std::endl;
+ std::cout << "strategy radius: " << strategy.radius() << std::endl;
+ std::cout << "expected distance = "
+ << expected_distance << " ; "
+ << "expected comp. distance = "
+ << expected_comparable_distance
+ << std::endl;
+ std::cout << "distance = "
+ << dist << " ; "
+ << "comp. distance = "
+ << cdist
+ << std::endl;
+
+ if ( !test_reversed )
+ {
+ std::cout << std::endl;
+ }
+#endif
+
+ if ( test_reversed )
+ {
+ // check distance with given strategy
+ dist = bg::distance(geometry2, geometry1, strategy);
+
+ check_equal
+ <
+ default_distance_result
+ >::apply(case_id, "ra", geometry2, geometry1,
+ dist, expected_distance);
+
+ // check comparable distance with given strategy
+ cdist = bg::comparable_distance(geometry2, geometry1, strategy);
+
+ check_equal
+ <
+ default_comparable_distance_result
+ >::apply(case_id, "rc", geometry2, geometry1,
+ cdist, expected_comparable_distance);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "distance[reversed args] = "
+ << dist << " ; "
+ << "comp. distance[reversed args] = "
+ << cdist
+ << std::endl;
+ std::cout << std::endl;
+#endif
+ }
+ }
+};
+
+
+//========================================================================
+
+
+template <typename Geometry1, typename Geometry2, typename Strategy>
+void test_empty_input(Geometry1 const& geometry1,
+ Geometry2 const& geometry2,
+ Strategy const& strategy)
+{
+ try
+ {
+ bg::distance(geometry1, geometry2);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry2, geometry1);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry1, geometry2, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+
+ try
+ {
+ bg::distance(geometry2, geometry1, strategy);
+ }
+ catch(bg::empty_input_exception const& )
+ {
+ return;
+ }
+ BOOST_CHECK_MESSAGE(false,
+ "A empty_input_exception should have been thrown");
+}
+
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP
diff --git a/src/boost/libs/geometry/test/algorithms/distance/test_empty_geometry.hpp b/src/boost/libs/geometry/test/algorithms/distance/test_empty_geometry.hpp
new file mode 100644
index 00000000..5aa0a43e
--- /dev/null
+++ b/src/boost/libs/geometry/test/algorithms/distance/test_empty_geometry.hpp
@@ -0,0 +1,213 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2018, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+
+// Licensed under the Boost Software License version 1.0.
+// http://www.boost.org/users/license.html
+
+
+#ifndef BOOST_GEOMETRY_TEST_EMPTY_GEOMETRY_HPP
+#define BOOST_GEOMETRY_TEST_EMPTY_GEOMETRY_HPP
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_pointlike_pointlike(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::multi_point<Point> multipoint_empty;
+
+ Point point = from_wkt<Point>("point(0 0)");
+
+ // 1st geometry is empty
+ test_empty_input(multipoint_empty, point, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(point, multipoint_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(multipoint_empty, multipoint_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_pointlike_linear(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::linestring<Point> line_empty;
+ bg::model::multi_point<Point> multipoint_empty;
+ bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
+
+ Point point = from_wkt<Point>("POINT(0 0)");
+ bg::model::linestring<Point> line =
+ from_wkt<bg::model::linestring<Point> >("LINESTRING(0 0,1 1,2 2)");
+
+ // 1st geometry is empty
+ test_empty_input(multipoint_empty, line, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(line, multipoint_empty, strategy);
+ test_empty_input(point, line_empty, strategy);
+ test_empty_input(point, multiline_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(multipoint_empty, line_empty, strategy);
+ test_empty_input(multipoint_empty, multiline_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_pointlike_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::multi_point<Point> multipoint_empty;
+
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+
+ Point point = from_wkt<Point>("POINT(0 0)");
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("POLYGON((0 0,1 0,1 1,0 1,0 0))");
+
+ // 1st geometry is empty
+ test_empty_input(multipoint_empty, polygon, strategy);
+ test_empty_input(polygon_empty, point, strategy);
+ test_empty_input(multipolygon_empty, point, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(point, polygon_empty, strategy);
+ test_empty_input(point, multipolygon_empty, strategy);
+ test_empty_input(polygon, multipoint_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(multipoint_empty, polygon_empty, strategy);
+ test_empty_input(multipoint_empty, multipolygon_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_linear_linear(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::linestring<Point> line_empty;
+ bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
+
+ bg::model::linestring<Point> line =
+ from_wkt<bg::model::linestring<Point> >("LINESTRING(0 0,1 1)");
+
+ // 1st geometry is empty
+ test_empty_input(line_empty, line, strategy);
+ test_empty_input(multiline_empty, line, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(line, line_empty, strategy);
+ test_empty_input(line, multiline_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(line_empty, line_empty, strategy);
+ test_empty_input(multiline_empty, line_empty, strategy);
+ test_empty_input(multiline_empty, multiline_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_linear_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::linestring<Point> line_empty;
+ bg::model::multi_linestring<bg::model::linestring<Point> > multiline_empty;
+
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+
+ bg::model::linestring<Point> line =
+ from_wkt<bg::model::linestring<Point> >("LINESTRING(0 0,1 1)");
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("POLYGON((0 0,1 0,1 1,0 1,0 0))");
+
+ // 1st geometry is empty
+ test_empty_input(line_empty, polygon, strategy);
+ test_empty_input(multiline_empty, polygon, strategy);
+ test_empty_input(polygon_empty, line, strategy);
+ test_empty_input(multipolygon_empty, line, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(line, polygon_empty, strategy);
+ test_empty_input(line, multipolygon_empty, strategy);
+ test_empty_input(polygon, line_empty, strategy);
+ test_empty_input(polygon, multiline_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(line_empty, polygon_empty, strategy);
+ test_empty_input(line_empty, multipolygon_empty, strategy);
+ test_empty_input(multiline_empty, polygon_empty, strategy);
+ test_empty_input(multiline_empty, multipolygon_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+
+template <typename Point, typename Strategy>
+void test_more_empty_input_areal_areal(Strategy const& strategy)
+{
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << "testing on empty inputs... " << std::flush;
+#endif
+ bg::model::polygon<Point> polygon_empty;
+ bg::model::multi_polygon<bg::model::polygon<Point> > multipolygon_empty;
+
+ bg::model::polygon<Point> polygon =
+ from_wkt<bg::model::polygon<Point> >("POLYGON((0 0,1 0,1 1,0 1,0 0))");
+
+ // 1st geometry is empty
+ test_empty_input(polygon_empty, polygon, strategy);
+ test_empty_input(multipolygon_empty, polygon, strategy);
+
+ // 2nd geometry is empty
+ test_empty_input(polygon, polygon_empty, strategy);
+ test_empty_input(polygon, multipolygon_empty, strategy);
+
+ // both geometries are empty
+ test_empty_input(polygon_empty, multipolygon_empty, strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "done!" << std::endl;
+#endif
+}
+
+#endif // BOOST_GEOMETRY_TEST_EMPTY_GEOMETRY_HPP