summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/geometry/test/strategies
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/strategies
parentInitial commit. (diff)
downloadceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.tar.xz
ceph-483eb2f56657e8e7f419ab1a4fab8dce9ade8609.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/strategies')
-rw-r--r--src/boost/libs/geometry/test/strategies/Jamfile.v246
-rw-r--r--src/boost/libs/geometry/test/strategies/andoyer.cpp346
-rw-r--r--src/boost/libs/geometry/test/strategies/cross_track.cpp181
-rw-r--r--src/boost/libs/geometry/test/strategies/crossings_multiply.cpp87
-rw-r--r--src/boost/libs/geometry/test/strategies/distance.cpp117
-rw-r--r--src/boost/libs/geometry/test/strategies/distance_cross_track.cpp116
-rw-r--r--src/boost/libs/geometry/test/strategies/distance_cross_track_cases.hpp518
-rw-r--r--src/boost/libs/geometry/test/strategies/distance_default_result.cpp270
-rw-r--r--src/boost/libs/geometry/test/strategies/douglas_peucker.cpp422
-rw-r--r--src/boost/libs/geometry/test/strategies/envelope_segment.cpp134
-rw-r--r--src/boost/libs/geometry/test/strategies/franklin.cpp86
-rw-r--r--src/boost/libs/geometry/test/strategies/haversine.cpp266
-rw-r--r--src/boost/libs/geometry/test/strategies/matrix_transformer.cpp103
-rw-r--r--src/boost/libs/geometry/test/strategies/point_in_box.cpp81
-rw-r--r--src/boost/libs/geometry/test/strategies/projected_point.cpp75
-rw-r--r--src/boost/libs/geometry/test/strategies/projected_point_ax.cpp87
-rw-r--r--src/boost/libs/geometry/test/strategies/pythagoras.cpp363
-rw-r--r--src/boost/libs/geometry/test/strategies/pythagoras_point_box.cpp505
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection.cpp218
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection_collinear.cpp527
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection_geo.cpp430
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection_geo.hpp270
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection_sph.cpp299
-rw-r--r--src/boost/libs/geometry/test/strategies/segment_intersection_sph.hpp221
-rw-r--r--src/boost/libs/geometry/test/strategies/side_of_intersection.cpp108
-rw-r--r--src/boost/libs/geometry/test/strategies/spherical_side.cpp173
-rw-r--r--src/boost/libs/geometry/test/strategies/test_projected_point.hpp185
-rw-r--r--src/boost/libs/geometry/test/strategies/test_within.hpp106
-rw-r--r--src/boost/libs/geometry/test/strategies/thomas.cpp153
-rw-r--r--src/boost/libs/geometry/test/strategies/transform_cs.cpp149
-rw-r--r--src/boost/libs/geometry/test/strategies/transformer.cpp119
-rw-r--r--src/boost/libs/geometry/test/strategies/vincenty.cpp330
-rw-r--r--src/boost/libs/geometry/test/strategies/winding.cpp218
33 files changed, 7309 insertions, 0 deletions
diff --git a/src/boost/libs/geometry/test/strategies/Jamfile.v2 b/src/boost/libs/geometry/test/strategies/Jamfile.v2
new file mode 100644
index 00000000..e58abee7
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/Jamfile.v2
@@ -0,0 +1,46 @@
+# Boost.Geometry (aka GGL, Generic Geometry Library)
+#
+# 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.
+#
+# This file was modified by Oracle on 2014-2019.
+# Modifications copyright (c) 2014-2019, 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-strategies
+ :
+ [ run andoyer.cpp : : : : strategies_andoyer ]
+ [ run cross_track.cpp : : : : strategies_cross_track ]
+ [ run crossings_multiply.cpp : : : : strategies_crossings_multiply ]
+ [ run distance_default_result.cpp : : : : strategies_distance_default_result ]
+ [ run distance_cross_track.cpp : : : : strategies_distance_cross_track ]
+ [ run douglas_peucker.cpp : : : : strategies_douglas_peucker ]
+ [ run envelope_segment.cpp : : : : strategies_envelope_segment ]
+ [ run franklin.cpp : : : : strategies_franklin ]
+ [ run haversine.cpp : : : : strategies_haversine ]
+ [ run point_in_box.cpp : : : : strategies_point_in_box ]
+ [ run projected_point.cpp : : : : strategies_projected_point ]
+ [ run projected_point_ax.cpp : : : : strategies_projected_point_ax ]
+ [ run pythagoras.cpp : : : : strategies_pythagoras ]
+ [ run pythagoras_point_box.cpp : : : : strategies_pythagoras_point_box ]
+ [ run segment_intersection.cpp : : : : strategies_segment_intersection ]
+ [ run segment_intersection_collinear.cpp : : : : strategies_segment_intersection_collinear ]
+ [ run segment_intersection_geo.cpp : : : : strategies_segment_intersection_geo ]
+ [ run segment_intersection_sph.cpp : : : : strategies_segment_intersection_sph ]
+ [ run side_of_intersection.cpp : : : : strategies_side_of_intersection ]
+ [ run spherical_side.cpp : : : : strategies_spherical_side ]
+ [ run thomas.cpp : : : : strategies_thomas ]
+ [ run transform_cs.cpp : : : : strategies_transform_cs ]
+ [ run transformer.cpp : : : : strategies_transformer ]
+ [ run matrix_transformer.cpp : : : : strategies_matrix_transformer ]
+ [ run vincenty.cpp : : : : strategies_vincenty ]
+ [ run winding.cpp : : : : strategies_winding ]
+ ;
diff --git a/src/boost/libs/geometry/test/strategies/andoyer.cpp b/src/boost/libs/geometry/test/strategies/andoyer.cpp
new file mode 100644
index 00000000..515bbf2e
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/andoyer.cpp
@@ -0,0 +1,346 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2016 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2016 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2016 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014-2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/geographic/distance_andoyer.hpp>
+#include <boost/geometry/strategies/geographic/side_andoyer.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+
+
+double make_deg(double deg, double min, double sec)
+{
+ return deg + min / 60.0 + sec / 3600.0;
+}
+
+double to_rad(double deg)
+{
+ return bg::math::pi<double>() * deg / 180.0;
+}
+
+double to_deg(double rad)
+{
+ return 180.0 * rad / bg::math::pi<double>();
+}
+
+double normlized_deg(double deg)
+{
+ if (deg > 180)
+ return deg - 360;
+ else if (deg < -180)
+ return deg + 360;
+ else
+ return deg;
+}
+
+
+template <typename P1, typename P2>
+void test_distance(double lon1, double lat1, double lon2, double lat2, double expected_km)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<P1>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+
+ typedef bg::strategy::distance::andoyer<stype> andoyer_type;
+ typedef bg::strategy::distance::geographic<bg::strategy::andoyer, stype> geographic_type;
+ typedef bg::formula::andoyer_inverse<rtype, true, false> andoyer_inverse_type;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointDistanceStrategy<andoyer_type, P1, P2>)
+ );
+
+ andoyer_type andoyer;
+ geographic_type geographic;
+ typedef typename bg::strategy::distance
+ ::services::return_type<andoyer_type, P1, P2>::type return_type;
+
+ P1 p1;
+ P2 p2;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+
+ return_type d_strategy = andoyer.apply(p1, p2);
+ return_type d_strategy2 = geographic.apply(p1, p2);
+ return_type d_function = bg::distance(p1, p2, andoyer);
+
+ double diff = bg::math::longitude_distance_signed<bg::degree>(lon1, lon2);
+ return_type d_formula;
+
+ // if the points lay on a meridian, distance strategy calls the special formula
+ // for meridian distance that returns different result than andoyer formula
+ // for nearly antipodal points
+ if (bg::math::equals(diff, 0.0)
+ || bg::math::equals(bg::math::abs(diff), 180.0))
+ {
+ d_formula = d_strategy;
+ }
+ else
+ {
+ d_formula = andoyer_inverse_type::apply(to_rad(lon1), to_rad(lat1),
+ to_rad(lon2), to_rad(lat2),
+ stype()).distance;
+ }
+
+ BOOST_CHECK_CLOSE(d_strategy / 1000.0, expected_km, 0.001);
+ BOOST_CHECK_CLOSE(d_strategy2 / 1000.0, expected_km, 0.001);
+ BOOST_CHECK_CLOSE(d_function / 1000.0, expected_km, 0.001);
+ BOOST_CHECK_CLOSE(d_formula / 1000.0, expected_km, 0.001);
+}
+
+template <typename PS, typename P>
+void test_azimuth(double lon1, double lat1,
+ double lon2, double lat2,
+ double expected_azimuth_deg)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<PS>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+ typedef bg::formula::andoyer_inverse<rtype, false, true> andoyer_inverse_type;
+
+ rtype a_formula = andoyer_inverse_type::apply(to_rad(lon1), to_rad(lat1), to_rad(lon2), to_rad(lat2), stype()).azimuth;
+
+ rtype azimuth_deg = to_deg(a_formula);
+
+ if (bg::math::equals(azimuth_deg, -180.0))
+ azimuth_deg = 180.0;
+ if (bg::math::equals(expected_azimuth_deg, -180.0))
+ expected_azimuth_deg = 180.0;
+
+ if (bg::math::equals(expected_azimuth_deg, 0.0))
+ {
+ BOOST_CHECK(bg::math::equals(azimuth_deg, expected_azimuth_deg));
+ }
+ else
+ {
+ BOOST_CHECK_CLOSE(azimuth_deg, expected_azimuth_deg, 0.001);
+ }
+}
+
+template <typename P1, typename P2>
+void test_distazi(double lon1, double lat1, double lon2, double lat2,
+ double expected_km, double expected_azimuth_deg)
+{
+ test_distance<P1, P2>(lon1, lat1, lon2, lat2, expected_km);
+ test_azimuth<P1, P2>(lon1, lat1, lon2, lat2, expected_azimuth_deg);
+}
+
+// requires SW->NE
+template <typename P1, typename P2>
+void test_distazi_symm(double lon1, double lat1, double lon2, double lat2,
+ double expected_km, double expected_azimuth_deg,
+ bool is_antipodal = false)
+{
+ double d180 = is_antipodal ? 0 : 180;
+ test_distazi<P1, P2>(lon1, lat1, lon2, lat2, expected_km, expected_azimuth_deg);
+ test_distazi<P1, P2>(-lon1, lat1, -lon2, lat2, expected_km, -expected_azimuth_deg);
+ test_distazi<P1, P2>(lon1, -lat1, lon2, -lat2, expected_km, d180 - expected_azimuth_deg);
+ test_distazi<P1, P2>(-lon1, -lat1, -lon2, -lat2, expected_km, -d180 + expected_azimuth_deg);
+}
+
+template <typename P1, typename P2>
+void test_distazi_symmNS(double lon1, double lat1, double lon2, double lat2,
+ double expected_km, double expected_azimuth_deg)
+{
+ test_distazi<P1, P2>(lon1, lat1, lon2, lat2, expected_km, expected_azimuth_deg);
+ test_distazi<P1, P2>(lon1, -lat1, lon2, -lat2, expected_km, 180 - expected_azimuth_deg);
+}
+
+
+template <typename PS, typename P>
+void test_side(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon, double lat,
+ int expected_side)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<PS>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+
+ typedef bg::strategy::side::andoyer<stype> strategy_type;
+ typedef bg::strategy::side::geographic<bg::strategy::andoyer, stype> strategy2_type;
+
+ strategy_type strategy;
+ strategy2_type strategy2;
+
+ PS p1, p2;
+ P p;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+ bg::assign_values(p, lon, lat);
+
+ int side = strategy.apply(p1, p2, p);
+ int side2 = strategy2.apply(p1, p2, p);
+
+ BOOST_CHECK_EQUAL(side, expected_side);
+ BOOST_CHECK_EQUAL(side2, expected_side);
+}
+
+template <typename P1, typename P2>
+void test_all()
+{
+ // polar
+ test_distazi<P1, P2>(0, 90, 1, 80,
+ 1116.814237, 179);
+
+ // no point difference
+ test_distazi<P1, P2>(4, 52, 4, 52,
+ 0.0, 0.0);
+
+ // normal cases
+ test_distazi<P1, P2>(4, 52, 3, 40,
+ 1336.039890, -176.3086);
+ test_distazi<P1, P2>(3, 52, 4, 40,
+ 1336.039890, 176.3086);
+ test_distazi<P1, P2>(make_deg(17, 19, 43.28),
+ make_deg(40, 30, 31.151),
+ 18, 40,
+ 80.323245,
+ make_deg(134, 27, 50.05));
+
+ // antipodal
+ // ok? in those cases shorter path would pass through a pole
+ // but 90 or -90 would be consistent with distance?
+ test_distazi<P1, P2>(0, 0, 180, 0, 20003.9, 0.0);
+ test_distazi<P1, P2>(0, 0, -180, 0, 20003.9, 0.0);
+ test_distazi<P1, P2>(-90, 0, 90, 0, 20003.9, 0.0);
+ test_distazi<P1, P2>(90, 0, -90, 0, 20003.9, 0.0);
+
+ // 0, 45, 90 ...
+ for (int i = 0 ; i < 360 ; i += 45)
+ {
+ // 0 45 90 ...
+ double l = normlized_deg(i);
+ // -1 44 89 ...
+ double l1 = normlized_deg(i - 1);
+ // 1 46 91 ...
+ double l2 = normlized_deg(i + 1);
+
+ // near equator
+ test_distazi_symm<P1, P2>(l1, -1, l2, 1, 313.7956, 45.1964);
+
+ // near poles
+ test_distazi_symmNS<P1, P2>(l, -89.5, l, 89.5, 19892.2, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.6, l, 89.6, 19914.6, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.7, l, 89.7, 19936.9, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.8, l, 89.8, 19959.2, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.9, l, 89.9, 19981.6, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.99, l, 89.99, 20001.7, 0.0);
+ test_distazi_symmNS<P1, P2>(l, -89.999, l, 89.999, 20003.7, 0.0);
+ // antipodal
+ test_distazi_symmNS<P1, P2>(l, -90, l, 90, 20003.9, 0.0);
+
+ test_distazi_symm<P1, P2>(normlized_deg(l-10.0), -10.0, normlized_deg(l+135), 45, 14892.1, 34.1802);
+ test_distazi_symm<P1, P2>(normlized_deg(l-30.0), -30.0, normlized_deg(l+135), 45, 17890.7, 33.7002);
+ test_distazi_symm<P1, P2>(normlized_deg(l-40.0), -40.0, normlized_deg(l+135), 45, 19319.7, 33.4801);
+ test_distazi_symm<P1, P2>(normlized_deg(l-41.0), -41.0, normlized_deg(l+135), 45, 19459.1, 33.2408);
+ test_distazi_symm<P1, P2>(normlized_deg(l-42.0), -42.0, normlized_deg(l+135), 45, 19597.8, 32.7844);
+ test_distazi_symm<P1, P2>(normlized_deg(l-43.0), -43.0, normlized_deg(l+135), 45, 19735.8, 31.7784);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.0), -44.0, normlized_deg(l+135), 45, 19873.0, 28.5588);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.1), -44.1, normlized_deg(l+135), 45, 19886.7, 27.8304);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.2), -44.2, normlized_deg(l+135), 45, 19900.4, 26.9173);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.3), -44.3, normlized_deg(l+135), 45, 19914.1, 25.7401);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.4), -44.4, normlized_deg(l+135), 45, 19927.7, 24.1668);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.5), -44.5, normlized_deg(l+135), 45, 19941.4, 21.9599);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.6), -44.6, normlized_deg(l+135), 45, 19955.0, 18.6438);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.7), -44.7, normlized_deg(l+135), 45, 19968.6, 13.1096);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.8), -44.8, normlized_deg(l+135), 45, 19982.3, 2.0300);
+ // nearly antipodal
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.9), -44.9, normlized_deg(l+135), 45, 19995.9, 0.0);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.95), -44.95, normlized_deg(l+135), 45, 20002.7, 0.0);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.99), -44.99, normlized_deg(l+135), 45, 20008.1, 0.0);
+ test_distazi_symm<P1, P2>(normlized_deg(l-44.999), -44.999, normlized_deg(l+135), 45, 20009.4, 0.0);
+ // antipodal
+ test_distazi_symm<P1, P2>(normlized_deg(l-45), -45, normlized_deg(l+135), 45, 20003.92, 0.0, true);
+ }
+
+ /* SQL Server gives:
+ 1116.82586908528, 0, 1336.02721932545
+
+ with:
+SELECT 0.001 * geography::STGeomFromText('POINT(0 90)', 4326).STDistance(geography::STGeomFromText('POINT(1 80)', 4326))
+union SELECT 0.001 * geography::STGeomFromText('POINT(4 52)', 4326).STDistance(geography::STGeomFromText('POINT(4 52)', 4326))
+union SELECT 0.001 * geography::STGeomFromText('POINT(4 52)', 4326).STDistance(geography::STGeomFromText('POINT(3 40)', 4326))
+ */
+
+
+ test_side<P1, P2>(0, 0, 0, 1, 0, 2, 0);
+ test_side<P1, P2>(0, 0, 0, 1, 0, -2, 0);
+ test_side<P1, P2>(10, 0, 10, 1, 10, 2, 0);
+ test_side<P1, P2>(10, 0, 10, -1, 10, 2, 0);
+
+ test_side<P1, P2>(10, 0, 10, 1, 0, 2, 1); // left
+ test_side<P1, P2>(10, 0, 10, -1, 0, 2, -1); // right
+
+ test_side<P1, P2>(-10, -10, 10, 10, 10, 0, -1); // right
+ test_side<P1, P2>(-10, -10, 10, 10, -10, 0, 1); // left
+ test_side<P1, P2>(170, -10, -170, 10, -170, 0, -1); // right
+ test_side<P1, P2>(170, -10, -170, 10, 170, 0, 1); // left
+}
+
+template <typename P>
+void test_all()
+{
+ test_all<P, P>();
+}
+
+int test_main(int, char* [])
+{
+ //test_all<float[2]>();
+ //test_all<double[2]>();
+ //test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
+ //test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
+
+#if defined(HAVE_TTMATH)
+ test_all<bg::model::point<ttmath::Big<1,4>, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<ttmath_big, 2, bg::cs::geographic<bg::degree> > >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/cross_track.cpp b/src/boost/libs/geometry/test/strategies/cross_track.cpp
new file mode 100644
index 00000000..861251e4
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/cross_track.cpp
@@ -0,0 +1,181 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/io/wkt/read.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+
+#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
+
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+
+// This test is GIS oriented.
+
+
+template <typename Point, typename LatitudePolicy>
+void test_distance(
+ typename bg::coordinate_type<Point>::type const& lon1,
+ typename bg::coordinate_type<Point>::type const& lat1,
+ typename bg::coordinate_type<Point>::type const& lon2,
+ typename bg::coordinate_type<Point>::type const& lat2,
+ typename bg::coordinate_type<Point>::type const& lon3,
+ typename bg::coordinate_type<Point>::type const& lat3,
+ typename bg::coordinate_type<Point>::type const& radius,
+ typename bg::coordinate_type<Point>::type const& expected,
+ typename bg::coordinate_type<Point>::type const& tolerance)
+{
+ typedef bg::strategy::distance::cross_track
+ <
+ typename bg::coordinate_type<Point>::type
+ > strategy_type;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ strategy_type,
+ Point,
+ Point
+ >::type return_type;
+
+
+ {
+ // compile-check if there is a strategy for this type
+ typedef typename bg::strategy::distance::services::default_strategy
+ <
+ bg::point_tag, bg::segment_tag, Point, Point
+ >::type cross_track_strategy_type;
+
+ typedef typename bg::strategy::distance::services::default_strategy
+ <
+ bg::segment_tag, bg::point_tag, Point, Point
+ >::type reversed_tags_cross_track_strategy_type;
+
+ boost::ignore_unused<cross_track_strategy_type,
+ reversed_tags_cross_track_strategy_type>();
+ }
+
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointSegmentDistanceStrategy<strategy_type, Point, Point>)
+ );
+
+
+ Point p1, p2, p3;
+ bg::assign_values(p1, lon1, LatitudePolicy::apply(lat1));
+ bg::assign_values(p2, lon2, LatitudePolicy::apply(lat2));
+ bg::assign_values(p3, lon3, LatitudePolicy::apply(lat3));
+
+
+ strategy_type strategy;
+ return_type d = strategy.apply(p1, p2, p3);
+
+ BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
+
+ // The strategy should return the same result if we reverse the parameters
+ d = strategy.apply(p1, p3, p2);
+ BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
+
+ // Test specifying radius explicitly
+ strategy_type strategy_radius(radius);
+ d = strategy_radius.apply(p1, p2, p3);
+ BOOST_CHECK_CLOSE(d, expected, tolerance);
+
+
+ // Test the "default strategy" registration
+ bg::model::referring_segment<Point const> segment(p2, p3);
+ d = bg::distance(p1, segment);
+ BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
+}
+
+
+template <typename Point>
+void test_case_boost_geometry_list_20120625()
+{
+ // This function tests the bug submitted by Karsten Ahnert
+ // on Boost.Geometry list at 2012-06-25, and wherefore he
+ // submitted a patch a few days later.
+
+ Point p1, p2;
+ bg::model::segment<Point> s1, s2;
+
+ bg::read_wkt("POINT(1 1)", p1);
+ bg::read_wkt("POINT(5 1)", p2);
+ bg::read_wkt("LINESTRING(0 2,2 2)", s1);
+ bg::read_wkt("LINESTRING(2 2,4 2)", s2);
+
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s1), 0.0174586, 0.0001);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s2), 0.0246783, 0.0001);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s1), 0.0551745, 0.0001);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s2), 0.0246783, 0.0001);
+
+ // Check degenerated segments
+ bg::model::segment<Point> s3;
+ bg::read_wkt("LINESTRING(2 2,2 2)", s3);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s3), 0.0246783, 0.0001);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s3), 0.0551745, 0.0001);
+
+ // Point/Point distance should be identical:
+ Point p3;
+ bg::read_wkt("POINT(2 2)", p3);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p1, p3), 0.0246783, 0.0001);
+ BOOST_CHECK_CLOSE(boost::geometry::distance(p2, p3), 0.0551745, 0.0001);
+}
+
+
+template <typename Point, typename LatitudePolicy>
+void test_all()
+{
+ typename bg::coordinate_type<Point>::type const average_earth_radius = 6372795.0;
+
+ // distance (Paris <-> Amsterdam/Barcelona),
+ // with coordinates rounded as below ~87 km
+ // is equal to distance (Paris <-> Barcelona/Amsterdam)
+ typename bg::coordinate_type<Point>::type const p_to_ab = 86.798321 * 1000.0;
+ test_distance<Point, LatitudePolicy>(2, 48, 4, 52, 2, 41, average_earth_radius, p_to_ab, 0.1);
+ test_distance<Point, LatitudePolicy>(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 0.1);
+
+ test_case_boost_geometry_list_20120625<Point>();
+}
+
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy >();
+
+ // NYI: haversine for mathematical spherical coordinate systems
+ // test_all<bg::model::point<double, 2, bg::cs::spherical<bg::degree> >, mathematical_policya >();
+
+#if defined(HAVE_TTMATH)
+ typedef ttmath::Big<1,4> tt;
+ //test_all<bg::model::point<tt, 2, bg::cs::geographic<bg::degree> >, geographic_policy>();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/crossings_multiply.cpp b/src/boost/libs/geometry/test/strategies/crossings_multiply.cpp
new file mode 100644
index 00000000..f57d383f
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/crossings_multiply.cpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <strategies/test_within.hpp>
+
+
+template <typename Point>
+void test_all()
+{
+ typedef bg::model::polygon<Point> polygon;
+
+ std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))";
+ std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))";
+ std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))";
+
+ bg::strategy::within::crossings_multiply<Point> s;
+
+
+ test_geometry<Point, polygon>("b1", "POINT(1 1)", box, s, true);
+ test_geometry<Point, polygon>("b2", "POINT(3 3)", box, s, false);
+
+ // Test ALL corners (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b3a", "POINT(0 0)", box, s, false);
+ test_geometry<Point, polygon>("b3b", "POINT(0 2)", box, s, false);
+ test_geometry<Point, polygon>("b3c", "POINT(2 2)", box, s, false);
+ test_geometry<Point, polygon>("b3d", "POINT(2 0)", box, s, false);
+
+ // Test ALL sides (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b4a", "POINT(0 1)", box, s, false);
+ test_geometry<Point, polygon>("b4b", "POINT(1 2)", box, s, true); // different
+ test_geometry<Point, polygon>("b4c", "POINT(2 1)", box, s, false);
+ test_geometry<Point, polygon>("b4d", "POINT(1 0)", box, s, false);
+
+
+ test_geometry<Point, polygon>("t1", "POINT(1 1)", triangle, s, true);
+ test_geometry<Point, polygon>("t2", "POINT(3 3)", triangle, s, false);
+
+ test_geometry<Point, polygon>("t3a", "POINT(0 0)", triangle, s, false);
+ test_geometry<Point, polygon>("t3b", "POINT(0 4)", triangle, s, true); // diff
+ test_geometry<Point, polygon>("t3c", "POINT(5 0)", triangle, s, false);
+
+ test_geometry<Point, polygon>("t4a", "POINT(0 2)", triangle, s, false);
+ test_geometry<Point, polygon>("t4b", "POINT(3 2)", triangle, s, false);
+ test_geometry<Point, polygon>("t4c", "POINT(2 0)", triangle, s, false);
+
+
+ test_geometry<Point, polygon>("h1", "POINT(0.5 0.5)", with_hole, s, true);
+ test_geometry<Point, polygon>("h2a", "POINT(1.5 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h2b", "POINT(5 5)", with_hole, s, false);
+
+ test_geometry<Point, polygon>("h3a", "POINT(1 1)", with_hole, s, true); // diff
+ test_geometry<Point, polygon>("h3b", "POINT(2 2)", with_hole, s, false);
+ test_geometry<Point, polygon>("h3c", "POINT(0 0)", with_hole, s, false);
+
+ test_geometry<Point, polygon>("h4a", "POINT(1 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h4b", "POINT(1.5 2)", with_hole, s, false);
+
+ // Lying ON (one of the sides of) interior ring
+ test_geometry<Point, polygon>("#77-1", "POINT(6 3.5)",
+ "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))",
+ s, false);
+}
+
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+#if defined(HAVE_TTMATH)
+ test_all<bg::model::point<ttmath_big, 2, bg::cs::cartesian> >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/distance.cpp b/src/boost/libs/geometry/test/strategies/distance.cpp
new file mode 100644
index 00000000..876e2873
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/distance.cpp
@@ -0,0 +1,117 @@
+// Boost.Geometry
+
+// Copyright (c) 2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, 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)
+
+#include <geometry_test_common.hpp>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/srs/srs.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+typedef bg::srs::spheroid<double> stype;
+
+typedef bg::strategy::andoyer andoyer_formula;
+typedef bg::strategy::thomas thomas_formula;
+typedef bg::strategy::vincenty vincenty_formula;
+
+template <typename P>
+bool non_precise_ct()
+{
+ typedef typename bg::coordinate_type<P>::type ct;
+ return boost::is_integral<ct>::value || boost::is_float<ct>::value;
+}
+
+template <typename P1, typename P2, typename FormulaPolicy>
+void test_distance(double lon1, double lat1, double lon2, double lat2)
+{
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::select_calculation_type<P1, P2, void>::type
+ >::type calc_t;
+
+ calc_t tolerance = non_precise_ct<P1>() || non_precise_ct<P2>() ?
+ 5.0 : 0.001;
+
+ P1 p1;
+ P2 p2;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+
+ // Test strategy that implements meridian distance against formula
+ // that implements general distance
+ // That may change in the future but in any case these calls must return
+ // the same result
+
+ calc_t dist_formula = FormulaPolicy::template inverse
+ <
+ double, true, false, false, false, false
+ >::apply(lon1 * bg::math::d2r<double>(),
+ lat1 * bg::math::d2r<double>(),
+ lon2 * bg::math::d2r<double>(),
+ lat2 * bg::math::d2r<double>(),
+ stype()).distance;
+
+ bg::strategy::distance::geographic<FormulaPolicy, stype> strategy;
+ calc_t dist_strategy = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(dist_formula, dist_strategy, tolerance);
+}
+
+template <typename P1, typename P2, typename FormulaPolicy>
+void test_distance_reverse(double lon1, double lat1,
+ double lon2, double lat2)
+{
+ test_distance<P1, P2, FormulaPolicy>(lon1, lat1, lon2, lat2);
+ test_distance<P1, P2, FormulaPolicy>(lon2, lat2, lon1, lat1);
+}
+
+template <typename P1, typename P2, typename FormulaPolicy>
+void test_meridian()
+{
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 0., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0, 70, 0., -80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 0., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 0., -80.);
+
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 180., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., 70., 180., -80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 180., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(0., -70., 180., -80.);
+
+ test_distance_reverse<P1, P2, FormulaPolicy>(350., 70., 170., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(350., 70., 170., -80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(350., -70., 170., 80.);
+ test_distance_reverse<P1, P2, FormulaPolicy>(350., -70., 170., -80.);
+}
+
+template <typename P>
+void test_all()
+{
+ test_meridian<P, P, andoyer_formula>();
+ test_meridian<P, P, thomas_formula>();
+ test_meridian<P, P, vincenty_formula>();
+}
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/distance_cross_track.cpp b/src/boost/libs/geometry/test/strategies/distance_cross_track.cpp
new file mode 100644
index 00000000..3ec098c8
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/distance_cross_track.cpp
@@ -0,0 +1,116 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2019 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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 <sstream>
+
+#include "../formulas/test_formula.hpp"
+#include "distance_cross_track_cases.hpp"
+
+#include <boost/geometry/strategies/strategies.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+
+struct error{
+ double long_distance;
+ double short_distance;
+ double very_short_distance;
+ double very_very_short_distance;
+};
+
+void check_result(double const& result, double const& expected,
+ double const& reference, error const& reference_error)
+{
+ BOOST_GEOMETRY_CHECK_CLOSE(result, expected, 0.1,
+ std::setprecision(20) << "result {" << result
+ << "} different than expected {" << expected << "}.");
+
+ double reference_error_value = result > 2000 ? reference_error.long_distance
+ : result > 100 ? reference_error.short_distance
+ : result > 20 ? reference_error.very_short_distance
+ : reference_error.very_very_short_distance;
+
+ BOOST_GEOMETRY_CHECK_CLOSE(result, reference, reference_error_value,
+ std::setprecision(20) << "result {" << result
+ << "} different than reference {"
+ << reference << "}.");
+}
+
+template <typename Point>
+void test_all(expected_results const& results)
+{
+ double const d2r = bg::math::d2r<double>();
+
+ double lon1r = results.p1.lon * d2r;
+ double lat1r = results.p1.lat * d2r;
+ double lon2r = results.p2.lon * d2r;
+ double lat2r = results.p2.lat * d2r;
+ double lon3r = results.p3.lon * d2r;
+ double lat3r = results.p3.lat * d2r;
+
+ typedef bg::srs::spheroid<double> Spheroid;
+
+ // WGS84
+ Spheroid spheroid(6378137.0, 6356752.3142451793);
+
+ error errors [] =
+ {
+ {0.00000001, 0.00000001, 0.00000001, 0.000001}, //vincenty
+ {0.0002, 0.002, 0.01, 0.2}, //thomas
+ {0.002, 0.4, 15, 25}, //andoyer
+ {1, 6, 15, 200} //spherical
+ };
+
+ //vincenty
+ double distance = bg::strategy::distance::detail::geographic_cross_track<bg::strategy::vincenty, Spheroid, double, true>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.vincenty_bisection, results.reference, errors[0]);
+
+ distance = bg::strategy::distance::geographic_cross_track<bg::strategy::vincenty, Spheroid, double>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.vincenty, results.reference, errors[0]);
+
+ //thomas
+ distance = bg::strategy::distance::detail::geographic_cross_track<bg::strategy::thomas, Spheroid, double, true>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.thomas_bisection, results.reference, errors[1]);
+
+ distance = bg::strategy::distance::geographic_cross_track<bg::strategy::thomas, Spheroid, double>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.thomas, results.reference, errors[1]);
+
+ //andoyer
+ distance = bg::strategy::distance::detail::geographic_cross_track<bg::strategy::andoyer, Spheroid, double, true>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.andoyer_bisection, results.reference, errors[2]);
+
+ distance = bg::strategy::distance::geographic_cross_track<bg::strategy::andoyer, Spheroid, double>(spheroid)
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.andoyer, results.reference, errors[2]);
+
+ //spherical
+ distance = bg::strategy::distance::cross_track<>(bg::formula::mean_radius<double>(spheroid))
+ .apply(Point(lon3r, lat3r), Point(lon1r, lat1r), Point(lon2r, lat2r));
+ check_result(distance, results.spherical, results.reference, errors[3]);
+
+}
+
+int test_main(int, char*[])
+{
+ typedef bg::model::point<double, 2, bg::cs::geographic<bg::radian> > point;
+
+ for (size_t i = 0; i < expected_size; ++i)
+ {
+ test_all<point>(expected[i]);
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/distance_cross_track_cases.hpp b/src/boost/libs/geometry/test/strategies/distance_cross_track_cases.hpp
new file mode 100644
index 00000000..01cf2a12
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/distance_cross_track_cases.hpp
@@ -0,0 +1,518 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2019 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, 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)
+
+#ifndef BOOST_GEOMETRY_TEST_DISTANCE_CROSS_TRACK_CASES_HPP
+#define BOOST_GEOMETRY_TEST_DISTANCE_CROSS_TRACK_CASES_HPP
+
+struct coordinates
+{
+ double lon;
+ double lat;
+};
+
+struct expected_results
+{
+ coordinates p1; //1st point of segment
+ coordinates p2; //2nd point of segment
+ coordinates p3; //point to compute distance from segment
+ double reference; // karney or vincenty
+ double vincenty_bisection;
+ double vincenty;
+ double thomas_bisection;
+ double thomas;
+ double andoyer_bisection;
+ double andoyer;
+ double spherical;
+};
+
+expected_results expected[] =
+{
+ {
+ { 0, 0 },{ 1, 1 },{ 0, 1 },
+ 78442.119873761606868,
+ 78442.119873761606868,
+ 78442.119873761592316,
+ 78442.118218914125464,
+ 78442.118218840550981,
+ 78440.792929481409374,
+ 78440.792934224984492,
+ 78618.810427426869865
+ } , {
+ { 0, 0 },{ 1, 1 },{ 1, 0 },
+ 78453.98942845336569,
+ 78453.98942845336569,
+ 78453.98942845336569,
+ 78453.990728736869642,
+ 78453.990728682110785,
+ 78453.54172924211889,
+ 78453.541733992169611,
+ 78630.786885094828904
+ } , {
+ { 10, 15 },{ 30, 15 },{ 15, 80 },
+ 7204174.4886689241976,
+ 7204174.4886689241976,
+ 7204174.4886689241976,
+ 7204174.4785777237266,
+ 7204174.4785777227953,
+ 7204194.9162934627384,
+ 7204194.9162937803194,
+ 7205729.8545973757282
+ } , {
+ { 10, 15 },{ 30, 15 },{ 15, 10 },
+ 571412.78107940487098,
+ 571412.78107940487098,
+ 571412.78107940475456,
+ 571412.77996722259559,
+ 571412.77996722620446,
+ 571408.51759251800831,
+ 571408.51759251928888,
+ 574226.66911869682372
+ } , {
+ { 10, 15 },{ 30, 15 },{ 5, 10 },
+ 775316.40275838342495,
+ 775316.40275838342495,
+ 775316.40275838342495,
+ 775316.40098149504047,
+ 775316.40098149504047,
+ 775309.55307898123283,
+ 775309.55307898123283,
+ 776861.2271022957284
+ } , {
+ { 10, 15 },{ 30, 15 },{ 35, 10 },
+ 775316.40275838342495,
+ 775316.40275838342495,
+ 775316.40275838342495,
+ 775316.40098149504047,
+ 775316.40098149504047,
+ 775309.55307898123283,
+ 775309.55307898123283,
+ 776861.22710229584482
+ } , {
+ { 2, 2 },{ 3, 2 },{ 3.5, 3 },
+ 123770.82713049851009,
+ 123770.82713049851009,
+ 123770.82713049851009,
+ 123770.82682863833907,
+ 123770.82682863833907,
+ 123769.27773668900772,
+ 123769.27773668900772,
+ 124295.90554402528505
+ } , {
+ { 2, 2 },{ 3, 2 },{ 1.5, 3 },
+ 123770.82713049851009,
+ 123770.82713049851009,
+ 123770.82713049851009,
+ 123770.82682863833907,
+ 123770.82682863833907,
+ 123769.27773668900772,
+ 123769.27773668900772,
+ 124295.90554402528505
+ } , {
+ { 2, 2 },{ 3, 2 },{ 2, 3 },
+ 110576.41139532231318,
+ 110576.41139532231318,
+ 110576.41139532238594,
+ 110576.41139116862905,
+ 110576.41139118297724,
+ 110575.1780244907568,
+ 110575.17802451056195,
+ 111195.07457694716868
+ } , {
+ { 2, 2 },{ 3, 2 },{ 3, 3 },
+ 110576.41139532234229,
+ 110576.41139532234229,
+ 110576.41139532234229,
+ 110576.41139242639474,
+ 110576.41139243228827,
+ 110575.17802478378871,
+ 110575.17802474705968,
+ 111195.07457694721234
+ } , {
+ { 2, 2 },{ 3, 2 },{ 3.5, 1 },
+ 123784.75399867084343,
+ 123784.75399867084343,
+ 123784.75399867084343,
+ 123784.75369734384003,
+ 123784.75369734384003,
+ 123783.19294134904339,
+ 123783.19294134904339,
+ 124311.043335600305
+ } , {
+ { 2, 2 },{ 3, 2 },{ 1.5, 1 },
+ 123784.75399867084343,
+ 123784.75399867084343,
+ 123784.75399867084343,
+ 123784.75369734384003,
+ 123784.75369734384003,
+ 123783.19294134904339,
+ 123783.19294134904339,
+ 124311.043335600305
+ } , {
+ { 2, 2 },{ 3, 2 },{ 2, 1 },
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06688667042181,
+ 110575.06688667042181,
+ 110573.82008001199574,
+ 110573.82008001199574,
+ 111195.07973463158123
+ } , {
+ { 2, 2 },{ 3, 2 },{ 3, 1 },
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06688667042181,
+ 110575.06688667042181,
+ 110573.82008001199574,
+ 110573.82008001199574,
+ 111195.07973463158123
+ } , {
+ { 2, -2 },{ 3, -2 },{ 3, -1 },
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06688667042181,
+ 110575.06688667042181,
+ 110573.82008001199574,
+ 110573.82008001199574,
+ 111195.07973463158123
+ } , {
+ { 220, 2 },{ 3, 2 },{ 3, 1 },
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06688667042181,
+ 110575.06688667042181,
+ 110573.82008001199574,
+ 110573.82008001199574,
+ 111195.07973463158123
+ } , //antimeridian
+ {
+ { 220, 2 },{ 3, 2 },{ 220, 1 },
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06481432798319,
+ 110575.06688667042181,
+ 110575.06688667042181,
+ 110573.82008001199574,
+ 110573.82008001199574,
+ 111195.07973463158123
+ } , //meridian
+ {
+ { 2, 2 },{ 2, 4 },{ 2.5, 2 },
+ 55626.064900081859,
+ 55626.064900081859,
+ 55626.064900081867,
+ 55626.06490013907,
+ 55626.064900107223,
+ 55626.065279513903,
+ 55626.065279463517,
+ 55563.670489238102
+ } , {
+ { 2, 2 },{ 2, 4 },{ 2.5, 5 },
+ 123722.15822285149,
+ 123722.15822285149,
+ 123722.15822285149,
+ 123722.15791917888,
+ 123722.15791917888,
+ 123720.64936755209,
+ 123720.64936755209,
+ 124243.00560435352
+ } , {
+ { 2, 2 },{ 2, 4 },{ 2.5, 3 },
+ 55583.973320908837,
+ 55583.973320908837,
+ 55583.97332090883,
+ 55583.973320941128,
+ 55583.973320900877,
+ 55583.97416950998,
+ 55583.974169663285,
+ 55521.343440931159
+ } , {
+ { 0, 40 },{ 180, 80 },{ 0, 20 },
+ 2217162.7761786841,
+ 2217162.7761786841,
+ 2217162.7761786841,
+ 2217162.7361901053,
+ 2217162.7361901053,
+ 2217171.9891410829,
+ 2217171.9891410829,
+ 2223901.5946926316
+ } , {
+ { 0, 40 },{ 0, 80 },{ 0, 20 },
+ 2217162.7761786841,
+ 2217162.7761786841,
+ 2217162.7761786841,
+ 2217162.7361901053,
+ 2217162.7361901053,
+ 2217171.9891410829,
+ 2217171.9891410829,
+ 2223901.5946926316
+ } , {
+ { 0, 0 },{ 0, 90 },{ 0, 80 },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ } , {
+ { 0, 0 },{ 0, 90 },{ 1, 80 },
+ 19392.530629092114,
+ 19392.530629092114,
+ 19392.530629092107,
+ 19392.53062953979,
+ 19392.530629094777,
+ 19392.328788289116,
+ 19392.328788113067,
+ 19307.872231041671
+ } , {
+ { 1, -1 }, { 1, 0 },{ 2, 0 },
+ 111319.4907932264,
+ 111319.4907932264,
+ 111319.4907932264,
+ 111319.49079334327,
+ 111319.49079326246,
+ 111319.49079326226,
+ 111319.49079326246,
+ 111195.07973463158
+ } , //equator
+ {
+ { 2, 0 },{ 3, 0 },{ 0, 0 },
+ 222638.98158645280637,
+ 222638.98158645280637,
+ 222638.98158645280637,
+ 222638.98158654122381,
+ 222638.98158654122381,
+ 222638.98158654125291,
+ 222638.98158654125291,
+ 222390.15946926316246
+ } , {
+ { 2, 0 },{ 3, 0 },{ 2.5, 3 },
+ 331725.86989626317518,
+ 331725.86989626317518,
+ 331725.86989626317518,
+ 331725.87608870770782,
+ 331725.87608870770782,
+ 331722.14136137196328,
+ 331722.14136137196328,
+ 333585.2392038948019
+ } , {
+ { 2, 0 },{ 3, 0 },{ 2, 0 },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ } , {
+ { 2, 0 },{ 3, 0 },{ 3, 0 },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ } , {
+ { 2, 0 },{ 3, 0 },{ 2.5, 0 },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ } , {
+ { 2, 0 },{ 3, 0 },{ 3.5, 3 },
+ 336358.80734967370518,
+ 336358.80734967370518,
+ 336358.80734967370518,
+ 336358.80718013871228,
+ 336358.80718013871228,
+ 336354.9292840428534,
+ 336354.9292840428534,
+ 338182.45508443051949
+ } , //segment pass by pole
+/* those cases have expected very large reference errors for spherical
+ * {
+ { 0, 0 },{ 180, 0 },{ 0, 90 },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 10007557.176116843
+ } , {
+ { 0, 0 },{ 180, 0 },{ 80, 89 },
+ 109996.81571864839,
+ 109996.81571864839,
+ 109996.81571864836,
+ 109996.81571864968,
+ 109996.81571858823,
+ 109995.58014976831,
+ 109995.58014972134,
+ 9896362.096382184,
+ }*/ // short distance to segment
+ {
+ { 0.5, 0 },{ 175.5, 0 },{ 90, 1e-3 },
+ 110.57427582169922,
+ 110.57427582169922,
+ 110.57427582169922,
+ 110.57427792305019,
+ 110.57427792305019,
+ 110.57302444153535,
+ 110.57302444153535,
+ 111.19507973475258
+ } , {
+ { 0.5, 0 },{ 175.5, 0 },{ 90, 1e-8 },
+ 0.0011057427582158647,
+ 0.0011057427582158647,
+ 0.0011057427582158647,
+ 0.0011057427792293744,
+ 0.0011057427792293744,
+ 0.0011057302444142166,
+ 0.0011057302444142166,
+ 0.0011119503057618657
+ } , {
+ // mysql Bug #29545865
+ { -16.42203, -7.52882 },{ 4.89998, -6.15568 },{ 3.32696, -6.29345 },
+ 481.73908764883043,
+ 481.73908764883043,
+ 481.73908764873721,
+ 481.74578258317035,
+ 481.74576160418479,
+ 480.34603374821353,
+ 480.34602624448405,
+ 508.0731159303939
+ } , { // same segment but the point is from the other side
+ { -16.42203, -7.52882 },{ 4.89998, -6.15568 },{ 3.3262, -6.28451},
+ 510.48273138899611,
+ 510.48273138899611,
+ 510.48273138908797,
+ 510.47605556026537,
+ 510.47605888246693,
+ 511.86547773473234,
+ 511.86548088955459,
+ 489.55321195417821
+ } , {
+ { -16.42203, -7.52882 },{ 4.89998, -6.1556 },{ 3.32696, -6.2889 },
+ 11.511229576046485,
+ 11.511229576046485,
+ 11.51122957617916,
+ 11.50474785537202,
+ 11.504394870933424,
+ 12.898977232559222,
+ 12.898968261046516,
+ 12.130727461169611
+ } , {
+ { -16.42203, -7.52882 },{ 4.89998, -6.1556 },{ 3.32696, -6.28895 },
+ 6.0009073659133909,
+ 6.0009073659133909,
+ 6.0009073659387502,
+ 5.9949823734311893,
+ 5.9941706378723278,
+ 7.3883629173067344,
+ 7.3889362323779535,
+ 17.671122161310702
+ } , {
+ // mysql Bug #29545865
+ //{ 8.65279, -2.71668 },
+ { -7.13372, 8.35583 },{ -9.09998, -1.22625 },{ -7.35561, 7.2137 },
+ 1671.2894143458557,
+ 1671.2894143458557,
+ 1671.2894143458786,
+ 1671.2962894596874,
+ 1671.296284713379,
+ 1677.2323385335374,
+ 1677.232338307874,
+ 1668.697566121507
+ }
+#ifdef GEOMETRY_TEST_INCLUDE_FAILING_TESTS
+ , {
+ { 0, 10 }, { 20, 10 }, { 18.00000000000003908, 10.054676080707787733 },
+ 0.0011398027228318023,
+ 0.0011398027228318023,
+ 0.0060057460922939617,
+ 0,
+ 0,
+ 0,
+ 0.30055333992381872,
+ 39.88666722147299
+ } , {
+ { 0, 10 }, { 20, 10 }, { 18, 10.054678231628329854 },
+ 0.23669789852514209,
+ 0.23669789852514209,
+ 0.23669789883426567,
+ 0.25069019912476698,
+ 0.23204712322540744,
+ 0.26712030782599411,
+ 0.40206187237490559,
+ 40.125767043637062
+ } , {
+ { 0, 10 }, { 20, 10 },{ 17.999999999999950262, 10.054676091041047314 },
+ 2.7930744094407741e-06,
+ 2.7930744094407741e-06,
+ 0.0058967770186943418,
+ 0,
+ 0,
+ 0,
+ 0.30055160527904862,
+ 39.887815883329125
+ }
+#endif
+ , // large distance to segment
+ {
+ { 0.5, 0 }, { 175.5, 0 }, { 90, 90 },
+ 10001965.729311479,
+ 10001965.729311479,
+ 10001965.729311479,
+ 10001965.729311479,
+ 10001965.729311479,
+ 10001958.678477952,
+ 10001958.678477952,
+ 10007557.108987356
+ } , {
+ { 0.5, -89 }, { 175.5, -89 }, { 90, 90 },
+ 19892237.59370932,
+ 19892237.59370932,
+ 19892237.59370932,
+ 19892237.570068691,
+ 19892237.570068691,
+ 19892224.746673118,
+ 19892224.746673118,
+ 19903919.272499084
+ } , //acos issue solved
+ {
+ { 90, 0 }, { 0, 1.000005 }, {0, 90},
+ 9891389.2448064201,
+ 9891389.2448064201,
+ 9891389.2448064163,
+ 9891370.4775929395,
+ 9891370.4775932431,
+ 9891383.4444574378,
+ 9891383.4444574378,
+ 9896361.5404068138
+ }
+};
+
+size_t const expected_size = sizeof(expected) / sizeof(expected_results);
+
+#endif // BOOST_GEOMETRY_TEST_DISTANCE_CROSS_TRACK_CASES_HPP
diff --git a/src/boost/libs/geometry/test/strategies/distance_default_result.cpp b/src/boost/libs/geometry/test/strategies/distance_default_result.cpp
new file mode 100644
index 00000000..e862d331
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/distance_default_result.cpp
@@ -0,0 +1,270 @@
+// 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_default_result
+#endif
+
+#include <cstddef>
+#include <iostream>
+
+#include <boost/test/included/unit_test.hpp>
+
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <boost/geometry/util/calculation_type.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/box.hpp>
+
+#include <boost/geometry/strategies/strategies.hpp>
+#include <boost/geometry/strategies/default_distance_result.hpp>
+#include <boost/geometry/strategies/default_comparable_distance_result.hpp>
+
+#if defined(HAVE_TTMATH)
+#include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+namespace bg = ::boost::geometry;
+
+
+template <typename DefaultResult, typename ExpectedResult>
+struct assert_equal_types
+{
+ assert_equal_types()
+ {
+ static const bool are_same =
+ boost::is_same<DefaultResult, ExpectedResult>::type::value;
+
+ BOOST_MPL_ASSERT_MSG((are_same),
+ WRONG_DEFAULT_DISTANCE_RESULT,
+ (types<DefaultResult, ExpectedResult>));
+ }
+};
+
+//=========================================================================
+
+template
+<
+ typename Geometry1,
+ typename Geometry2,
+ typename ExpectedResult,
+ typename ExpectedComparableResult
+>
+inline void test_distance_result()
+{
+ typedef typename bg::default_distance_result
+ <
+ Geometry1, Geometry2
+ >::type result12;
+
+ typedef typename bg::default_distance_result
+ <
+ Geometry2, Geometry1
+ >::type result21;
+
+ typedef typename bg::default_comparable_distance_result
+ <
+ Geometry1, Geometry2
+ >::type comparable_result12;
+
+ typedef typename bg::default_comparable_distance_result
+ <
+ Geometry2, Geometry1
+ >::type comparable_result21;
+
+ assert_equal_types<result12, ExpectedResult>();
+ assert_equal_types<result21, ExpectedResult>();
+ assert_equal_types<comparable_result12, ExpectedComparableResult>();
+ assert_equal_types<comparable_result21, ExpectedComparableResult>();
+}
+
+//=========================================================================
+
+template
+<
+ typename CoordinateType1,
+ typename CoordinateType2,
+ std::size_t Dimension,
+ typename CoordinateSystem,
+ typename ExpectedResult,
+ typename ExpectedComparableResult = ExpectedResult
+>
+struct test_distance_result_segment
+{
+ test_distance_result_segment()
+ {
+ typedef typename bg::model::point
+ <
+ CoordinateType1, Dimension, CoordinateSystem
+ > point1;
+
+ typedef typename bg::model::point
+ <
+ CoordinateType2, Dimension, CoordinateSystem
+ > point2;
+
+ typedef typename bg::model::segment<point1> segment1;
+ typedef typename bg::model::segment<point2> segment2;
+
+ test_distance_result
+ <
+ point1, point2, ExpectedResult, ExpectedComparableResult
+ >();
+
+ test_distance_result
+ <
+ point1, segment2, ExpectedResult, ExpectedComparableResult
+ >();
+
+ test_distance_result
+ <
+ point2, segment1, ExpectedResult, ExpectedComparableResult
+ >();
+ }
+};
+
+//=========================================================================
+
+template
+<
+ typename CoordinateType1,
+ typename CoordinateType2,
+ std::size_t Dimension,
+ typename ExpectedResult,
+ typename ExpectedComparableResult = ExpectedResult
+>
+struct test_distance_result_box
+{
+ test_distance_result_box()
+ {
+ typedef typename bg::model::point
+ <
+ CoordinateType1, Dimension, bg::cs::cartesian
+ > point1;
+
+ typedef typename bg::model::point
+ <
+ CoordinateType2, Dimension, bg::cs::cartesian
+ > point2;
+
+ typedef typename bg::model::box<point1> box1;
+ typedef typename bg::model::box<point2> box2;
+
+ test_distance_result
+ <
+ point1, box2, ExpectedResult, ExpectedComparableResult
+ >();
+
+ test_distance_result
+ <
+ point2, box1, ExpectedResult, ExpectedComparableResult
+ >();
+
+ test_distance_result
+ <
+ box1, box2, ExpectedResult, ExpectedComparableResult
+ >();
+ }
+};
+
+//=========================================================================
+
+template <std::size_t D, typename CoordinateSystem>
+inline void test_segment_all()
+{
+#if defined(HAVE_TTMATH)
+ typedef ttmath_big tt;
+ typedef bg::util::detail::default_integral::type default_integral;
+#endif
+ typedef typename boost::mpl::if_
+ <
+ typename boost::is_same<CoordinateSystem, bg::cs::cartesian>::type,
+ double,
+ float
+ >::type float_return_type;
+
+ test_distance_result_segment<short, short, D, CoordinateSystem, double>();
+ test_distance_result_segment<int, int, D, CoordinateSystem, double>();
+ test_distance_result_segment<int, long, D, CoordinateSystem, double>();
+ test_distance_result_segment<long, long, D, CoordinateSystem, double>();
+
+ test_distance_result_segment<int, float, D, CoordinateSystem, float_return_type>();
+ test_distance_result_segment<float, float, D, CoordinateSystem, float_return_type>();
+
+ test_distance_result_segment<int, double, D, CoordinateSystem, double>();
+ test_distance_result_segment<double, int, D, CoordinateSystem, double>();
+ test_distance_result_segment<float, double, D, CoordinateSystem, double>();
+ test_distance_result_segment<double, float, D, CoordinateSystem, double>();
+ test_distance_result_segment<double, double, D, CoordinateSystem, double>();
+
+#if defined(HAVE_TTMATH)
+ test_distance_result_segment<tt, int, D, CoordinateSystem, tt>();
+ test_distance_result_segment<tt, default_integral, D, CoordinateSystem, tt>();
+
+ test_distance_result_segment<tt, float, D, CoordinateSystem, tt>();
+ test_distance_result_segment<tt, double, D, CoordinateSystem, tt>();
+ test_distance_result_segment<tt, tt, D, CoordinateSystem, tt>();
+#endif
+}
+
+//=========================================================================
+
+template <std::size_t D>
+inline void test_box_all()
+{
+#if defined(HAVE_TTMATH)
+ typedef ttmath_big tt;
+#endif
+ typedef bg::util::detail::default_integral::type default_integral;
+
+ test_distance_result_box<short, short, D, double, default_integral>();
+ test_distance_result_box<int, int, D, double, default_integral>();
+ test_distance_result_box<int, long, D, double, default_integral>();
+ test_distance_result_box<long, long, D, double, default_integral>();
+
+ test_distance_result_box<int, float, D, double>();
+ test_distance_result_box<float, float, D, double>();
+
+ test_distance_result_box<int, double, D, double>();
+ test_distance_result_box<double, int, D, double>();
+ test_distance_result_box<float, double, D, double>();
+ test_distance_result_box<double, float, D, double>();
+ test_distance_result_box<double, double, D, double>();
+
+#if defined(HAVE_TTMATH)
+ test_distance_result_box<tt, int, D, tt>();
+ test_distance_result_box<tt, default_integral, D, tt>();
+
+ test_distance_result_box<tt, float, D, tt>();
+ test_distance_result_box<tt, double, D, tt>();
+ test_distance_result_box<tt, tt, D, tt>();
+#endif
+}
+
+//=========================================================================
+
+BOOST_AUTO_TEST_CASE( test_point_point_or_point_segment )
+{
+ test_segment_all<2, bg::cs::cartesian>();
+ test_segment_all<3, bg::cs::cartesian>();
+ test_segment_all<4, bg::cs::cartesian>();
+ test_segment_all<2, bg::cs::spherical_equatorial<bg::degree> >();
+}
+
+BOOST_AUTO_TEST_CASE( test_point_box_or_box )
+{
+ test_box_all<2>();
+ test_box_all<3>();
+ test_box_all<4>();
+}
diff --git a/src/boost/libs/geometry/test/strategies/douglas_peucker.cpp b/src/boost/libs/geometry/test/strategies/douglas_peucker.cpp
new file mode 100644
index 00000000..7f9e77f2
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/douglas_peucker.cpp
@@ -0,0 +1,422 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2015, 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_douglas_peucker
+#endif
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+#ifndef BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
+#define BOOST_GEOMETRY_DEBUG_DOUGLAS_PEUCKER
+#endif
+#endif
+
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <string>
+
+#include <boost/test/included/unit_test.hpp>
+
+#include <boost/geometry/core/point_type.hpp>
+#include <boost/geometry/core/tags.hpp>
+
+#include <boost/geometry/strategies/distance.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+
+#include <boost/geometry/geometries/geometries.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+#include <boost/geometry/geometries/register/multi_point.hpp>
+
+#include <boost/geometry/algorithms/comparable_distance.hpp>
+#include <boost/geometry/algorithms/equals.hpp>
+
+#include <boost/geometry/io/wkt/wkt.hpp>
+#include <boost/geometry/io/dsv/write.hpp>
+
+#include <boost/assign/list_of.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/tuple/tuple.hpp>
+
+
+namespace bg = ::boost::geometry;
+namespace ba = ::boost::assign;
+namespace services = bg::strategy::distance::services;
+
+typedef boost::tuple<double, double> tuple_point_type;
+typedef std::vector<tuple_point_type> tuple_multi_point_type;
+
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_MULTI_POINT(tuple_multi_point_type)
+BOOST_GEOMETRY_REGISTER_MULTI_POINT_TEMPLATED(std::vector)
+
+typedef bg::strategy::distance::projected_point<> distance_strategy_type;
+typedef bg::strategy::distance::projected_point
+ <
+ void, bg::strategy::distance::comparable::pythagoras<>
+ > comparable_distance_strategy_type;
+
+
+template <typename CoordinateType>
+struct default_simplify_strategy
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef typename bg::strategy::distance::services::default_strategy
+ <
+ bg::point_tag, bg::segment_tag, point_type
+ >::type default_distance_strategy_type;
+
+ typedef bg::strategy::simplify::douglas_peucker
+ <
+ point_type, default_distance_strategy_type
+ > type;
+};
+
+
+template <typename CoordinateType>
+struct simplify_regular_distance_strategy
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::strategy::simplify::douglas_peucker
+ <
+ point_type, distance_strategy_type
+ > type;
+};
+
+template <typename CoordinateType>
+struct simplify_comparable_distance_strategy
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::strategy::simplify::douglas_peucker
+ <
+ point_type, comparable_distance_strategy_type
+ > type;
+};
+
+
+
+template <typename Geometry>
+inline Geometry from_wkt(std::string const& wkt)
+{
+ Geometry geometry;
+ boost::geometry::read_wkt(wkt, geometry);
+ return geometry;
+}
+
+template <typename Iterator>
+inline std::ostream& print_point_range(std::ostream& os,
+ Iterator first,
+ Iterator beyond,
+ std::string const& header)
+{
+ os << header << "(";
+ for (Iterator it = first; it != beyond; ++it)
+ {
+ os << " " << bg::dsv(*it);
+ }
+ os << " )";
+ return os;
+}
+
+
+struct equals
+{
+ template <typename Iterator1, typename Iterator2>
+ static inline bool apply(Iterator1 begin1, Iterator1 end1,
+ Iterator2 begin2, Iterator2 end2)
+ {
+ std::size_t num_points1 = std::distance(begin1, end1);
+ std::size_t num_points2 = std::distance(begin2, end2);
+
+ if ( num_points1 != num_points2 )
+ {
+ return false;
+ }
+
+ Iterator1 it1 = begin1;
+ Iterator2 it2 = begin2;
+ for (; it1 != end1; ++it1, ++it2)
+ {
+ if ( !bg::equals(*it1, *it2) )
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ template <typename Range1, typename Range2>
+ static inline bool apply(Range1 const& range1, Range2 const& range2)
+ {
+ return apply(boost::begin(range1), boost::end(range1),
+ boost::begin(range2), boost::end(range2));
+ }
+};
+
+
+
+
+template <typename Geometry>
+struct test_one_case
+{
+ template <typename Strategy, typename Range>
+ static inline void apply(std::string const& case_id,
+ std::string const& wkt,
+ double max_distance,
+ Strategy const& strategy,
+ Range const& expected_result)
+ {
+ typedef typename bg::point_type<Geometry>::type point_type;
+ std::vector<point_type> result;
+
+ Geometry geometry = from_wkt<Geometry>(wkt);
+
+ std::string typeid_name
+ = typeid(typename bg::coordinate_type<point_type>::type).name();
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << case_id << " - " << typeid_name
+ << std::endl;
+ std::cout << wkt << std::endl;
+#endif
+
+ strategy.apply(geometry, std::back_inserter(result), max_distance);
+
+ boost::ignore_unused(strategy);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ print_point_range(std::cout, boost::begin(result), boost::end(result),
+ "output: ");
+ std::cout << std::endl << std::endl;
+#endif
+ std::stringstream stream_expected;
+ print_point_range(stream_expected, boost::begin(expected_result),
+ boost::end(expected_result),
+ "");
+ std::stringstream stream_detected;
+ print_point_range(stream_detected, boost::begin(result),
+ boost::end(result),
+ "");
+
+ BOOST_CHECK_MESSAGE(equals::apply(result, expected_result),
+ "case id: " << case_id << " - " << typeid_name
+ << ", geometry: " << wkt
+ << ", Expected: " << stream_expected.str()
+ << " - Detected: " << stream_detected.str());
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << "---------------" << std::endl;
+ std::cout << "---------------" << std::endl;
+ std::cout << std::endl << std::endl;
+#endif
+ }
+};
+
+
+template <typename CoordinateType, typename Strategy>
+inline void test_with_strategy(std::string label)
+{
+ std::cout.precision(20);
+ Strategy strategy;
+
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::model::linestring<point_type> linestring_type;
+ typedef bg::model::segment<point_type> segment_type;
+ typedef test_one_case<linestring_type> tester;
+
+ label = " (" + label + ")";
+
+ {
+ point_type const p1(-6,-13), p2(0,-15);
+ segment_type const s(point_type(12,-3), point_type(-12,5));
+
+ if (bg::comparable_distance(p1, s) >= bg::comparable_distance(p2, s))
+ {
+ tester::apply("l01c1" + label,
+ "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)",
+ 10,
+ strategy,
+ ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-12,5)
+ );
+ }
+ else
+ {
+ tester::apply("l01c2" + label,
+ "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -15,-12 5)",
+ 10,
+ strategy,
+ ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-9,4)(0,-15)(-12,5)
+ );
+ }
+ }
+
+ tester::apply("l02" + label,
+ "LINESTRING(-6 -13,-9 4,0 -15,-12 5)",
+ 10,
+ strategy,
+ ba::tuple_list_of(-6,-13)(-12,5)
+ );
+
+ tester::apply("l03" + label,
+ "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)",
+ 10,
+ strategy,
+ ba::tuple_list_of(12,-3)(4,8)(-6,-13)(-12,5)
+ );
+
+ tester::apply("l04" + label,
+ "LINESTRING(12 -3, 4 8,-6 -13,-9 4,0 -14,-12 5)",
+ 14,
+ strategy,
+ ba::tuple_list_of(12,-3)(-6,-13)(-12,5)
+ );
+
+ {
+ segment_type const s(point_type(0,-1), point_type(5,-4));
+ point_type const p1(5,-1), p2(0,-4);
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ bool d_larger_first = (bg::distance(p1, s) > bg::distance(p2, s));
+ bool d_larger_second = (bg::distance(p1, s) < bg::distance(p2, s));
+ bool cd_larger_first
+ = (bg::comparable_distance(p1, s) > bg::comparable_distance(p2, s));
+ bool cd_larger_second
+ = (bg::comparable_distance(p1, s) < bg::comparable_distance(p2, s));
+
+ std::cout << "segment: " << bg::dsv(s) << std::endl;
+ std::cout << "distance from " << bg::dsv(p1) << ": "
+ << bg::distance(p1, s) << std::endl;
+ std::cout << "comp. distance from " << bg::dsv(p1) << ": "
+ << bg::comparable_distance(p1, s) << std::endl;
+ std::cout << "distance from " << bg::dsv(p2) << ": "
+ << bg::distance(p2, s) << std::endl;
+ std::cout << "comp. distance from " << bg::dsv(p2) << ": "
+ << bg::comparable_distance(p2, s) << std::endl;
+ std::cout << "larger distance from "
+ << (d_larger_first ? "first" : (d_larger_second ? "second" : "equal"))
+ << std::endl;
+ std::cout << "larger comp. distance from "
+ << (cd_larger_first ? "first" : (cd_larger_second ? "second" : "equal"))
+ << std::endl;
+ std::cout << "difference of distances: "
+ << (bg::distance(p1, s) - bg::distance(p2, s))
+ << std::endl;
+ std::cout << "difference of comp. distances: "
+ << (bg::comparable_distance(p1, s) - bg::comparable_distance(p2, s))
+ << std::endl;
+#endif
+
+ std::string wkt =
+ "LINESTRING(0 0,5 0,0 -1,5 -1,0 -2,5 -2,0 -3,5 -3,0 -4,5 -4,0 0)";
+
+ if (bg::comparable_distance(p1, s) >= bg::comparable_distance(p2, s))
+ {
+ tester::apply("l05c1" + label,
+ wkt,
+ 1,
+ strategy,
+ ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-2)(0,-3)(5,-4)(0,0)
+ );
+ tester::apply("l05c1a" + label,
+ wkt,
+ 2,
+ strategy,
+ ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-4)(0,0)
+ );
+ }
+ else
+ {
+ tester::apply("l05c2" + label,
+ wkt,
+ 1,
+ strategy,
+ ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-2)(5,-2)(0,-4)(5,-4)(0,0)
+ );
+ tester::apply("l05c2a" + label,
+ wkt,
+ 2,
+ strategy,
+ ba::tuple_list_of(0,0)(5,0)(0,-1)(5,-1)(0,-4)(5,-4)(0,0)
+ );
+ }
+ }
+
+#ifdef BOOST_GEOMETRY_TEST_DEBUG
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << "*************************************************";
+ std::cout << std::endl;
+ std::cout << std::endl;
+#endif
+}
+
+
+BOOST_AUTO_TEST_CASE( test_default_strategy )
+{
+ test_with_strategy<int, default_simplify_strategy<int>::type>("i");
+ test_with_strategy<float, default_simplify_strategy<float>::type>("f");
+ test_with_strategy<double, default_simplify_strategy<double>::type>("d");
+ test_with_strategy
+ <
+ long double,
+ default_simplify_strategy<long double>::type
+ >("ld");
+}
+
+BOOST_AUTO_TEST_CASE( test_with_regular_distance_strategy )
+{
+ test_with_strategy
+ <
+ int,
+ simplify_regular_distance_strategy<int>::type
+ >("i");
+
+ test_with_strategy
+ <
+ float,
+ simplify_regular_distance_strategy<float>::type
+ >("f");
+
+ test_with_strategy
+ <
+ double,
+ simplify_regular_distance_strategy<double>::type
+ >("d");
+ test_with_strategy
+ <
+ long double,
+ simplify_regular_distance_strategy<long double>::type
+ >("ld");
+}
+
+BOOST_AUTO_TEST_CASE( test_with_comparable_distance_strategy )
+{
+ test_with_strategy
+ <
+ int,
+ simplify_comparable_distance_strategy<int>::type
+ >("i");
+ test_with_strategy
+ <
+ float,
+ simplify_comparable_distance_strategy<float>::type
+ >("f");
+ test_with_strategy
+ <
+ double,
+ simplify_comparable_distance_strategy<double>::type
+ >("d");
+ test_with_strategy
+ <
+ long double,
+ simplify_comparable_distance_strategy<long double>::type
+ >("ld");
+}
diff --git a/src/boost/libs/geometry/test/strategies/envelope_segment.cpp b/src/boost/libs/geometry/test/strategies/envelope_segment.cpp
new file mode 100644
index 00000000..09610e3c
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/envelope_segment.cpp
@@ -0,0 +1,134 @@
+// Boost.Geometry
+
+// Copyright (c) 2016-2018 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// 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 <geometry_test_common.hpp>
+#include <boost/geometry/io/wkt/wkt.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
+#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
+
+template
+<
+ typename FormulaPolicy,
+ typename P,
+ typename CT
+>
+void test_strategies_lat(P p1, P p2, CT expected_max, CT expected_min,
+ CT expected_max_sph, CT expected_min_sph, CT error = 0.0001)
+{
+ bg::model::box<P> box;
+
+ bg::strategy::envelope::geographic_segment
+ <
+ FormulaPolicy,
+ bg::srs::spheroid<CT>,
+ CT
+ > strategy_geo;
+
+ strategy_geo.apply(p1, p2, box);
+
+ CT p_min_degree_geo = bg::get<0, 1>(box);
+ CT p_max_degree_geo = bg::get<1, 1>(box);
+
+ BOOST_CHECK_CLOSE(p_max_degree_geo, expected_max, error);
+ BOOST_CHECK_CLOSE(p_min_degree_geo, expected_min, error);
+
+ typedef bg::strategy::envelope::spherical_segment<CT> strategy_sph_t;
+
+ strategy_sph_t::apply(p1, p2, box);
+
+ CT p_min_degree_sph = bg::get<0, 1>(box);
+ CT p_max_degree_sph = bg::get<1, 1>(box);
+
+ BOOST_CHECK_CLOSE(p_max_degree_sph, expected_max_sph, error);
+ BOOST_CHECK_CLOSE(p_min_degree_sph, expected_min_sph, error);
+}
+
+
+template <typename CT>
+void test_all()
+{
+ typedef bg::model::point<CT, 2, bg::cs::geographic<bg::degree> > Pg;
+
+ // Short segments
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 1), Pg(10, 5), 5.0, 1.0, 5.0, 1.0);
+
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 1), Pg(10, 1), 1.0031124506594733, 1.0, 1.0030915676477881, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(-5, 1), Pg(4, 1), 1.0031124506594733, 1.0, 1.0030915676477881, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(175, 1), Pg(184, 1), 1.0031124506594733, 1.0, 1.0030915676477881, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(355, 1), Pg(4, 1), 1.0031124506594733, 1.0, 1.0030915676477881, 1.0);
+
+ // Reverse direction
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 2), Pg(70, 1), 2.0239716998355468, 1.0, 2.0228167431951536, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(70, 1), Pg(1, 2), 2.0239716998351849, 1.0, 2.022816743195063, 1.0);
+
+ // Long segments
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(0, 1), Pg(170, 1), 11.975026023950877, 1.0, 11.325049479775814, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(0, 1), Pg(179, 1), 68.452669316418039, 1.0, 63.437566893227093, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(0, 1), Pg(179.5, 1), 78.84050225214871, 1.0, 75.96516822754981, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(0, 1), Pg(180.5, 1), 78.84050225214871, 1.0, 75.965168227550194, 1.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(0, 1), Pg(180, 1), 90.0, 1.0, 90.0, 1.0);
+
+ // South hemisphere
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, -1), Pg(10, -5), -1.0, -5.0, -1.0, -5.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, -1), Pg(10, -1), -1.0, -1.0031124506594733, -1.0, -1.0030915676477881);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, -1), Pg(170, -1), -1.0, -10.85834257048573, -1.0, -10.321374780571153);
+
+ // Different strategies for inverse
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 1), Pg(10, 1), 1.0031124506594733, 1.0,
+ 1.0030915676477881, 1.0, 0.00000001);
+ test_strategies_lat<bg::strategy::andoyer>
+ (Pg(1, 1), Pg(10, 1), 1.0031124504591062, 1.0,
+ 1.0030915676477881, 1.0, 0.00000001);
+ test_strategies_lat<bg::strategy::vincenty>
+ (Pg(1, 1), Pg(10, 1), 1.0031124508942098, 1.0,
+ 1.0030915676477881, 1.0, 0.00000001);
+
+ // Meridian and equator
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 10), Pg(1, -10), 10.0, -10.0, 10.0, -10.0);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 0), Pg(10, 0), 0.0, 0.0, 0.0, 0.0);
+
+ // One endpoint in northern hemisphere and the other in southern hemisphere
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(1, 1), Pg(150, -5), 1.0, -8.1825389632359933, 1.0, -8.0761230625567588);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(150, -5), Pg(1, 1), 1.0, -8.1825389632359933, 1.0, -8.0761230625568015);
+ test_strategies_lat<bg::strategy::thomas>
+ (Pg(150, 5), Pg(1, -1), 8.1825389632359933, -1.0, 8.0761230625568015, -1.0);
+}
+
+
+
+int test_main( int , char* [] )
+{
+ test_all<double>();
+
+ return 0;
+}
+
diff --git a/src/boost/libs/geometry/test/strategies/franklin.cpp b/src/boost/libs/geometry/test/strategies/franklin.cpp
new file mode 100644
index 00000000..6a6c5fe1
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/franklin.cpp
@@ -0,0 +1,86 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <strategies/test_within.hpp>
+
+
+template <typename Point>
+void test_all()
+{
+ typedef bg::model::polygon<Point> polygon;
+
+ std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))";
+ std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))";
+ std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))";
+
+ bg::strategy::within::franklin<Point> s;
+
+ test_geometry<Point, polygon>("b1", "POINT(1 1)", box, s, true);
+ test_geometry<Point, polygon>("b2", "POINT(3 3)", box, s, false);
+
+ // Test ALL corners (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b3a", "POINT(0 0)", box, s, true); // different
+ test_geometry<Point, polygon>("b3b", "POINT(0 2)", box, s, false);
+ test_geometry<Point, polygon>("b3c", "POINT(2 2)", box, s, false);
+ test_geometry<Point, polygon>("b3d", "POINT(2 0)", box, s, false);
+
+ // Test ALL sides (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b4a", "POINT(0 1)", box, s, true); // different
+ test_geometry<Point, polygon>("b4b", "POINT(1 2)", box, s, false);
+ test_geometry<Point, polygon>("b4c", "POINT(2 1)", box, s, false);
+ test_geometry<Point, polygon>("b4d", "POINT(1 0)", box, s, true); // different
+
+
+ test_geometry<Point, polygon>("t1", "POINT(1 1)", triangle, s, true);
+ test_geometry<Point, polygon>("t2", "POINT(3 3)", triangle, s, false);
+
+ test_geometry<Point, polygon>("t3a", "POINT(0 0)", triangle, s, true); // diff
+ test_geometry<Point, polygon>("t3b", "POINT(0 4)", triangle, s, false);
+ test_geometry<Point, polygon>("t3c", "POINT(5 0)", triangle, s, true); // diff
+
+ test_geometry<Point, polygon>("t4a", "POINT(0 2)", triangle, s, true); // diff
+ test_geometry<Point, polygon>("t4b", "POINT(3 2)", triangle, s, false);
+ test_geometry<Point, polygon>("t4c", "POINT(2 0)", triangle, s, true); // diff
+
+
+ test_geometry<Point, polygon>("h1", "POINT(0.5 0.5)", with_hole, s, true);
+ test_geometry<Point, polygon>("h2a", "POINT(1.5 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h2b", "POINT(5 5)", with_hole, s, false);
+
+ test_geometry<Point, polygon>("h3a", "POINT(1 1)", with_hole, s, false);
+ test_geometry<Point, polygon>("h3b", "POINT(2 2)", with_hole, s, true); // diff
+ test_geometry<Point, polygon>("h3c", "POINT(0 0)", with_hole, s, true); // diff
+
+ test_geometry<Point, polygon>("h4a", "POINT(1 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h4b", "POINT(1.5 2)", with_hole, s, true); // diff
+
+ // Lying ON (one of the sides of) interior ring
+ test_geometry<Point, polygon>("#77-1", "POINT(6 3.5)",
+ "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))",
+ s, false);
+}
+
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+#if defined(HAVE_TTMATH)
+ test_all<bg::model::point<ttmath_big, 2, bg::cs::cartesian> >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/haversine.cpp b/src/boost/libs/geometry/test/strategies/haversine.cpp
new file mode 100644
index 00000000..b6853954
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/haversine.cpp
@@ -0,0 +1,266 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+
+#include <boost/geometry/geometries/point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+
+
+double const average_earth_radius = 6372795.0;
+
+
+template <typename Point, typename LatitudePolicy>
+struct test_distance
+{
+ typedef bg::strategy::distance::haversine<double> haversine_type;
+ typedef typename bg::strategy::distance::services::return_type<haversine_type, Point, Point>::type return_type;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointDistanceStrategy<haversine_type, Point, Point>)
+ );
+
+
+ static void test(double lon1, double lat1, double lon2, double lat2,
+ double radius, double expected, double tolerance)
+ {
+ haversine_type strategy(radius);
+
+ Point p1, p2;
+ bg::assign_values(p1, lon1, LatitudePolicy::apply(lat1));
+ bg::assign_values(p2, lon2, LatitudePolicy::apply(lat2));
+ return_type d = strategy.apply(p1, p2);
+
+ BOOST_CHECK_CLOSE(d, expected, tolerance);
+ }
+};
+
+template <typename Point, typename LatitudePolicy>
+void test_all()
+{
+ // earth to unit-sphere -> divide by earth circumference, then it is from 0-1,
+ // then multiply with 2 PI, so effectively just divide by earth radius
+ double e2u = 1.0 / average_earth_radius;
+
+ // ~ Amsterdam/Paris, 467 kilometers
+ double const a_p = 467.2704 * 1000.0;
+ test_distance<Point, LatitudePolicy>::test(4, 52, 2, 48, average_earth_radius, a_p, 1.0);
+ test_distance<Point, LatitudePolicy>::test(2, 48, 4, 52, average_earth_radius, a_p, 1.0);
+ test_distance<Point, LatitudePolicy>::test(4, 52, 2, 48, 1.0, a_p * e2u, 0.001);
+
+ // ~ Amsterdam/Barcelona
+ double const a_b = 1232.9065 * 1000.0;
+ test_distance<Point, LatitudePolicy>::test(4, 52, 2, 41, average_earth_radius, a_b, 1.0);
+ test_distance<Point, LatitudePolicy>::test(2, 41, 4, 52, average_earth_radius, a_b, 1.0);
+ test_distance<Point, LatitudePolicy>::test(4, 52, 2, 41, 1.0, a_b * e2u, 0.001);
+}
+
+
+template <typename P1, typename P2, typename CalculationType, typename LatitudePolicy>
+void test_services()
+{
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+
+ {
+
+ // Compile-check if there is a strategy for this type
+ typedef typename services::default_strategy
+ <
+ bg::point_tag, bg::point_tag, P1, P2
+ >::type haversine_strategy_type;
+
+ boost::ignore_unused<haversine_strategy_type>();
+ }
+
+ P1 p1;
+ bg::assign_values(p1, 4, 52);
+
+ P2 p2;
+ bg::assign_values(p2, 2, 48);
+
+ // ~ Amsterdam/Paris, 467 kilometers
+ double const km = 1000.0;
+ double const a_p = 467.2704 * km;
+ double const expected = a_p;
+
+ double const expected_lower = 460.0 * km;
+ double const expected_higher = 470.0 * km;
+
+ // 1: normal, calculate distance:
+
+ typedef bgsd::haversine<double, CalculationType> strategy_type;
+ typedef typename bgsd::services::return_type<strategy_type, P1, P2>::type return_type;
+
+ strategy_type strategy(average_earth_radius);
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: the strategy should return the same result if we reverse parameters
+ result = strategy.apply(p2, p1);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ // Check vice versa:
+ // First the result of the comparable strategy
+ return_type c_result = comparable.apply(p1, p2);
+ // Second the comparable result of the expected distance
+ return_type c_expected = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected);
+ // And that one should be equa.
+ BOOST_CHECK_CLOSE(c_result, return_type(c_expected), 0.001);
+
+ // 4: the comparable_type should have a distance_strategy_constructor as well,
+ // knowing how to compare something with a fixed distance
+ return_type c_dist_lower = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected_lower);
+ return_type c_dist_higher = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, expected_higher);
+
+ // If this is the case:
+ BOOST_CHECK(c_dist_lower < c_result && c_result < c_dist_higher);
+
+ // Calculate the Haversine by hand here:
+ return_type c_check = return_type(2.0) * asin(sqrt(c_result)) * average_earth_radius;
+ BOOST_CHECK_CLOSE(c_check, expected, 0.001);
+
+ // This should also be the case
+ return_type dist_lower = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, expected_lower);
+ return_type dist_higher = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, expected_higher);
+ BOOST_CHECK(dist_lower < result && result < dist_higher);
+}
+
+/****
+template <typename P, typename Strategy>
+void time_compare_s(int const n)
+{
+ boost::timer t;
+ P p1, p2;
+ bg::assign_values(p1, 1, 1);
+ bg::assign_values(p2, 2, 2);
+ Strategy strategy;
+ typename Strategy::return_type s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += strategy.apply(p1, p2);
+ }
+ }
+ std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
+}
+
+template <typename P>
+void time_compare(int const n)
+{
+ time_compare_s<P, bg::strategy::distance::haversine<double> >(n);
+ time_compare_s<P, bg::strategy::distance::comparable::haversine<double> >(n);
+}
+
+#include <time.h>
+double time_sqrt(int n)
+{
+ clock_t start = clock();
+
+ double v = 2.0;
+ double s = 0.0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += sqrt(v);
+ v += 1.0e-10;
+ }
+ }
+ clock_t end = clock();
+ double diff = double(end - start) / CLOCKS_PER_SEC;
+
+ std::cout << "Check: " << s << " Time: " << diff << std::endl;
+ return diff;
+}
+
+double time_normal(int n)
+{
+ clock_t start = clock();
+
+ double v = 2.0;
+ double s = 0.0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ s += v;
+ v += 1.0e-10;
+ }
+ }
+ clock_t end = clock();
+ double diff = double(end - start) / CLOCKS_PER_SEC;
+
+ std::cout << "Check: " << s << " Time: " << diff << std::endl;
+ return diff;
+}
+***/
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<int, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy>();
+ test_all<bg::model::point<float, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy>();
+ test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy>();
+
+ // NYI: haversine for mathematical spherical coordinate systems
+ // test_all<bg::model::point<double, 2, bg::cs::spherical<bg::degree> >, mathematical_policy>();
+
+ //double t1 = time_sqrt(20000);
+ //double t2 = time_normal(20000);
+ //std::cout << "Factor: " << (t1 / t2) << std::endl;
+ //time_compare<bg::model::point<double, 2, bg::cs::spherical<bg::radian> > >(10000);
+
+#if defined(HAVE_TTMATH)
+ typedef ttmath::Big<1,4> tt;
+ test_all<bg::model::point<tt, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy>();
+#endif
+
+
+ test_services
+ <
+ bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >,
+ bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >,
+ double,
+ geographic_policy
+ >();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/matrix_transformer.cpp b/src/boost/libs/geometry/test/strategies/matrix_transformer.cpp
new file mode 100644
index 00000000..b617b5c2
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/matrix_transformer.cpp
@@ -0,0 +1,103 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2019 Tinko Bartels
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+#include <boost/geometry/geometries/point.hpp>
+
+template <typename coordinate_type>
+void test_all()
+{
+ typedef bg::model::point<coordinate_type, 2, bg::cs::cartesian> point_2d;
+ typedef bg::model::point<coordinate_type, 3, bg::cs::cartesian> point_3d;
+ typedef bg::model::point<coordinate_type, 4, bg::cs::cartesian> point_4d;
+
+ point_2d p2d;
+ point_3d p3d;
+ point_4d p4d;
+
+ bg::assign_values(p2d, 3, 5);
+
+ boost::qvm::mat<coordinate_type, 5, 3> mat24;
+ boost::qvm::A<0, 0>(mat24) = 1; boost::qvm::A<0, 1>(mat24) = 0; boost::qvm::A<0, 2>(mat24) = 0;
+ boost::qvm::A<1, 0>(mat24) = 0; boost::qvm::A<1, 1>(mat24) = 1; boost::qvm::A<1, 2>(mat24) = 0;
+ boost::qvm::A<2, 0>(mat24) = 1; boost::qvm::A<2, 1>(mat24) = -1; boost::qvm::A<2, 2>(mat24) = 0;
+ boost::qvm::A<3, 0>(mat24) = -1; boost::qvm::A<3, 1>(mat24) = 1; boost::qvm::A<3, 2>(mat24) = 0;
+ boost::qvm::A<4, 0>(mat24) = 0; boost::qvm::A<4, 1>(mat24) = 0; boost::qvm::A<4, 2>(mat24) = 1;
+ bg::strategy::transform::matrix_transformer<coordinate_type, 2, 4> trans24(mat24);
+ bg::transform(p2d, p4d, trans24);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p4d)), 3.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p4d)), 5.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<2>(p4d)), -2.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<3>(p4d)), 2.0, 0.001);
+
+ bg::strategy::transform::scale_transformer<coordinate_type, 4, 4> scale44(2);
+ bg::transform(p4d, p4d, scale44);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p4d)), 6.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p4d)), 10.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<2>(p4d)), -4.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<3>(p4d)), 4.0, 0.001);
+
+ boost::qvm::mat<coordinate_type, 4, 5> mat43;
+ boost::qvm::A<0, 0>(mat43) = 0 ; boost::qvm::A<0, 1>(mat43) = 0; boost::qvm::A<0, 2>(mat43) = 0.5; boost::qvm::A<0, 3>(mat43) = 0 ; boost::qvm::A<0, 4>(mat43) = 0;
+ boost::qvm::A<1, 0>(mat43) = 0.5; boost::qvm::A<1, 1>(mat43) = 0; boost::qvm::A<1, 2>(mat43) = 0 ; boost::qvm::A<1, 3>(mat43) = 0 ; boost::qvm::A<1, 4>(mat43) = 0;
+ boost::qvm::A<2, 0>(mat43) = 0 ; boost::qvm::A<2, 1>(mat43) = 0; boost::qvm::A<2, 2>(mat43) = 0 ; boost::qvm::A<2, 3>(mat43) = 0.5; boost::qvm::A<2, 4>(mat43) = 0;
+ boost::qvm::A<3, 0>(mat43) = 0 ; boost::qvm::A<3, 1>(mat43) = 0; boost::qvm::A<3, 2>(mat43) = 0 ; boost::qvm::A<3, 3>(mat43) = 0 ; boost::qvm::A<3, 4>(mat43) = 1;
+ bg::strategy::transform::matrix_transformer<coordinate_type, 4, 3> trans43(mat43);
+ bg::transform(p4d, p3d, trans43);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p3d)), -2.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p3d)), 3.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<2>(p3d)), 2.0, 0.001);
+
+ bg::strategy::transform::matrix_transformer<coordinate_type, 3, 3> trans33(1, 0, 0, 0,
+ 0, 0, 1, 0,
+ 0, 1, 0, 0,
+ 0, 0, 0, 1);
+ bg::transform(p3d, p3d, trans33);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p3d)), -2.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p3d)), 2.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<2>(p3d)), 3.0, 0.001);
+
+ boost::qvm::mat<coordinate_type, 3, 4> mat32;
+ boost::qvm::A<0, 0>(mat32) = 1; boost::qvm::A<0, 1>(mat32) = 1; boost::qvm::A<0, 2>(mat32) = 1; boost::qvm::A<0, 3>(mat32) = 0;
+ boost::qvm::A<1, 0>(mat32) = -1; boost::qvm::A<1, 1>(mat32) = 0; boost::qvm::A<1, 2>(mat32) = 1; boost::qvm::A<1, 3>(mat32) = 0;
+ boost::qvm::A<2, 0>(mat32) = 0; boost::qvm::A<2, 1>(mat32) = 0; boost::qvm::A<2, 2>(mat32) = 0; boost::qvm::A<2, 3>(mat32) = 1;
+
+ bg::strategy::transform::matrix_transformer<coordinate_type, 3, 2> trans32(mat32);
+ bg::transform(p3d, p2d, trans32);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p2d)), 3.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p2d)), 5.0, 0.001);
+
+ bg::strategy::transform::matrix_transformer<coordinate_type, 2, 2>
+ trans_composed(
+ trans32.matrix() * trans33.matrix() * trans43.matrix() * scale44.matrix() * trans24.matrix());
+ bg::transform(p2d, p2d, trans_composed);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(p2d)), 3.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(p2d)), 5.0, 0.001);
+}
+
+int test_main(int, char* [])
+{
+ test_all<float>();
+ test_all<double>();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/point_in_box.cpp b/src/boost/libs/geometry/test/strategies/point_in_box.cpp
new file mode 100644
index 00000000..50d5f65a
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/point_in_box.cpp
@@ -0,0 +1,81 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014.
+// Modifications copyright (c) 2014 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <strategies/test_within.hpp>
+
+
+template <typename Point>
+void test_box_of(std::string const& wkt_point, std::string const& wkt_box,
+ bool expected_within, bool expected_covered_by)
+{
+ typedef bg::model::box<Point> box_type;
+
+ Point point;
+ box_type box;
+ bg::read_wkt(wkt_point, point);
+ bg::read_wkt(wkt_box, box);
+
+ bool detected_within = bg::within(point, box);
+ bool detected_covered_by = bg::covered_by(point, box);
+ BOOST_CHECK_EQUAL(detected_within, expected_within);
+ BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by);
+
+ // Also test with the non-default agnostic side version
+ namespace wi = bg::strategy::within;
+ wi::point_in_box_by_side<> within_strategy;
+ wi::point_in_box_by_side<wi::decide_covered_by> covered_by_strategy;
+
+ detected_within = bg::within(point, box, within_strategy);
+ detected_covered_by = bg::covered_by(point, box, covered_by_strategy);
+ BOOST_CHECK_EQUAL(detected_within, expected_within);
+ BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by);
+
+ // We might exchange strategies between within/covered by.
+ // So the lines below might seem confusing, but are as intended
+ detected_within = bg::covered_by(point, box, within_strategy);
+ detected_covered_by = bg::within(point, box, covered_by_strategy);
+ BOOST_CHECK_EQUAL(detected_within, expected_within);
+ BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by);
+
+ // Finally we call the strategies directly
+ detected_within = within_strategy.apply(point, box);
+ detected_covered_by = covered_by_strategy.apply(point, box);
+ BOOST_CHECK_EQUAL(detected_within, expected_within);
+ BOOST_CHECK_EQUAL(detected_covered_by, expected_covered_by);
+}
+
+template <typename Point>
+void test_box()
+{
+ test_box_of<Point>("POINT(1 1)", "BOX(0 0,2 2)", true, true);
+ test_box_of<Point>("POINT(0 0)", "BOX(0 0,2 2)", false, true);
+ test_box_of<Point>("POINT(2 2)", "BOX(0 0,2 2)", false, true);
+ test_box_of<Point>("POINT(0 1)", "BOX(0 0,2 2)", false, true);
+ test_box_of<Point>("POINT(1 0)", "BOX(0 0,2 2)", false, true);
+ test_box_of<Point>("POINT(3 3)", "BOX(0 0,2 2)", false, false);
+}
+
+
+int test_main(int, char* [])
+{
+ test_box<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_box<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+#if defined(HAVE_TTMATH)
+ test_box<bg::model::point<ttmath_big, 2, bg::cs::cartesian> >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/projected_point.cpp b/src/boost/libs/geometry/test/strategies/projected_point.cpp
new file mode 100644
index 00000000..c2307eb4
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/projected_point.cpp
@@ -0,0 +1,75 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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.
+// Modifications copyright (c) 2014, 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
+
+// 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 <strategies/test_projected_point.hpp>
+
+
+template <typename P1, typename P2>
+void test_all_2d()
+{
+ test_2d<P1, P2>("POINT(1 1)", "POINT(0 0)", "POINT(2 3)", 0.27735203958327);
+ test_2d<P1, P2>("POINT(2 2)", "POINT(1 4)", "POINT(4 1)", 0.5 * sqrt(2.0));
+ test_2d<P1, P2>("POINT(6 1)", "POINT(1 4)", "POINT(4 1)", 2.0);
+ test_2d<P1, P2>("POINT(1 6)", "POINT(1 4)", "POINT(4 1)", 2.0);
+}
+
+template <typename P>
+void test_all_2d()
+{
+ //test_all_2d<P, int[2]>();
+ //test_all_2d<P, float[2]>();
+ //test_all_2d<P, double[2]>();
+ //test_all_2d<P, test::test_point>();
+ test_all_2d<P, bg::model::point<int, 2, bg::cs::cartesian> >();
+ test_all_2d<P, bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all_2d<P, bg::model::point<double, 2, bg::cs::cartesian> >();
+ test_all_2d<P, bg::model::point<long double, 2, bg::cs::cartesian> >();
+}
+
+int test_main(int, char* [])
+{
+ test_all_2d<int[2]>();
+ test_all_2d<float[2]>();
+ test_all_2d<double[2]>();
+ //test_all_2d<test::test_point>();
+
+ test_all_2d<bg::model::point<int, 2, bg::cs::cartesian> >();
+ test_all_2d<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all_2d<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+ test_services
+ <
+ bg::model::point<double, 2, bg::cs::cartesian>,
+ bg::model::point<float, 2, bg::cs::cartesian>,
+ long double
+ >();
+
+
+#if defined(HAVE_TTMATH)
+ test_all_2d
+ <
+ bg::model::point<ttmath_big, 2, bg::cs::cartesian>,
+ bg::model::point<ttmath_big, 2, bg::cs::cartesian>
+ >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/projected_point_ax.cpp b/src/boost/libs/geometry/test/strategies/projected_point_ax.cpp
new file mode 100644
index 00000000..e9bd9096
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/projected_point_ax.cpp
@@ -0,0 +1,87 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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.
+// Modifications copyright (c) 2014, 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
+
+// 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 <strategies/test_projected_point.hpp>
+
+
+template <typename P1, typename P2>
+void test_all_2d_ax()
+{
+ typedef bg::strategy::distance::detail::projected_point_ax<> strategy_type;
+ typedef bg::strategy::distance::detail::projected_point_ax
+ <
+ void,
+ bg::strategy::distance::comparable::pythagoras<>
+ > comparable_strategy_type;
+
+ typedef typename strategy_type::result_type<P1, P2>::type result_type;
+
+ strategy_type strategy;
+ comparable_strategy_type comparable_strategy;
+ boost::ignore_unused(strategy, comparable_strategy);
+
+ test_2d<P1, P2>("POINT(1 1)", "POINT(0 0)", "POINT(2 3)",
+ result_type(0, 0.27735203958327),
+ result_type(0, 0.27735203958327 * 0.27735203958327),
+ strategy, comparable_strategy);
+
+ test_2d<P1, P2>("POINT(2 2)", "POINT(1 4)", "POINT(4 1)",
+ result_type(0, 0.5 * sqrt(2.0)),
+ result_type(0, 0.5),
+ strategy, comparable_strategy);
+
+ test_2d<P1, P2>("POINT(6 1)", "POINT(1 4)", "POINT(4 1)",
+ result_type(sqrt(2.0), sqrt(2.0)),
+ result_type(2.0, 2.0),
+ strategy, comparable_strategy);
+
+ test_2d<P1, P2>("POINT(1 6)", "POINT(1 4)", "POINT(4 1)",
+ result_type(sqrt(2.0), sqrt(2.0)),
+ result_type(2.0, 2.0),
+ strategy, comparable_strategy);
+}
+
+template <typename P>
+void test_all_2d_ax()
+{
+ test_all_2d_ax<P, bg::model::point<int, 2, bg::cs::cartesian> >();
+ test_all_2d_ax<P, bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all_2d_ax<P, bg::model::point<double, 2, bg::cs::cartesian> >();
+ test_all_2d_ax<P, bg::model::point<long double, 2, bg::cs::cartesian> >();
+}
+
+int test_main(int, char* [])
+{
+ test_all_2d_ax<bg::model::point<int, 2, bg::cs::cartesian> >();
+ test_all_2d_ax<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all_2d_ax<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+#if defined(HAVE_TTMATH)
+ test_all_2d_ax
+ <
+ bg::model::point<ttmath_big, 2, bg::cs::cartesian>,
+ bg::model::point<ttmath_big, 2, bg::cs::cartesian>
+ >();
+#endif
+
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/pythagoras.cpp b/src/boost/libs/geometry/test/strategies/pythagoras.cpp
new file mode 100644
index 00000000..8bb02c03
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/pythagoras.cpp
@@ -0,0 +1,363 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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 <geometry_test_common.hpp>
+
+#if defined(_MSC_VER)
+# pragma warning( disable : 4101 )
+#endif
+
+#include <boost/timer.hpp>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/adapted/c_array.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+
+
+template <typename P1, typename P2>
+void test_null_distance_3d()
+{
+ P1 p1;
+ bg::assign_values(p1, 1, 2, 3);
+ P2 p2;
+ bg::assign_values(p2, 1, 2, 3);
+
+ typedef bg::strategy::distance::pythagoras<> pythagoras_type;
+ typedef typename bg::strategy::distance::services::return_type<pythagoras_type, P1, P2>::type return_type;
+
+ pythagoras_type pythagoras;
+ return_type result = pythagoras.apply(p1, p2);
+
+ BOOST_CHECK_EQUAL(result, return_type(0));
+}
+
+template <typename P1, typename P2>
+void test_axis_3d()
+{
+ P1 p1;
+ bg::assign_values(p1, 0, 0, 0);
+ P2 p2;
+ bg::assign_values(p2, 1, 0, 0);
+
+ typedef bg::strategy::distance::pythagoras<> pythagoras_type;
+ typedef typename bg::strategy::distance::services::return_type<pythagoras_type, P1, P2>::type return_type;
+
+ pythagoras_type pythagoras;
+
+ return_type result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign_values(p2, 0, 1, 0);
+ result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign_values(p2, 0, 0, 1);
+ result = pythagoras.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(1), 0.001);
+}
+
+template <typename P1, typename P2>
+void test_arbitrary_3d()
+{
+ P1 p1;
+ bg::assign_values(p1, 1, 2, 3);
+ P2 p2;
+ bg::assign_values(p2, 9, 8, 7);
+
+ {
+ typedef bg::strategy::distance::pythagoras<> strategy_type;
+ typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(10.77032961427), 0.001);
+ }
+
+ {
+ // Check comparable distance
+ typedef bg::strategy::distance::comparable::pythagoras<> strategy_type;
+ typedef typename bg::strategy::distance::services::return_type<strategy_type, P1, P2>::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_EQUAL(result, return_type(116));
+ }
+}
+
+template <typename P1, typename P2, typename CalculationType>
+void test_services()
+{
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+
+ {
+
+ // Compile-check if there is a strategy for this type
+ typedef typename services::default_strategy
+ <
+ bg::point_tag, bg::point_tag, P1, P2
+ >::type pythagoras_strategy_type;
+
+ boost::ignore_unused<pythagoras_strategy_type>();
+ }
+
+
+ P1 p1;
+ bg::assign_values(p1, 1, 2, 3);
+
+ P2 p2;
+ bg::assign_values(p2, 4, 5, 6);
+
+ double const sqr_expected = 3*3 + 3*3 + 3*3; // 27
+ double const expected = sqrt(sqr_expected); // sqrt(27)=5.1961524227
+
+ // 1: normal, calculate distance:
+
+ typedef bgsd::pythagoras<CalculationType> strategy_type;
+
+ BOOST_CONCEPT_ASSERT( (bg::concepts::PointDistanceStrategy<strategy_type, P1, P2>) );
+
+ typedef typename bgsd::services::return_type<strategy_type, P1, P2>::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: the strategy should return the same result if we reverse parameters
+ result = strategy.apply(p2, p1);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ return_type c_result = comparable.apply(p1, p2);
+ BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
+
+ // 4: the comparable_type should have a distance_strategy_constructor as well,
+ // knowing how to compare something with a fixed distance
+ return_type c_dist5 = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, 5.0);
+ return_type c_dist6 = services::result_from_distance<comparable_type, P1, P2>::apply(comparable, 6.0);
+
+ // If this is the case:
+ BOOST_CHECK(c_dist5 < c_result && c_result < c_dist6);
+
+ // This should also be the case
+ return_type dist5 = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, 5.0);
+ return_type dist6 = services::result_from_distance<strategy_type, P1, P2>::apply(strategy, 6.0);
+ BOOST_CHECK(dist5 < result && result < dist6);
+}
+
+
+template <typename CoordinateType, typename CalculationType, typename AssignType>
+void test_big_2d_with(AssignType const& x1, AssignType const& y1,
+ AssignType const& x2, AssignType const& y2)
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::strategy::distance::pythagoras<CalculationType> pythagoras_type;
+
+ pythagoras_type pythagoras;
+ typedef typename bg::strategy::distance::services::return_type<pythagoras_type, point_type, point_type>::type return_type;
+
+
+ point_type p1, p2;
+ bg::assign_values(p1, x1, y1);
+ bg::assign_values(p2, x2, y2);
+ return_type d = pythagoras.apply(p1, p2);
+
+ /***
+ std::cout << typeid(CalculationType).name()
+ << " " << std::fixed << std::setprecision(20) << d
+ << std::endl << std::endl;
+ ***/
+
+
+ BOOST_CHECK_CLOSE(d, return_type(1076554.5485833955678294387789057), 0.001);
+}
+
+template <typename CoordinateType, typename CalculationType>
+void test_big_2d()
+{
+ test_big_2d_with<CoordinateType, CalculationType>
+ (123456.78900001, 234567.89100001,
+ 987654.32100001, 876543.21900001);
+}
+
+template <typename CoordinateType, typename CalculationType>
+void test_big_2d_string()
+{
+ test_big_2d_with<CoordinateType, CalculationType>
+ ("123456.78900001", "234567.89100001",
+ "987654.32100001", "876543.21900001");
+}
+
+template <typename CoordinateType>
+void test_integer(bool check_types)
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+
+ point_type p1, p2;
+ bg::assign_values(p1, 12345678, 23456789);
+ bg::assign_values(p2, 98765432, 87654321);
+
+ typedef bg::strategy::distance::pythagoras<> pythagoras_type;
+ typedef typename bg::strategy::distance::services::comparable_type
+ <
+ pythagoras_type
+ >::type comparable_type;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ pythagoras_type, point_type, point_type
+ >::type distance_type;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ comparable_type, point_type, point_type
+ >::type cdistance_type;
+
+ pythagoras_type pythagoras;
+ distance_type distance = pythagoras.apply(p1, p2);
+ BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
+
+ comparable_type comparable;
+ cdistance_type cdistance = comparable.apply(p1, p2);
+ BOOST_CHECK_EQUAL(cdistance, 11589696996311540.0);
+
+ distance_type distance2 = sqrt(distance_type(cdistance));
+ BOOST_CHECK_CLOSE(distance, distance2, 0.001);
+
+ if (check_types)
+ {
+ BOOST_CHECK((boost::is_same<distance_type, double>::type::value));
+ // comparable_distance results in now double too, obviously because
+ // comp.distance point-segment can be fraction, even for integer input
+ BOOST_CHECK((boost::is_same<cdistance_type, double>::type::value));
+ }
+}
+
+
+template <typename P1, typename P2>
+void test_all_3d()
+{
+ test_null_distance_3d<P1, P2>();
+ test_axis_3d<P1, P2>();
+ test_arbitrary_3d<P1, P2>();
+}
+
+template <typename P>
+void test_all_3d()
+{
+ test_all_3d<P, int[3]>();
+ test_all_3d<P, float[3]>();
+ test_all_3d<P, double[3]>();
+ test_all_3d<P, test::test_point>();
+ test_all_3d<P, bg::model::point<int, 3, bg::cs::cartesian> >();
+ test_all_3d<P, bg::model::point<float, 3, bg::cs::cartesian> >();
+ test_all_3d<P, bg::model::point<double, 3, bg::cs::cartesian> >();
+}
+
+template <typename P, typename Strategy>
+void time_compare_s(int const n)
+{
+ boost::timer t;
+ P p1, p2;
+ bg::assign_values(p1, 1, 1);
+ bg::assign_values(p2, 2, 2);
+ Strategy strategy;
+ typename bg::strategy::distance::services::return_type<Strategy, P, P>::type s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ bg::set<0>(p2, bg::get<0>(p2) + 0.001);
+ s += strategy.apply(p1, p2);
+ }
+ }
+ std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
+}
+
+template <typename P>
+void time_compare(int const n)
+{
+ time_compare_s<P, bg::strategy::distance::pythagoras<> >(n);
+ time_compare_s<P, bg::strategy::distance::comparable::pythagoras<> >(n);
+}
+
+int test_main(int, char* [])
+{
+ test_integer<int>(true);
+ test_integer<boost::long_long_type>(true);
+ test_integer<double>(false);
+
+ test_all_3d<int[3]>();
+ test_all_3d<float[3]>();
+ test_all_3d<double[3]>();
+
+ test_all_3d<test::test_point>();
+
+ test_all_3d<bg::model::point<int, 3, bg::cs::cartesian> >();
+ test_all_3d<bg::model::point<float, 3, bg::cs::cartesian> >();
+ test_all_3d<bg::model::point<double, 3, bg::cs::cartesian> >();
+
+ test_big_2d<float, float>();
+ test_big_2d<double, double>();
+ test_big_2d<long double, long double>();
+ test_big_2d<float, long double>();
+
+ test_services<bg::model::point<float, 3, bg::cs::cartesian>, double[3], long double>();
+ test_services<double[3], test::test_point, float>();
+
+
+ // TODO move this to another non-unit test
+ // time_compare<bg::model::point<double, 2, bg::cs::cartesian> >(10000);
+
+#if defined(HAVE_TTMATH)
+
+ typedef ttmath::Big<1,4> tt;
+ typedef bg::model::point<tt, 3, bg::cs::cartesian> tt_point;
+
+ //test_all_3d<tt[3]>();
+ test_all_3d<tt_point>();
+ test_all_3d<tt_point, tt_point>();
+ test_big_2d<tt, tt>();
+ test_big_2d_string<tt, tt>();
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/pythagoras_point_box.cpp b/src/boost/libs/geometry/test/strategies/pythagoras_point_box.cpp
new file mode 100644
index 00000000..4121ce02
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/pythagoras_point_box.cpp
@@ -0,0 +1,505 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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.
+// Modifications copyright (c) 2014, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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_TEST_MODULE
+#define BOOST_TEST_MODULE test_pythagoras_point_box
+#endif
+
+#include <boost/test/included/unit_test.hpp>
+
+#if defined(_MSC_VER)
+# pragma warning( disable : 4101 )
+#endif
+
+#include <boost/core/ignore_unused.hpp>
+#include <boost/timer.hpp>
+
+#include <boost/concept/requires.hpp>
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/expand.hpp>
+#include <boost/geometry/strategies/cartesian/distance_pythagoras_point_box.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/adapted/c_array.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+
+namespace bg = boost::geometry;
+
+
+BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+
+
+template <typename Box, typename Coordinate>
+inline void assign_values(Box& box,
+ Coordinate const& x1,
+ Coordinate const& y1,
+ Coordinate const& z1,
+ Coordinate const& x2,
+ Coordinate const& y2,
+ Coordinate const& z2)
+{
+ typename bg::point_type<Box>::type p1, p2;
+ bg::assign_values(p1, x1, y1, z1);
+ bg::assign_values(p2, x2, y2, z2);
+ bg::assign(box, p1);
+ bg::expand(box, p2);
+}
+
+template <typename Point, typename Box>
+inline void test_null_distance_3d()
+{
+ Point p;
+ bg::assign_values(p, 1, 2, 4);
+ Box b;
+ assign_values(b, 1, 2, 3, 4, 5, 6);
+
+ typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_pb_type;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ pythagoras_pb_type, Point, Box
+ >::type return_type;
+
+ pythagoras_pb_type pythagoras_pb;
+ return_type result = pythagoras_pb.apply(p, b);
+
+ BOOST_CHECK_EQUAL(result, return_type(0));
+
+ bg::assign_values(p, 1, 3, 4);
+ result = pythagoras_pb.apply(p, b);
+ BOOST_CHECK_EQUAL(result, return_type(0));
+
+ bg::assign_values(p, 2, 3, 4);
+ result = pythagoras_pb.apply(p, b);
+ BOOST_CHECK_EQUAL(result, return_type(0));
+}
+
+template <typename Point, typename Box>
+inline void test_axis_3d()
+{
+ Box b;
+ assign_values(b, 0, 0, 0, 1, 1, 1);
+ Point p;
+ bg::assign_values(p, 2, 0, 0);
+
+ typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_pb_type;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ pythagoras_pb_type, Point, Box
+ >::type return_type;
+
+ pythagoras_pb_type pythagoras_pb;
+
+ return_type result = pythagoras_pb.apply(p, b);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign_values(p, 0, 2, 0);
+ result = pythagoras_pb.apply(p, b);
+ BOOST_CHECK_EQUAL(result, return_type(1));
+
+ bg::assign_values(p, 0, 0, 2);
+ result = pythagoras_pb.apply(p, b);
+ BOOST_CHECK_CLOSE(result, return_type(1), 0.001);
+}
+
+template <typename Point, typename Box>
+inline void test_arbitrary_3d()
+{
+ Box b;
+ assign_values(b, 0, 0, 0, 1, 2, 3);
+ Point p;
+ bg::assign_values(p, 9, 8, 7);
+
+ {
+ typedef bg::strategy::distance::pythagoras_point_box<> strategy_type;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ strategy_type, Point, Box
+ >::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p, b);
+ BOOST_CHECK_CLOSE(result, return_type(10.77032961427), 0.001);
+ }
+
+ {
+ // Check comparable distance
+ typedef bg::strategy::distance::comparable::pythagoras_point_box<>
+ strategy_type;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ strategy_type, Point, Box
+ >::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p, b);
+ BOOST_CHECK_EQUAL(result, return_type(116));
+ }
+}
+
+template <typename Point, typename Box, typename CalculationType>
+inline void test_services()
+{
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+
+ {
+ // Compile-check if there is a strategy for this type
+ typedef typename services::default_strategy
+ <
+ bg::point_tag, bg::box_tag, Point, Box
+ >::type pythagoras_pb_strategy_type;
+
+ // reverse geometry tags
+ typedef typename services::default_strategy
+ <
+ bg::box_tag, bg::point_tag, Box, Point
+ >::type reversed_pythagoras_pb_strategy_type;
+
+ boost::ignore_unused
+ <
+ pythagoras_pb_strategy_type,
+ reversed_pythagoras_pb_strategy_type
+ >();
+ }
+
+ Point p;
+ bg::assign_values(p, 1, 2, 3);
+
+ Box b;
+ assign_values(b, 4, 5, 6, 14, 15, 16);
+
+ double const sqr_expected = 3*3 + 3*3 + 3*3; // 27
+ double const expected = sqrt(sqr_expected); // sqrt(27)=5.1961524227
+
+ // 1: normal, calculate distance:
+
+ typedef bgsd::pythagoras_point_box<CalculationType> strategy_type;
+
+ BOOST_CONCEPT_ASSERT
+ ( (bg::concepts::PointDistanceStrategy<strategy_type, Point, Box>) );
+
+ typedef typename bgsd::services::return_type
+ <
+ strategy_type, Point, Box
+ >::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p, b);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: the strategy should return the same result if we reverse parameters
+ // result = strategy.apply(p2, p1);
+ // BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for Point/Box
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type
+ <
+ strategy_type
+ >::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable
+ <
+ strategy_type
+ >::apply(strategy);
+
+ typedef typename bgsd::services::return_type
+ <
+ comparable_type, Point, Box
+ >::type comparable_return_type;
+
+ comparable_return_type c_result = comparable.apply(p, b);
+ BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
+
+ // 4: the comparable_type should have a distance_strategy_constructor as well,
+ // knowing how to compare something with a fixed distance
+ comparable_return_type c_dist5 = services::result_from_distance
+ <
+ comparable_type, Point, Box
+ >::apply(comparable, 5.0);
+
+ comparable_return_type c_dist6 = services::result_from_distance
+ <
+ comparable_type, Point, Box
+ >::apply(comparable, 6.0);
+
+ // If this is the case:
+ BOOST_CHECK(c_dist5 < c_result && c_result < c_dist6);
+
+ // This should also be the case
+ return_type dist5 = services::result_from_distance
+ <
+ strategy_type, Point, Box
+ >::apply(strategy, 5.0);
+ return_type dist6 = services::result_from_distance
+ <
+ strategy_type, Point, Box
+ >::apply(strategy, 6.0);
+ BOOST_CHECK(dist5 < result && result < dist6);
+}
+
+template
+<
+ typename CoordinateType,
+ typename CalculationType,
+ typename AssignType
+>
+inline void test_big_2d_with(AssignType const& x1, AssignType const& y1,
+ AssignType const& x2, AssignType const& y2,
+ AssignType const& zero)
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::model::box<point_type> box_type;
+ typedef bg::strategy::distance::pythagoras_point_box
+ <
+ CalculationType
+ > pythagoras_pb_type;
+
+ pythagoras_pb_type pythagoras_pb;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ pythagoras_pb_type, point_type, box_type
+ >::type return_type;
+
+
+ point_type p;
+ box_type b;
+ bg::assign_values(b, zero, zero, x1, y1);
+ bg::assign_values(p, x2, y2);
+ return_type d = pythagoras_pb.apply(p, b);
+
+ BOOST_CHECK_CLOSE(d, return_type(1076554.5485833955678294387789057), 0.001);
+}
+
+template <typename CoordinateType, typename CalculationType>
+inline void test_big_2d()
+{
+ test_big_2d_with<CoordinateType, CalculationType>
+ (123456.78900001, 234567.89100001,
+ 987654.32100001, 876543.21900001,
+ 0.0);
+}
+
+template <typename CoordinateType, typename CalculationType>
+inline void test_big_2d_string()
+{
+ test_big_2d_with<CoordinateType, CalculationType>
+ ("123456.78900001", "234567.89100001",
+ "987654.32100001", "876543.21900001",
+ "0.0000000000000");
+}
+
+template <typename CoordinateType>
+inline void test_integer(bool check_types)
+{
+ typedef bg::model::point<CoordinateType, 2, bg::cs::cartesian> point_type;
+ typedef bg::model::box<point_type> box_type;
+
+ point_type p;
+ box_type b;
+ bg::assign_values(b, 0, 0, 12345678, 23456789);
+ bg::assign_values(p, 98765432, 87654321);
+
+ typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_type;
+ typedef typename bg::strategy::distance::services::comparable_type
+ <
+ pythagoras_type
+ >::type comparable_type;
+
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ pythagoras_type, point_type, box_type
+ >::type distance_type;
+ typedef typename bg::strategy::distance::services::return_type
+ <
+ comparable_type, point_type, box_type
+ >::type cdistance_type;
+
+ pythagoras_type pythagoras;
+ distance_type distance = pythagoras.apply(p, b);
+ BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
+
+ comparable_type comparable;
+ cdistance_type cdistance = comparable.apply(p, b);
+ BOOST_CHECK_EQUAL(cdistance, 11589696996311540.0);
+
+ distance_type distance2 = sqrt(distance_type(cdistance));
+ BOOST_CHECK_CLOSE(distance, distance2, 0.001);
+
+ if (check_types)
+ {
+ BOOST_CHECK((boost::is_same<distance_type, double>::type::value));
+ BOOST_CHECK((boost::is_same<cdistance_type, boost::long_long_type>::type::value));
+ }
+}
+
+template <typename P1, typename P2>
+void test_all_3d()
+{
+ test_null_distance_3d<P1, bg::model::box<P2> >();
+ test_axis_3d<P1, bg::model::box<P2> >();
+ test_arbitrary_3d<P1, bg::model::box<P2> >();
+
+ test_null_distance_3d<P2, bg::model::box<P1> >();
+ test_axis_3d<P2, bg::model::box<P1> >();
+ test_arbitrary_3d<P2, bg::model::box<P1> >();
+}
+
+template <typename P>
+void test_all_3d()
+{
+ test_all_3d<P, int[3]>();
+ test_all_3d<P, float[3]>();
+ test_all_3d<P, double[3]>();
+ test_all_3d<P, test::test_point>();
+ test_all_3d<P, bg::model::point<int, 3, bg::cs::cartesian> >();
+ test_all_3d<P, bg::model::point<float, 3, bg::cs::cartesian> >();
+ test_all_3d<P, bg::model::point<double, 3, bg::cs::cartesian> >();
+}
+
+template <typename P, typename Strategy>
+void time_compare_s(int const n)
+{
+ typedef bg::model::box<P> box_type;
+
+ boost::timer t;
+ P p;
+ box_type b;
+ bg::assign_values(b, 0, 0, 1, 1);
+ bg::assign_values(p, 2, 2);
+ Strategy strategy;
+ typename bg::strategy::distance::services::return_type
+ <
+ Strategy, P, box_type
+ >::type s = 0;
+ for (int i = 0; i < n; i++)
+ {
+ for (int j = 0; j < n; j++)
+ {
+ bg::set<0>(p, bg::get<0>(p) + 0.001);
+ s += strategy.apply(p, b);
+ }
+ }
+ std::cout << "s: " << s << " t: " << t.elapsed() << std::endl;
+}
+
+template <typename P>
+inline void time_compare(int const n)
+{
+ time_compare_s<P, bg::strategy::distance::pythagoras_point_box<> >(n);
+ time_compare_s
+ <
+ P, bg::strategy::distance::comparable::pythagoras_point_box<>
+ >(n);
+}
+
+
+
+
+BOOST_AUTO_TEST_CASE( test_integer_all )
+{
+ test_integer<int>(true);
+ test_integer<boost::long_long_type>(true);
+ test_integer<double>(false);
+}
+
+
+BOOST_AUTO_TEST_CASE( test_3d_all )
+{
+ test_all_3d<int[3]>();
+ test_all_3d<float[3]>();
+ test_all_3d<double[3]>();
+
+ test_all_3d<test::test_point>();
+
+ test_all_3d<bg::model::point<int, 3, bg::cs::cartesian> >();
+ test_all_3d<bg::model::point<float, 3, bg::cs::cartesian> >();
+ test_all_3d<bg::model::point<double, 3, bg::cs::cartesian> >();
+}
+
+
+BOOST_AUTO_TEST_CASE( test_big_2d_all )
+{
+ test_big_2d<float, float>();
+ test_big_2d<double, double>();
+ test_big_2d<long double, long double>();
+ test_big_2d<float, long double>();
+}
+
+
+BOOST_AUTO_TEST_CASE( test_services_all )
+{
+ test_services
+ <
+ bg::model::point<float, 3, bg::cs::cartesian>,
+ bg::model::box<double[3]>,
+ long double
+ >();
+ test_services<double[3], bg::model::box<test::test_point>, float>();
+
+ // reverse the point and box types
+ test_services
+ <
+ double[3],
+ bg::model::box<bg::model::point<float, 3, bg::cs::cartesian> >,
+ long double
+ >();
+ test_services<test::test_point, bg::model::box<double[3]>, float>();
+}
+
+
+BOOST_AUTO_TEST_CASE( test_time_compare )
+{
+ // TODO move this to another non-unit test
+ // time_compare<bg::model::point<double, 2, bg::cs::cartesian> >(10000);
+}
+
+
+#if defined(HAVE_TTMATH)
+BOOST_AUTO_TEST_CASE( test_ttmath_all )
+{
+ typedef ttmath::Big<1,4> tt;
+ typedef bg::model::point<tt, 3, bg::cs::cartesian> tt_point;
+
+ //test_all_3d<tt[3]>();
+ test_all_3d<tt_point>();
+ test_all_3d<tt_point, tt_point>();
+ test_big_2d<tt, tt>();
+ test_big_2d_string<tt, tt>();
+}
+#endif
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection.cpp b/src/boost/libs/geometry/test/strategies/segment_intersection.cpp
new file mode 100644
index 00000000..5bccc1d4
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection.cpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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)
+
+
+#if defined(_MSC_VER)
+// We deliberately mix float/double's here so turn off warning
+#pragma warning( disable : 4244 )
+#endif // defined(_MSC_VER)
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/strategies/cartesian/intersection.hpp>
+#include <boost/geometry/strategies/intersection_result.hpp>
+
+#include <boost/geometry/policies/relate/intersection_points.hpp>
+#include <boost/geometry/policies/relate/direction.hpp>
+#include <boost/geometry/policies/relate/tupled.hpp>
+
+#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian);
+
+
+template <typename P>
+static void test_segment_intersection(int caseid,
+ int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4,
+ char expected_how,
+ int expected_x1 = -99, int expected_y1 = -99,
+ int expected_x2 = -99, int expected_y2 = -99)
+{
+ using namespace boost::geometry;
+
+ typedef typename bg::coordinate_type<P>::type coordinate_type;
+ typedef bg::model::referring_segment<const P> segment_type;
+
+ P p1, p2, p3, p4;
+ bg::assign_values(p1, x1, y1);
+ bg::assign_values(p2, x2, y2);
+ bg::assign_values(p3, x3, y3);
+ bg::assign_values(p4, x4, y4);
+
+ segment_type s12(p1,p2);
+ segment_type s34(p3,p4);
+
+ bg::detail::segment_as_subrange<segment_type> sr12(s12);
+ bg::detail::segment_as_subrange<segment_type> sr34(s34);
+
+ std::size_t expected_count = 0;
+
+ if (expected_x1 != -99 && expected_y1 != -99)
+ {
+ expected_count++;
+ }
+ if (expected_x2 != -99 && expected_y2 != -99)
+ {
+ expected_count++;
+ }
+
+ // Using intersection_insert
+
+ std::vector<P> out;
+ bg::detail::intersection::intersection_insert<P>(s12, s34,
+ std::back_inserter(out));
+
+ // Using strategy
+ typedef bg::segment_intersection_points<P> result_type;
+
+ typedef bg::policies::relate::segments_intersection_points
+ <
+ result_type
+ > points_policy_type;
+
+ result_type is
+ = bg::strategy::intersection::cartesian_segments<>
+ ::apply(sr12, sr34, points_policy_type());
+
+ bg::policies::relate::direction_type dir
+ = bg::strategy::intersection::cartesian_segments<>
+ ::apply(sr12, sr34, bg::policies::relate::segments_direction());
+
+ //BOOST_CHECK_EQUAL(boost::size(out), expected_count);
+ BOOST_CHECK_EQUAL(is.count, expected_count);
+ BOOST_CHECK_MESSAGE(dir.how == expected_how,
+ caseid
+ << " how: detected: " << dir.how
+ << " expected: " << expected_how);
+
+ if (expected_count == 2
+ && is.count == 2
+ && boost::size(out) == 2)
+ {
+ // Two intersection points, reverse expectation if necessary
+ bool const first_matches
+ = std::fabs(bg::get<0>(out[0]) - expected_x1) < 1.0e-6
+ && std::fabs(bg::get<1>(out[0]) - expected_y1) < 1.0e-6;
+
+ if (! first_matches)
+ {
+ std::swap(expected_x1, expected_x2);
+ std::swap(expected_y1, expected_y2);
+ }
+ }
+
+ if (expected_x1 != -99 && expected_y1 != -99
+ && boost::size(out) >= 1)
+ {
+
+ BOOST_CHECK_CLOSE(bg::get<0>(out[0]), coordinate_type(expected_x1), 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(out[0]), coordinate_type(expected_y1), 0.001);
+
+ BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[0]), expected_x1, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[0]), expected_y1, 0.001);
+
+ }
+ if (expected_x2 != -99 && expected_y2 != -99
+ && boost::size(out) >= 2)
+ {
+ BOOST_CHECK_CLOSE(bg::get<0>(out[1]), coordinate_type(expected_x2), 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(out[1]), coordinate_type(expected_y2), 0.001);
+
+ BOOST_CHECK_CLOSE(bg::get<0>(is.intersections[1]), expected_x2, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(is.intersections[1]), expected_y2, 0.001);
+ }
+}
+
+
+template <typename P>
+void test_all()
+{
+ test_segment_intersection<P>( 1, 0,2, 2,0, 0,0, 2,2, 'i', 1, 1);
+ test_segment_intersection<P>( 2, 2,2, 3,1, 0,0, 2,2, 'a', 2, 2);
+ test_segment_intersection<P>( 3, 3,1, 2,2, 0,0, 2,2, 't', 2, 2);
+ test_segment_intersection<P>( 4, 0,2, 1,1, 0,0, 2,2, 'm', 1, 1);
+
+ test_segment_intersection<P>( 5, 1,1, 0,2, 0,0, 2,2, 's', 1, 1);
+ test_segment_intersection<P>( 6, 0,2, 2,0, 0,0, 1,1, 'm', 1, 1);
+ test_segment_intersection<P>( 7, 2,0, 0,2, 0,0, 1,1, 'm', 1, 1);
+ test_segment_intersection<P>( 8, 2,3, 3,2, 0,0, 2,2, 'd');
+
+ test_segment_intersection<P>( 9, 0,0, 2,2, 0,0, 2,2, 'e', 0, 0, 2, 2);
+ test_segment_intersection<P>(10, 2,2, 0,0, 0,0, 2,2, 'e', 2, 2, 0, 0);
+ test_segment_intersection<P>(11, 1,1, 3,3, 0,0, 2,2, 'c', 1, 1, 2, 2);
+ test_segment_intersection<P>(12, 3,3, 1,1, 0,0, 2,2, 'c', 1, 1, 2, 2);
+
+ test_segment_intersection<P>(13, 0,2, 2,2, 2,1, 2,3, 'm', 2, 2);
+ test_segment_intersection<P>(14, 2,2, 2,4, 2,0, 2,2, 'a', 2, 2);
+ test_segment_intersection<P>(15, 2,2, 2,4, 2,0, 2,1, 'd');
+ test_segment_intersection<P>(16, 2,4, 2,2, 2,0, 2,1, 'd');
+
+ test_segment_intersection<P>(17, 2,1, 2,3, 2,2, 2,4, 'c', 2, 2, 2, 3);
+ test_segment_intersection<P>(18, 2,3, 2,1, 2,2, 2,4, 'c', 2, 3, 2, 2);
+ test_segment_intersection<P>(19, 0,2, 2,2, 4,2, 2,2, 't', 2, 2);
+ test_segment_intersection<P>(20, 0,2, 2,2, 2,2, 4,2, 'a', 2, 2);
+
+ test_segment_intersection<P>(21, 1,2, 3,2, 2,1, 2,3, 'i', 2, 2);
+ test_segment_intersection<P>(22, 2,4, 2,1, 2,1, 2,3, 'c', 2, 1, 2, 3);
+ test_segment_intersection<P>(23, 2,4, 2,1, 2,3, 2,1, 'c', 2, 3, 2, 1);
+ test_segment_intersection<P>(24, 1,1, 3,3, 0,0, 3,3, 'c', 1, 1, 3, 3);
+
+ test_segment_intersection<P>(25, 2,0, 2,4, 2,1, 2,3, 'c', 2, 1, 2, 3);
+ test_segment_intersection<P>(26, 2,0, 2,4, 2,3, 2,1, 'c', 2, 3, 2, 1);
+ test_segment_intersection<P>(27, 0,0, 4,4, 1,1, 3,3, 'c', 1, 1, 3, 3);
+ test_segment_intersection<P>(28, 0,0, 4,4, 3,3, 1,1, 'c', 3, 3, 1, 1);
+
+ test_segment_intersection<P>(29, 1,1, 3,3, 0,0, 4,4, 'c', 1, 1, 3, 3);
+ test_segment_intersection<P>(30, 0,0, 2,2, 2,2, 3,1, 'a', 2, 2);
+ test_segment_intersection<P>(31, 0,0, 2,2, 2,2, 1,3, 'a', 2, 2);
+ test_segment_intersection<P>(32, 0,0, 2,2, 1,1, 2,0, 's', 1, 1);
+
+ test_segment_intersection<P>(33, 0,0, 2,2, 1,1, 0,2, 's', 1, 1);
+ test_segment_intersection<P>(34, 2,2, 1,3, 0,0, 2,2, 'a', 2, 2);
+ test_segment_intersection<P>(35, 2,2, 3,1, 0,0, 2,2, 'a', 2, 2);
+ test_segment_intersection<P>(36, 0,0, 2,2, 0,2, 1,1, 'm', 1, 1);
+
+ test_segment_intersection<P>(37, 0,0, 2,2, 2,0, 1,1, 'm', 1, 1);
+ test_segment_intersection<P>(38, 1,1, 0,2, 0,0, 2,2, 's', 1, 1);
+ test_segment_intersection<P>(39, 1,1, 2,0, 0,0, 2,2, 's', 1, 1);
+ test_segment_intersection<P>(40, 2,0, 1,1, 0,0, 2,2, 'm', 1, 1);
+
+ test_segment_intersection<P>(41, 1,2, 0,2, 2,2, 0,2, 'c', 1, 2, 0, 2);
+ test_segment_intersection<P>(42, 2,1, 1,1, 2,2, 0,2, 'd');
+ test_segment_intersection<P>(43, 4,1, 3,1, 2,2, 0,2, 'd');
+ test_segment_intersection<P>(44, 4,2, 3,2, 2,2, 0,2, 'd');
+
+ test_segment_intersection<P>(45, 2,0, 0,2, 0,0, 2,2, 'i', 1, 1);
+
+ // In figure: times 2
+ test_segment_intersection<P>(46, 8,2, 4,6, 0,0, 8, 8, 'i', 5, 5);
+}
+
+int test_main(int, char* [])
+{
+#if !defined(BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE)
+ test_all<boost::tuple<double, double> >();
+ test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+#endif
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection_collinear.cpp b/src/boost/libs/geometry/test/strategies/segment_intersection_collinear.cpp
new file mode 100644
index 00000000..287888f9
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection_collinear.cpp
@@ -0,0 +1,527 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// Copyright (c) 2017, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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)
+
+#define BOOST_GEOMETRY_DEFINE_STREAM_OPERATOR_SEGMENT_RATIO
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/strategies/cartesian/intersection.hpp>
+#include <boost/geometry/strategies/intersection_result.hpp>
+
+#include <boost/geometry/policies/relate/intersection_points.hpp>
+#include <boost/geometry/policies/relate/direction.hpp>
+#include <boost/geometry/policies/relate/tupled.hpp>
+
+#include <boost/geometry/algorithms/intersection.hpp>
+#include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+
+template <typename IntersectionPoints>
+static int check(IntersectionPoints const& is,
+ std::size_t index, double expected_x, double expected_y)
+{
+ if (expected_x != -99 && expected_y != -99 && is.count > index)
+ {
+ double x = bg::get<0>(is.intersections[index]);
+ double y = bg::get<1>(is.intersections[index]);
+
+ BOOST_CHECK_CLOSE(x, expected_x, 0.001);
+ BOOST_CHECK_CLOSE(y, expected_y, 0.001);
+ return 1;
+ }
+ return 0;
+}
+
+
+template <typename P>
+static void test_segment_intersection(std::string const& case_id,
+ int x1, int y1, int x2, int y2,
+ int x3, int y3, int x4, int y4,
+ char expected_how, bool expected_opposite,
+ int expected_arrival1, int expected_arrival2,
+ int expected_x1, int expected_y1,
+ int expected_x2 = -99, int expected_y2 = -99)
+
+{
+ boost::ignore_unused(case_id);
+
+ typedef bg::model::referring_segment<const P> segment_type;
+
+ P p1, p2, p3, p4;
+ bg::assign_values(p1, x1, y1);
+ bg::assign_values(p2, x2, y2);
+ bg::assign_values(p3, x3, y3);
+ bg::assign_values(p4, x4, y4);
+
+ segment_type s12(p1, p2);
+ segment_type s34(p3, p4);
+
+ bg::detail::segment_as_subrange<segment_type> sr12(s12);
+ bg::detail::segment_as_subrange<segment_type> sr34(s34);
+
+ typedef bg::segment_intersection_points<P> result_type;
+
+ typedef bg::policies::relate::segments_intersection_points
+ <
+ result_type
+ > points_policy_type;
+
+ // Get the intersection point (or two points)
+ result_type is
+ = bg::strategy::intersection::cartesian_segments<>
+ ::apply(sr12, sr34, points_policy_type());
+
+ // Get just a character for Left/Right/intersects/etc, purpose is more for debugging
+ bg::policies::relate::direction_type dir
+ = bg::strategy::intersection::cartesian_segments<>
+ ::apply(sr12, sr34, bg::policies::relate::segments_direction());
+
+ std::size_t expected_count =
+ check(is, 0, expected_x1, expected_y1)
+ + check(is, 1, expected_x2, expected_y2);
+
+ BOOST_CHECK_EQUAL(is.count, expected_count);
+ BOOST_CHECK_EQUAL(dir.how, expected_how);
+ BOOST_CHECK_EQUAL(dir.opposite, expected_opposite);
+ BOOST_CHECK_EQUAL(dir.arrival[0], expected_arrival1);
+ BOOST_CHECK_EQUAL(dir.arrival[1], expected_arrival2);
+}
+
+template <typename P, typename Pair>
+static void test_segment_ratio(std::string const& case_id,
+ int x1, int y1, int x2, int y2,
+ int x3, int y3, int x4, int y4,
+ Pair expected_pair_a1, Pair expected_pair_a2,
+ Pair expected_pair_b1, Pair expected_pair_b2,
+ int exp_ax1, int exp_ay1, int exp_ax2, int exp_ay2,
+ std::size_t expected_count = 2)
+
+{
+ boost::ignore_unused(case_id);
+
+ typedef bg::model::referring_segment<const P> segment_type;
+
+ P p1, p2, p3, p4;
+ bg::assign_values(p1, x1, y1);
+ bg::assign_values(p2, x2, y2);
+ bg::assign_values(p3, x3, y3);
+ bg::assign_values(p4, x4, y4);
+
+ segment_type s12(p1, p2);
+ segment_type s34(p3, p4);
+
+ bg::detail::segment_as_subrange<segment_type> sr12(s12);
+ bg::detail::segment_as_subrange<segment_type> sr34(s34);
+
+ typedef bg::segment_intersection_points<P> result_type;
+
+ typedef bg::policies::relate::segments_intersection_points
+ <
+ result_type
+ > points_policy_type;
+
+ // Get the intersection point (or two points)
+ result_type is
+ = bg::strategy::intersection::cartesian_segments<>
+ ::apply(sr12, sr34, points_policy_type());
+
+ typedef bg::segment_ratio<typename bg::coordinate_type<P>::type> ratio_type;
+
+ ratio_type expected_a1(expected_pair_a1.first, expected_pair_a1.second);
+ ratio_type expected_a2(expected_pair_a2.first, expected_pair_a2.second);
+ ratio_type expected_b1(expected_pair_b1.first, expected_pair_b1.second);
+ ratio_type expected_b2(expected_pair_b2.first, expected_pair_b2.second);
+
+ BOOST_CHECK_EQUAL(is.count, expected_count);
+
+ BOOST_CHECK_EQUAL(is.fractions[0].robust_ra, expected_a1);
+ BOOST_CHECK_EQUAL(is.fractions[0].robust_rb, expected_b1);
+ BOOST_CHECK_EQUAL(bg::get<0>(is.intersections[0]), exp_ax1);
+ BOOST_CHECK_EQUAL(bg::get<1>(is.intersections[0]), exp_ay1);
+
+ if (expected_count == 2)
+ {
+ BOOST_CHECK_EQUAL(bg::get<0>(is.intersections[1]), exp_ax2);
+ BOOST_CHECK_EQUAL(bg::get<1>(is.intersections[1]), exp_ay2);
+ BOOST_CHECK_EQUAL(is.fractions[1].robust_ra, expected_a2);
+ BOOST_CHECK_EQUAL(is.fractions[1].robust_rb, expected_b2);
+ }
+}
+
+
+template <typename P>
+void test_all()
+{
+ // Collinear - non opposite
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n1",
+ 2, 0, 6, 0,
+ 0, 0, 2, 0,
+ 'a', false, -1, 0,
+ 2, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n2",
+ 2, 0, 6, 0,
+ 1, 0, 3, 0,
+ 'c', false, -1, 1,
+ 2, 0, 3, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n3",
+ 2, 0, 6, 0,
+ 2, 0, 4, 0,
+ 'c', false, -1, 1,
+ 2, 0, 4, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n4",
+ 2, 0, 6, 0,
+ 3, 0, 5, 0,
+ 'c', false, -1, 1,
+ 3, 0, 5, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n5",
+ 2, 0, 6, 0,
+ 4, 0, 6, 0,
+ 'c', false, 0, 0,
+ 4, 0, 6, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n6",
+ 2, 0, 6, 0,
+ 5, 0, 7, 0,
+ 'c', false, 1, -1,
+ 5, 0, 6, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_intersection<P>("n7",
+ 2, 0, 6, 0,
+ 6, 0, 8, 0,
+ 'a', false, 0, -1,
+ 6, 0);
+
+ // Collinear - opposite
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o1",
+ 2, 0, 6, 0,
+ 2, 0, 0, 0,
+ 'f', true, -1, -1,
+ 2, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o2",
+ 2, 0, 6, 0,
+ 3, 0, 1, 0,
+ 'c', true, -1, -1,
+ 2, 0, 3, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o3",
+ 2, 0, 6, 0,
+ 4, 0, 2, 0,
+ 'c', true, -1, 0,
+ 2, 0, 4, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o4",
+ 2, 0, 6, 0,
+ 5, 0, 3, 0,
+ 'c', true, -1, 1,
+ 3, 0, 5, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o5",
+ 2, 0, 6, 0,
+ 6, 0, 4, 0,
+ 'c', true, 0, 1,
+ 4, 0, 6, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o6",
+ 2, 0, 6, 0,
+ 7, 0, 5, 0,
+ 'c', true, 1, 1,
+ 5, 0, 6, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_intersection<P>("o7",
+ 2, 0, 6, 0,
+ 8, 0, 6, 0,
+ 't', true, 0, 0,
+ 6, 0);
+
+ // a1---------->a2
+ // b1---------->b2
+ test_segment_intersection<P>("e1",
+ 2, 0, 6, 0,
+ 2, 0, 6, 0,
+ 'e', false, 0, 0,
+ 2, 0, 6, 0);
+
+ // a1---------->a2
+ // b2<----------b1
+ test_segment_intersection<P>("e1",
+ 2, 0, 6, 0,
+ 6, 0, 2, 0,
+ 'e', true, 0, 0,
+ 2, 0, 6, 0);
+
+ // Disjoint (in vertical direction, picture still horizontal)
+ // a2<---a1
+ // b2<---b1
+ test_segment_intersection<P>("case_recursive_boxes_1",
+ 10, 7, 10, 6,
+ 10, 10, 10, 9,
+ 'd', false, 0, 0,
+ -1, -1, -1, -1);
+
+}
+
+
+template <typename P>
+void test_ratios()
+{
+ // B inside A
+ // a1------------>a2
+ // b1--->b2
+ test_segment_ratio<P>("n4",
+ 2, 0, 7, 0,
+ 3, 0, 5, 0,
+ std::make_pair(1, 5), std::make_pair(3, 5), // IP located on 1/5, 3/5 w.r.t A
+ std::make_pair(0, 1), std::make_pair(1, 1), // IP located on 0, 1 w.r.t. B
+ // IP's are ordered as in A (currently)
+ 3, 0, 5, 0);
+
+ // a1------------>a2
+ // b2<---b1
+ test_segment_ratio<P>("o4",
+ 2, 0, 7, 0,
+ 5, 0, 3, 0,
+ std::make_pair(1, 5), std::make_pair(3, 5),
+ std::make_pair(1, 1), std::make_pair(0, 1),
+ 3, 0, 5, 0);
+
+ // a2<------------a1
+ // b2<---b1
+ test_segment_ratio<P>("o4b",
+ 7, 0, 2, 0,
+ 5, 0, 3, 0,
+ std::make_pair(2, 5), std::make_pair(4, 5),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 5, 0, 3, 0);
+
+ // a2<------------a1
+ // b1--->b2
+ test_segment_ratio<P>("o4c",
+ 7, 0, 2, 0,
+ 3, 0, 5, 0,
+ std::make_pair(2, 5), std::make_pair(4, 5),
+ std::make_pair(1, 1), std::make_pair(0, 1),
+ 5, 0, 3, 0);
+
+ // Touch-interior
+ // a1---------->a2
+ // b1--->b2
+ test_segment_ratio<P>("n3",
+ 2, 0, 7, 0,
+ 2, 0, 4, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 2, 0, 4, 0);
+
+ // a2<-------------a1
+ // b2<----b1
+ test_segment_ratio<P>("n3b",
+ 7, 0, 2, 0,
+ 7, 0, 5, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 7, 0, 5, 0);
+
+
+ // A inside B
+ // a1--->a2
+ // b1------------>b2
+ test_segment_ratio<P>("rn4",
+ 3, 0, 5, 0,
+ 2, 0, 7, 0,
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ std::make_pair(1, 5), std::make_pair(3, 5),
+ 3, 0, 5, 0);
+
+ // a2<---a1
+ // b1------------>b2
+ test_segment_ratio<P>("ro4",
+ 5, 0, 3, 0,
+ 2, 0, 7, 0,
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ std::make_pair(3, 5), std::make_pair(1, 5),
+ 5, 0, 3, 0);
+
+ // a2<---a1
+ // b2<------------b1
+ test_segment_ratio<P>("ro4b",
+ 5, 0, 3, 0,
+ 7, 0, 2, 0,
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ std::make_pair(2, 5), std::make_pair(4, 5),
+ 5, 0, 3, 0);
+
+ // a1--->a2
+ // b2<------------b1
+ test_segment_ratio<P>("ro4c",
+ 3, 0, 5, 0,
+ 7, 0, 2, 0,
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ std::make_pair(4, 5), std::make_pair(2, 5),
+ 3, 0, 5, 0);
+
+ // B inside A, boundaries intersect
+ // We change the coordinates a bit (w.r.t. n3 above) to have it asymmetrical
+ // a1---------->a2
+ // b1--->b2
+ test_segment_ratio<P>("n3",
+ 2, 0, 7, 0,
+ 2, 0, 4, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 2, 0, 4, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_ratio<P>("o3",
+ 2, 0, 7, 0,
+ 4, 0, 2, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(1, 1), std::make_pair(0, 1),
+ 2, 0, 4, 0);
+
+ // a1---------->a2
+ // b1--->b2
+ test_segment_ratio<P>("n5",
+ 2, 0, 7, 0,
+ 5, 0, 7, 0,
+ std::make_pair(3, 5), std::make_pair(1, 1),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 5, 0, 7, 0);
+
+ // a1---------->a2
+ // b2<---b1
+ test_segment_ratio<P>("o5",
+ 2, 0, 7, 0,
+ 7, 0, 5, 0,
+ std::make_pair(3, 5), std::make_pair(1, 1),
+ std::make_pair(1, 1), std::make_pair(0, 1),
+ 5, 0, 7, 0);
+
+ // Generic (overlaps)
+ // a1---------->a2
+ // b1----->b2
+ test_segment_ratio<P>("n2",
+ 2, 0, 7, 0,
+ 1, 0, 4, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(1, 3), std::make_pair(1, 1),
+ 2, 0, 4, 0);
+
+ // Same, b reversed
+ test_segment_ratio<P>("n2_b",
+ 2, 0, 7, 0,
+ 4, 0, 1, 0,
+ std::make_pair(0, 1), std::make_pair(2, 5),
+ std::make_pair(2, 3), std::make_pair(0, 1),
+ 2, 0, 4, 0);
+
+ // Same, both reversed
+ test_segment_ratio<P>("n2_c",
+ 7, 0, 2, 0,
+ 4, 0, 1, 0,
+ std::make_pair(3, 5), std::make_pair(1, 1),
+ std::make_pair(0, 1), std::make_pair(2, 3),
+ 4, 0, 2, 0);
+
+ // a1---------->a2
+ // b1----->b2
+ test_segment_ratio<P>("n6",
+ 2, 0, 6, 0,
+ 5, 0, 8, 0,
+ std::make_pair(3, 4), std::make_pair(1, 1),
+ std::make_pair(0, 1), std::make_pair(1, 3),
+ 5, 0, 6, 0);
+
+ // Degenerated one
+ // a1---------->a2
+ // b1/b2
+ const int ignored = 99;
+ test_segment_ratio<P>("degenerated1",
+ 2, 0, 6, 0,
+ 5, 0, 5, 0,
+ std::make_pair(3, 4), // IP located on 3/4 w.r.t A
+ std::make_pair(ignored, 1), // not checked
+ std::make_pair(0, 1), // IP located at any place w.r.t B, so 0
+ std::make_pair(ignored, 1), // not checked
+ 5, 0,
+ ignored, ignored,
+ 1);
+
+ test_segment_ratio<P>("degenerated2",
+ 5, 0, 5, 0,
+ 2, 0, 6, 0,
+ std::make_pair(0, 1), std::make_pair(ignored, 1),
+ std::make_pair(3, 4), std::make_pair(ignored, 1),
+ 5, 0,
+ ignored, ignored,
+ 1);
+
+ // Vertical one like in box_poly5 but in integer
+ test_segment_ratio<P>("box_poly5",
+ 45, 25, 45, 15,
+ 45, 22, 45, 19,
+ std::make_pair(3, 10), std::make_pair(6, 10),
+ std::make_pair(0, 1), std::make_pair(1, 1),
+ 45, 22, 45, 19);
+}
+
+int test_main(int, char* [])
+{
+ // We don't rescale but use integer points as, by nature, robust points
+ test_all<bg::model::point<int, 2, bg::cs::cartesian> >();
+ test_ratios<bg::model::point<int, 2, bg::cs::cartesian> >();
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection_geo.cpp b/src/boost/libs/geometry/test/strategies/segment_intersection_geo.cpp
new file mode 100644
index 00000000..16a41091
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection_geo.cpp
@@ -0,0 +1,430 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include "segment_intersection_geo.hpp"
+
+
+template <typename T>
+void test_geographic()
+{
+ typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree> > point_t;
+ typedef bg::model::segment<point_t> segment_t;
+
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -2, -1 -1)", 'a', "POINT(-1 -1)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, 1 1)", "SEGMENT(-1 -2, -1 -1)", 'f', "POINT(-1 -2)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(-1 -2, -1 -1)", 't', "POINT(-1 -1)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -2)", "SEGMENT(-1 -2, -1 -1)", 'a', "POINT(-1 -2)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, -1 -1)", "SEGMENT(-1 -1, 1 1)", 'a', "POINT(-1 -1)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, -1 -1)", "SEGMENT(-1 -2, 1 1)", 'f', "POINT(-1 -2)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, -1 -1)", "SEGMENT(1 1, -1 -1)", 't', "POINT(-1 -1)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, -1 -1)", "SEGMENT(1 1, -1 -2)", 'a', "POINT(-1 -2)");
+
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -2, -1 2)", "SEGMENT(-2 -2, 2 2)",
+ great_elliptic('i', "POINT(-1 -1.000457053724121)"),
+ geodesic_vincenty('i', "POINT(-1 -1.000459099991114)"),
+ geodesic_andoyer('i', "POINT(-1 -1.000453510849886)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-2 -2, 2 2)", "SEGMENT(-1 -2, -1 2)",
+ great_elliptic('i', "POINT(-1 -1.000457053724121)"),
+ geodesic_vincenty('i', "POINT(-1 -1.000459099991114)"),
+ geodesic_andoyer('i', "POINT(-1 -1.000453510849886)"));
+
+ // crossing X
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(-45 45, 45 -45)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000001380087204053 -0.0000000000000063611)"),
+ geodesic_andoyer('i', "POINT(0 0.0003512140328446071)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(45 -45, -45 45)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000001380087204053 -0.0000000000000063611)"),
+ geodesic_andoyer('i', "POINT(0 0.0003512140328446071)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(45 45, -45 -45)", "SEGMENT(-45 45, 45 -45)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000001380087204053 -0.0000000000000063611)"),
+ geodesic_andoyer('i', "POINT(0 0.0003512140328446071)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(45 45, -45 -45)", "SEGMENT(45 -45, -45 45)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000001380087204053 -0.0000000000000063611)"),
+ geodesic_andoyer('i', "POINT(0 0.0003512140328446071)"));
+
+ // crossing X
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 1, 1 -1)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000000000000596354 -0.0000000000626626779)"),
+ geodesic_andoyer('i', "POINT(-0.000000000000000596354 0.0000055787431347552)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 -1, -1 1)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000000000000596354 -0.0000000000626626779)"),
+ geodesic_andoyer('i', "POINT(-0.000000000000000596354 0.0000055787431347552)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(-1 1, 1 -1)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000000000000596354 -0.0000000000626626779)"),
+ geodesic_andoyer('i', "POINT(-0.000000000000000596354 0.0000055787431347552)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(1 -1, -1 1)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.000000000000000596354 -0.0000000000626626779)"),
+ geodesic_andoyer('i', "POINT(-0.000000000000000596354 0.0000055787431347552)"));
+
+ // equal
+ // //
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(-45 -45, 45 45)", 'e', "POINT(-45 -45)", "POINT(45 45)", false);
+ // //
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(45 45, -45 -45)", 'e', "POINT(-45 -45)", "POINT(45 45)", true);
+
+ // starting outside s1
+ // /
+ // |
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, -1 -1)", 'a', "POINT(-1 -1)");
+ // /
+ // /|
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 0 0)", 'm', "POINT(0 0)");
+ // /|
+ // / |
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 1 1)", 't', "POINT(1 1)");
+ // |/
+ // /|
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 2 2)",
+ great_elliptic('i', "POINT(0 0)"),
+ geodesic_vincenty('i', "POINT(0.00000013628420059 0.00000013624239008)"),
+ geodesic_thomas('i', "POINT(-0.00004079969079346 -0.00004078714535240)"),
+ geodesic_andoyer('i', "POINT(-0.01217344899138908 -0.01216980051876599)"));
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, -1 0)", 'a', "POINT(-1 0)");
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 0 0)", 'c', "POINT(-1 0)", "POINT(0 0)", false);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, -2 0)", 'c', "POINT(-1 0)", "POINT(0 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 0, -1 0)", "SEGMENT(-2 0, 0 0)", 'c', "POINT(0 0)", "POINT(-1 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 0, -1 0)", "SEGMENT(0 0, -2 0)", 'c', "POINT(0 0)", "POINT(-1 0)", false);
+ // ------
+ // ---------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 1 0)", 'c', "POINT(-1 0)", "POINT(1 0)", false);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(1 0, -2 0)", 'c', "POINT(-1 0)", "POINT(1 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 0, -1 0)", "SEGMENT(-2 0, 1 0)", 'c', "POINT(1 0)", "POINT(-1 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 0, -1 0)", "SEGMENT(1 0, -2 0)", 'c', "POINT(1 0)", "POINT(-1 0)", false);
+ // ------
+ // ------------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 2 0)", 'c', "POINT(-1 0)", "POINT(1 0)", false);
+
+ // starting at s1
+ // /
+ // //
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 0 0)", 'c', "POINT(-1 -1)", "POINT(0 0)", false);
+ // //
+ // //
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 1 1)", 'e', "POINT(-1 -1)", "POINT(1 1)", false);
+ // | /
+ // |/
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 2 2)", 'f', "POINT(-1 -1)");
+ // ------
+ // ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 0 0)", 'c', "POINT(-1 0)", "POINT(0 0)", false);
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 1 0)", 'e', "POINT(-1 0)", "POINT(1 0)", false);
+ // ------
+ // ---------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 2 0)", 'c', "POINT(-1 0)", "POINT(1 0)", false);
+
+ // starting inside
+ // //
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 1 1)", 'c', "POINT(0 0)", "POINT(1 1)", false);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 1, 0 0)", 'c', "POINT(0 0)", "POINT(1 1)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(0 0, 1 1)", 'c', "POINT(1 1)", "POINT(0 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(1 1, 0 0)", 'c', "POINT(1 1)", "POINT(0 0)", false);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(0 0, 1 1)", "SEGMENT(-1 -1, 1 1)", 'c', "POINT(0 0)", "POINT(1 1)", false);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, 0 0)", "SEGMENT(-1 -1, 1 1)", 'c', "POINT(1 1)", "POINT(0 0)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(0 0, 1 1)", "SEGMENT(1 1, -1 -1)", 'c', "POINT(0 0)", "POINT(1 1)", true);
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 1, 0 0)", "SEGMENT(1 1, -1 -1)", 'c', "POINT(1 1)", "POINT(0 0)", false);
+ // |/
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 2 2)", 's', "POINT(0 0)");
+ // ------
+ // ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 1 0)", 'c', "POINT(0 0)", "POINT(1 0)", false);
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 2 0)", 'c', "POINT(0 0)", "POINT(1 0)", false);
+
+ // starting at p2
+ // |
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 1, 2 2)", 'a', "POINT(1 1)");
+ // ------
+ // ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(1 0, 2 0)", 'a', "POINT(1 0)");
+
+ // disjoint, crossing
+ // /
+ // |
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-3 -3, -2 -2)", 'd');
+ // |
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(2 2, 3 3)", 'd');
+ // disjoint, collinear
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-3 0, -2 0)", 'd');
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(2 0, 3 0)", 'd');
+
+ // degenerated
+ // /
+ // *
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, -2 -2)", 'd');
+ // /
+ // *
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, -1 -1)", '0', "POINT(-1 -1)");
+ // /
+ // *
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 0 0)", '0', "POINT(0 0)");
+ // *
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 1, 1 1)", '0', "POINT(1 1)");
+ // *
+ // /
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(2 2, 2 2)", 'd');
+ // similar to above, collinear
+ // * ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, -2 0)", 'd');
+ // *------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, -1 0)", '0', "POINT(-1 0)");
+ // ---*---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 0 0)", '0', "POINT(0 0)");
+ // ------*
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(1 0, 1 0)", '0', "POINT(1 0)");
+ // ------ *
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(2 0, 2 0)", 'd');
+
+ // Northern hemisphere
+ // --- ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-3 50, -2 50)", 'd');
+ // ------
+ // ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, -1 50)", 'a', "POINT(-1 50)");
+ // \/
+ // /\ (avoid multi-line comment)
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 0 50)",
+ great_elliptic('i', "POINT(-0.5 50.0032229484023)"),
+ geodesic_vincenty('i', "POINT(-0.4999999996073994 50.00323192256208)"),
+ geodesic_thomas('i', "POINT(-0.4999999963998482 50.00323192258598)"),
+ geodesic_andoyer('i', "POINT(-0.4999990340391772 50.00323192463806)"));
+ // ________
+ // / _____\ (avoid multi-line comment)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 1 50)", 't', "POINT(1 50)");
+ // _________
+ // / _____ \ (avoid multi-line comment)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 2 50)", 'd');
+ // ______
+ // /___ \ (avoid multi-line comment)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 0 50)", 'f', "POINT(-1 50)");
+ // ------
+ // ------
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 1 50)", 'e', "POINT(-1 50)", "POINT(1 50)", false);
+ // ________
+ // /_____ \ (avoid multi-line comment)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 2 50)", 'f', "POINT(-1 50)");
+ // ______
+ // / ___\ (avoid multi-line comment)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(0 50, 1 50)", 't', "POINT(1 50)");
+ // \/
+ // /\ (avoid multi-line comment)
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(0 50, 2 50)",
+ great_elliptic('i', "POINT(0.5 50.0032229484023)"),
+ geodesic_vincenty('i', "POINT(0.4999999996112415 50.00323192256208)"),
+ geodesic_thomas('i', "POINT(0.5000000051005989 50.00323192258598)"),
+ geodesic_andoyer('i', "POINT(0.5000009655139563 50.00323192463806)"));
+ // ------
+ // ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(1 50, 2 50)", 'a', "POINT(1 50)");
+ // ------ ---
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(2 50, 3 50)", 'd');
+
+ // ___|
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(0 0, 1 0)", "SEGMENT(1 0, 1 1)", 'a', "POINT(1 0)");
+ // ___|
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(1 0, 1 1)", "SEGMENT(0 0, 1 0)", 'a', "POINT(1 0)");
+
+ // |/
+ // /|
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(10 -1, 20 1)", "SEGMENT(12.5 -1, 12.5 1)",
+ great_elliptic('i', "POINT(12.5 -0.50051443471392)"),
+ geodesic_vincenty('i', "POINT(12.5 -0.5005177749487734)"),
+ geodesic_thomas('i', "POINT(12.5 -0.5005177654827411)"),
+ geodesic_andoyer('i', "POINT(12.5 -0.500525380045163)"));
+ // |/
+ // /|
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(10 -1, 20 1)", "SEGMENT(17.5 -1, 17.5 1)",
+ great_elliptic('i', "POINT(17.5 0.50051443471392)"),
+ geodesic_vincenty('i', "POINT(17.5 0.5005177748229335)"),
+ geodesic_thomas('i', "POINT(17.5 0.5005178030678186)"),
+ geodesic_andoyer('i', "POINT(17.5 0.5004949944844279)"));
+
+ // vertical, crossing at the pole or disjoint
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 45, -90 60)", "SEGMENT(0 50, 180 70)", 'i', "POINT(0 90)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 -45, -90 -60)", "SEGMENT(0 -50, 180 -70)", 'i', "POINT(0 -90)");
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 45, -90 60)", "SEGMENT(0 -50, 180 -70)", 'd');
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 -45, -90 -60)", "SEGMENT(0 50, 180 70)", 'd');
+
+ // vertical touching at the pole
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 90, 90 45)", "SEGMENT(0 90, 0 45)", 'f', "POINT(90 90)"); // should probably be (0 90)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 90, 90 45)", "SEGMENT(0 45, 0 90)", 'a', "POINT(90 90)"); // should probably be (0 90)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 45, 90 90)", "SEGMENT(0 90, 0 45)", 'a', "POINT(90 90)"); // should probably be (0 90)
+ test_all_strategies<segment_t, point_t>(
+ "SEGMENT(90 45, 90 90)", "SEGMENT(0 45, 0 90)", 't', "POINT(90 90)"); // should probably be (0 90)
+
+ // one vertical with endpoint at a pole
+ /*test_strategies<segment_t, point_t>(
+ "SEGMENT(0 90, 90 0)", "SEGMENT(89 45, 91 45)",
+ great_elliptic('i', "POINT(90 45.00436354465514)"),
+ geodesic_vincenty('i', "POINT(90.00000000000112 45.00437824795338)"),
+ geodesic_thomas('i', "POINT(90.00000000472062 45.00437824797395)"),
+ geodesic_andoyer('i', "POINT(89.99999993672924 45.00437824794587)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(90 0, 0 90)", "SEGMENT(89 45, 91 45)",
+ great_elliptic('i', "POINT(90 45.00436354465514)"),
+ geodesic_vincenty('i', "POINT(90.00000000000112 45.00437824795338)"),
+ geodesic_thomas('i', "POINT(90.00000000472062 45.00437824797395)"),
+ geodesic_andoyer('i', "POINT(89.99999993672924 45.00437824794587)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(0 -90, 90 0)", "SEGMENT(89 -45, 91 -45)",
+ great_elliptic('i', "POINT(90 -45.00436354465514)"),
+ geodesic_vincenty('i', "POINT(90.00000000000112 -45.00437824795338)"),
+ geodesic_thomas('i', "POINT(90.00000000472062 -45.00437824797395)"),
+ geodesic_andoyer('i', "POINT(89.99999993672924 -45.00437824794587)"));
+ test_strategies<segment_t, point_t>(
+ "SEGMENT(90 0, 0 -90)", "SEGMENT(89 -45, 91 -45)",
+ great_elliptic('i', "POINT(90 -45.00436354465514)"),
+ geodesic_vincenty('i', "POINT(90.00000000000112 -45.00437824795338)"),
+ geodesic_thomas('i', "POINT(90.00000000472062 -45.00437824797395)"),
+ geodesic_andoyer('i', "POINT(89.99999993672924 -45.00437824794587)"));*/
+}
+
+template <typename T>
+void test_geographic_radian()
+{
+ typedef bg::model::point<T, 2, bg::cs::geographic<bg::radian> > point_t;
+ typedef bg::model::segment<point_t> segment_t;
+
+ bg::strategy::intersection::geographic_segments<bg::strategy::vincenty> strategy;
+
+ // https://github.com/boostorg/geometry/issues/470
+ point_t p0(0.000000001, 0.000000001);
+ point_t p1(0.000000001, 0.000000005);
+ point_t p2(0.000000005, 0.000000005);
+ segment_t s1(p0, p1);
+ segment_t s2(p1, p2);
+ test_strategy_one(s1, s1, strategy, 'e', 2, p0, p1);
+ test_strategy_one(s2, s2, strategy, 'e', 2, p1, p2);
+}
+
+int test_main(int, char* [])
+{
+ //test_geographic<float>();
+ test_geographic<double>();
+
+ test_geographic_radian<double>();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection_geo.hpp b/src/boost/libs/geometry/test/strategies/segment_intersection_geo.hpp
new file mode 100644
index 00000000..4cfb571e
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection_geo.hpp
@@ -0,0 +1,270 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
+
+// Copyright (c) 2016, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_GEO_HPP
+#define BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_GEO_HPP
+
+
+#include "segment_intersection_sph.hpp"
+
+#include <boost/geometry/strategies/geographic/intersection.hpp>
+#include <boost/geometry/strategies/geographic/intersection_elliptic.hpp>
+
+
+template <typename S, typename P>
+void test_default_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ typename bg::strategy::intersection::services::default_strategy
+ <
+ bg::geographic_tag
+ >::type strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+template <typename S, typename P>
+void test_great_elliptic(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ bg::strategy::intersection::great_elliptic_segments<> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+/*
+template <typename S, typename P>
+void test_experimental_elliptic(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ bg::strategy::intersection::experimental_elliptic_segments<> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+*/
+template <typename S, typename P>
+void test_geodesic_vincenty(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ bg::strategy::intersection::geographic_segments<bg::strategy::vincenty, 4> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+template <typename S, typename P>
+void test_geodesic_thomas(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ bg::strategy::intersection::geographic_segments<bg::strategy::thomas, 2> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+template <typename S, typename P>
+void test_geodesic_andoyer(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ bg::strategy::intersection::geographic_segments<bg::strategy::andoyer, 1> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+
+struct strategy_base
+{
+ strategy_base(char m_)
+ : m(m_), expected_count(0), opposite(-1)
+ {}
+ strategy_base(char m_, std::string const& wkt1_)
+ : m(m_), expected_count(1), wkt1(wkt1_), opposite(-1)
+ {}
+ strategy_base(char m_, std::string const& wkt1_, std::string const& wkt2_, bool opposite_)
+ : m(m_), expected_count(1), wkt1(wkt1_), wkt2(wkt2_), opposite(opposite_ ? 1 : 0)
+ {}
+
+ char m;
+ std::size_t expected_count;
+ std::string wkt1, wkt2;
+ int opposite;
+};
+struct strategy_default : strategy_base
+{
+ strategy_default(char m)
+ : strategy_base(m)
+ {}
+ strategy_default(char m, std::string const& wkt1)
+ : strategy_base(m, wkt1)
+ {}
+ strategy_default(char m, std::string const& wkt1, std::string const& wkt2, bool opposite)
+ : strategy_base(m, wkt1, wkt2, opposite)
+ {}
+};
+struct geodesic_vincenty : strategy_base
+{
+ geodesic_vincenty(char m)
+ : strategy_base(m)
+ {}
+ geodesic_vincenty(char m, std::string const& wkt1)
+ : strategy_base(m, wkt1)
+ {}
+ geodesic_vincenty(char m, std::string const& wkt1, std::string const& wkt2, bool opposite)
+ : strategy_base(m, wkt1, wkt2, opposite)
+ {}
+};
+struct geodesic_thomas : strategy_base
+{
+ geodesic_thomas(char m)
+ : strategy_base(m)
+ {}
+ geodesic_thomas(char m, std::string const& wkt1)
+ : strategy_base(m, wkt1)
+ {}
+ geodesic_thomas(char m, std::string const& wkt1, std::string const& wkt2, bool opposite)
+ : strategy_base(m, wkt1, wkt2, opposite)
+ {}
+};
+struct geodesic_andoyer : strategy_base
+{
+ geodesic_andoyer(char m)
+ : strategy_base(m)
+ {}
+ geodesic_andoyer(char m, std::string const& wkt1)
+ : strategy_base(m, wkt1)
+ {}
+ geodesic_andoyer(char m, std::string const& wkt1, std::string const& wkt2, bool opposite)
+ : strategy_base(m, wkt1, wkt2, opposite)
+ {}
+};
+struct great_elliptic : strategy_base
+{
+ great_elliptic(char m)
+ : strategy_base(m)
+ {}
+ great_elliptic(char m, std::string const& wkt1)
+ : strategy_base(m, wkt1)
+ {}
+ great_elliptic(char m, std::string const& wkt1, std::string const& wkt2, bool opposite)
+ : strategy_base(m, wkt1, wkt2, opposite)
+ {}
+};
+
+
+template <typename S, typename P>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ strategy_default const& s)
+{
+ test_default_strategy<S, P>(s1_wkt, s2_wkt, s.m, s.expected_count, s.wkt1, s.wkt2);
+}
+
+template <typename S, typename P>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ great_elliptic const& s)
+{
+ test_great_elliptic<S, P>(s1_wkt, s2_wkt, s.m, s.expected_count, s.wkt1, s.wkt2);
+}
+
+template <typename S, typename P>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ geodesic_vincenty const& s)
+{
+ test_geodesic_vincenty<S, P>(s1_wkt, s2_wkt, s.m, s.expected_count, s.wkt1, s.wkt2);
+}
+
+template <typename S, typename P>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ geodesic_thomas const& s)
+{
+ test_geodesic_thomas<S, P>(s1_wkt, s2_wkt, s.m, s.expected_count, s.wkt1, s.wkt2);
+}
+
+template <typename S, typename P>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ geodesic_andoyer const& s)
+{
+ test_geodesic_andoyer<S, P>(s1_wkt, s2_wkt, s.m, s.expected_count, s.wkt1, s.wkt2);
+}
+
+
+template <typename S, typename P, typename SR1>
+void test_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ SR1 const& sr1)
+{
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr1);
+}
+template <typename S, typename P, typename SR1, typename SR2>
+void test_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ SR1 const& sr1, SR2 const& sr2)
+{
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr1);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr2);
+}
+template <typename S, typename P, typename SR1, typename SR2, typename SR3>
+void test_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ SR1 const& sr1, SR2 const& sr2, SR3 const& sr3)
+{
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr1);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr2);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr3);
+}
+template <typename S, typename P, typename SR1, typename SR2, typename SR3, typename SR4>
+void test_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ SR1 const& sr1, SR2 const& sr2, SR3 const& sr3, SR4 const& sr4)
+{
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr1);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr2);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr3);
+ test_strategy<S, P>(s1_wkt, s2_wkt, sr4);
+}
+
+
+template <typename S, typename P>
+void test_all_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::string const& ip0_wkt = "")
+{
+ std::size_t expected_count = ip0_wkt.empty() ? 0 : 1;
+
+ test_default_strategy<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+ test_great_elliptic<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+ //test_experimental_elliptic<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+ test_geodesic_vincenty<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+ test_geodesic_thomas<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+ test_geodesic_andoyer<S, P>(s1_wkt, s2_wkt, m, expected_count, ip0_wkt);
+}
+
+template <typename S, typename P>
+void test_all_strategies(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m,
+ std::string const& ip0_wkt, std::string const& ip1_wkt,
+ bool opposite)
+{
+ int opposite_id = opposite ? 1 : 0;
+
+ test_default_strategy<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+ test_great_elliptic<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+ //test_experimental_elliptic<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+ test_geodesic_vincenty<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+ test_geodesic_thomas<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+ test_geodesic_andoyer<S, P>(s1_wkt, s2_wkt, m, 2, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+#endif // BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_GEO_HPP
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection_sph.cpp b/src/boost/libs/geometry/test/strategies/segment_intersection_sph.cpp
new file mode 100644
index 00000000..37a2af24
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection_sph.cpp
@@ -0,0 +1,299 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#define BOOST_GEOMETRY_TEST_GEO_INTERSECTION_TEST_SIMILAR
+#include "segment_intersection_sph.hpp"
+
+
+#include <boost/geometry/strategies/spherical/intersection.hpp>
+
+
+template <typename S, typename P>
+void test_spherical_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "")
+{
+ bg::strategy::intersection::spherical_segments<> strategy;
+
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt);
+}
+
+template <typename T>
+void test_spherical()
+{
+ typedef bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > point_t;
+ typedef bg::model::segment<point_t> segment_t;
+
+ // crossing X
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(-45 45, 45 -45)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(45 -45, -45 45)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(45 45, -45 -45)", "SEGMENT(-45 45, 45 -45)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(45 45, -45 -45)", "SEGMENT(45 -45, -45 45)", 'i', 1, "POINT(0 0)");
+ // crossing X
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 1, 1 -1)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 -1, -1 1)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(-1 1, 1 -1)", 'i', 1, "POINT(0 0)");
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(1 1, -1 -1)", "SEGMENT(1 -1, -1 1)", 'i', 1, "POINT(0 0)");
+
+ // equal
+ // //
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(-45 -45, 45 45)", 'e', 2, "POINT(-45 -45)", "POINT(45 45)");
+ // //
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-45 -45, 45 45)", "SEGMENT(45 45, -45 -45)", 'e', 2, "POINT(-45 -45)", "POINT(45 45)");
+
+ // starting outside s1
+ // /
+ // |
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, -1 -1)", 'a', 1, "POINT(-1 -1)");
+ // /
+ // /|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 0 0)", 'm', 1, "POINT(0 0)");
+ // /|
+ // / |
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 1 1)", 't', 1, "POINT(1 1)");
+ // |/
+ // /|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, 2 2)", 'i', 1, "POINT(0 0)");
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, -1 0)", 'a', 1, "POINT(-1 0)");
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 0 0)", 'c', 2, "POINT(-1 0)", "POINT(0 0)");
+ // ------
+ // ---------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 1 0)", 'c', 2, "POINT(-1 0)", "POINT(1 0)");
+ // ------
+ // ------------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, 2 0)", 'c', 2, "POINT(-1 0)", "POINT(1 0)");
+
+ // starting at s1
+ // /
+ // //
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 0 0)", 'c', 2, "POINT(-1 -1)", "POINT(0 0)");
+ // //
+ // //
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 1 1)", 'e', 2, "POINT(-1 -1)", "POINT(1 1)");
+ // | /
+ // |/
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, 2 2)", 'f', 1, "POINT(-1 -1)");
+ // ------
+ // ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 0 0)", 'c', 2, "POINT(-1 0)", "POINT(0 0)");
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 1 0)", 'e', 2, "POINT(-1 0)", "POINT(1 0)");
+ // ------
+ // ---------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, 2 0)", 'c', 2, "POINT(-1 0)", "POINT(1 0)");
+
+ // starting inside
+ // //
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 1 1)", 'c', 2, "POINT(0 0)", "POINT(1 1)");
+ // |/
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 2 2)", 's', 1, "POINT(0 0)");
+ // ------
+ // ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 1 0)", 'c', 2, "POINT(0 0)", "POINT(1 0)");
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 2 0)", 'c', 2, "POINT(0 0)", "POINT(1 0)");
+
+ // starting at p2
+ // |
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 1, 2 2)", 'a', 1, "POINT(1 1)");
+ // ------
+ // ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(1 0, 2 0)", 'a', 1, "POINT(1 0)");
+
+ // disjoint, crossing
+ // /
+ // |
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-3 -3, -2 -2)", 'd', 0);
+ // |
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(2 2, 3 3)", 'd', 0);
+ // disjoint, collinear
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-3 0, -2 0)", 'd', 0);
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(2 0, 3 0)", 'd', 0);
+
+ // degenerated
+ // /
+ // *
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-2 -2, -2 -2)", 'd', 0);
+ // /
+ // *
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(-1 -1, -1 -1)", '0', 1, "POINT(-1 -1)");
+ // /
+ // *
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(0 0, 0 0)", '0', 1, "POINT(0 0)");
+ // *
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(1 1, 1 1)", '0', 1, "POINT(1 1)");
+ // *
+ // /
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 -1, 1 1)", "SEGMENT(2 2, 2 2)", 'd', 0);
+ // similar to above, collinear
+ // * ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-2 0, -2 0)", 'd', 0);
+ // *------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(-1 0, -1 0)", '0', 1, "POINT(-1 0)");
+ // ---*---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(0 0, 0 0)", '0', 1, "POINT(0 0)");
+ // ------*
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(1 0, 1 0)", '0', 1, "POINT(1 0)");
+ // ------ *
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 0, 1 0)", "SEGMENT(2 0, 2 0)", 'd', 0);
+
+ // Northern hemisphere
+ // --- ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-3 50, -2 50)", 'd', 0);
+ // ------
+ // ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, -1 50)", 'a', 1, "POINT(-1 50)");
+ // \/
+ // /\ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 0 50)", 'i', 1, "POINT(-0.5 50.0032229484023)");
+ // ________
+ // / _____\ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 1 50)", 't', 1, "POINT(1 50)");
+ // _________
+ // / _____ \ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-2 50, 2 50)", 'd', 0);
+ // ______
+ // /___ \ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 0 50)", 'f', 1, "POINT(-1 50)");
+ // ------
+ // ------
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 1 50)", 'e', 2, "POINT(-1 50)", "POINT(1 50)");
+ // ________
+ // /_____ \ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(-1 50, 2 50)", 'f', 1, "POINT(-1 50)");
+ // ______
+ // / ___\ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(0 50, 1 50)", 't', 1, "POINT(1 50)");
+ // \/
+ // /\ (avoid multi-line comment)
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(0 50, 2 50)", 'i', 1, "POINT(0.5 50.0032229484023)");
+ // ------
+ // ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(1 50, 2 50)", 'a', 1, "POINT(1 50)");
+ // ------ ---
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(-1 50, 1 50)", "SEGMENT(2 50, 3 50)", 'd', 0);
+
+ // ___|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(0 0, 1 0)", "SEGMENT(1 0, 1 1)", 'a', 1, "POINT(1 0)");
+ // ___|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(1 0, 1 1)", "SEGMENT(0 0, 1 0)", 'a', 1, "POINT(1 0)");
+
+ // |/
+ // /|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(10 -1, 20 1)", "SEGMENT(12.5 -1, 12.5 1)", 'i', 1, "POINT(12.5 -0.50051443471392)");
+ // |/
+ // /|
+ test_spherical_strategy<segment_t, point_t>(
+ "SEGMENT(10 -1, 20 1)", "SEGMENT(17.5 -1, 17.5 1)", 'i', 1, "POINT(17.5 0.50051443471392)");
+}
+
+template <typename T>
+void test_spherical_radian()
+{
+ typedef bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::radian> > point_t;
+ typedef bg::model::segment<point_t> segment_t;
+
+ bg::strategy::intersection::spherical_segments<> strategy;
+
+ // https://github.com/boostorg/geometry/issues/470
+ point_t p0(0.00001, 0.00001);
+ point_t p1(0.00001, 0.00005);
+ point_t p2(0.00005, 0.00005);
+ segment_t s1(p0, p1);
+ segment_t s2(p1, p2);
+ test_strategy_one(s1, s1, strategy, 'e', 2, p0, p1);
+ test_strategy_one(s2, s2, strategy, 'e', 2, p1, p2);
+}
+
+int test_main(int, char* [])
+{
+ //test_spherical<float>();
+ test_spherical<double>();
+
+ test_spherical_radian<double>();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/segment_intersection_sph.hpp b/src/boost/libs/geometry/test/strategies/segment_intersection_sph.hpp
new file mode 100644
index 00000000..687d3402
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/segment_intersection_sph.hpp
@@ -0,0 +1,221 @@
+// Boost.Geometry
+// Unit Test
+
+// Copyright (c) 2016-2018, Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_SPH_HPP
+#define BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_SPH_HPP
+
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/equals.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/io/wkt/read.hpp>
+#include <boost/geometry/io/wkt/write.hpp>
+
+#include <boost/geometry/policies/relate/direction.hpp>
+#include <boost/geometry/policies/relate/intersection_points.hpp>
+#include <boost/geometry/policies/relate/tupled.hpp>
+
+#include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
+
+template <typename T>
+bool equals_relaxed_val(T const& v1, T const& v2, T const& eps_scale)
+{
+ T const c1 = 1;
+ T relaxed_eps = std::numeric_limits<T>::epsilon()
+ * bg::math::detail::greatest(c1, bg::math::abs(v1), bg::math::abs(v2))
+ * eps_scale;
+ return bg::math::abs(v1 - v2) <= relaxed_eps;
+}
+
+template <typename P1, typename P2, typename T>
+bool equals_relaxed(P1 const& p1, P2 const& p2, T const& eps_scale)
+{
+ typedef typename bg::select_coordinate_type<P1, P2>::type calc_t;
+ calc_t c1 = 1;
+ calc_t p10 = bg::get<0>(p1);
+ calc_t p11 = bg::get<1>(p1);
+ calc_t p20 = bg::get<0>(p2);
+ calc_t p21 = bg::get<1>(p2);
+ calc_t relaxed_eps = std::numeric_limits<calc_t>::epsilon()
+ * bg::math::detail::greatest(c1, bg::math::abs(p10), bg::math::abs(p11), bg::math::abs(p20), bg::math::abs(p21))
+ * eps_scale;
+ calc_t diff0 = p10 - p20;
+ // needed e.g. for -179.999999 - 180.0
+ if (diff0 < -180)
+ diff0 += 360;
+ return bg::math::abs(diff0) <= relaxed_eps
+ && bg::math::abs(p11 - p21) <= relaxed_eps;
+}
+
+template <typename S1, typename S2, typename Strategy, typename P>
+void test_strategy_one(S1 const& s1, S2 const& s2,
+ Strategy const& strategy,
+ char m, std::size_t expected_count,
+ P const& ip0 = P(), P const& ip1 = P(),
+ int opposite_id = -1)
+{
+ typedef typename bg::coordinate_type<P>::type coord_t;
+ typedef bg::policies::relate::segments_tupled
+ <
+ bg::policies::relate::segments_intersection_points
+ <
+ bg::segment_intersection_points<P, bg::segment_ratio<coord_t> >
+ >,
+ bg::policies::relate::segments_direction
+ > policy_t;
+
+ typedef typename policy_t::return_type return_type;
+
+ bg::detail::segment_as_subrange<S1> sr1(s1);
+ bg::detail::segment_as_subrange<S2> sr2(s2);
+
+ return_type res = strategy.apply(sr1, sr2, policy_t());
+
+ size_t const res_count = boost::get<0>(res).count;
+ char const res_method = boost::get<1>(res).how;
+
+ BOOST_CHECK_MESSAGE(res_method == m,
+ "IP method: " << res_method << " different than expected: " << m
+ << " for " << bg::wkt(s1) << " and " << bg::wkt(s2));
+
+ BOOST_CHECK_MESSAGE(res_count == expected_count,
+ "IP count: " << res_count << " different than expected: " << expected_count
+ << " for " << bg::wkt(s1) << " and " << bg::wkt(s2));
+
+ // The EPS is scaled because during the conversion various angles may be not converted
+ // to cartesian 3d the same way which results in a different intersection point
+ // For more information read the info in spherical intersection strategy file.
+
+ // Plus in geographic CS the result strongly depends on the compiler,
+ // probably due to differences in FP trigonometric function implementations
+
+ int eps_scale = 1;
+ bool is_geographic = boost::is_same<typename bg::cs_tag<S1>::type, bg::geographic_tag>::value;
+ if (is_geographic)
+ {
+ eps_scale = 100000;
+ }
+ else
+ {
+ eps_scale = res_method != 'i' ? 1 : 1000;
+ }
+
+ if (res_count > 0 && expected_count > 0)
+ {
+ P const& res_i0 = boost::get<0>(res).intersections[0];
+ coord_t denom_a0 = boost::get<0>(res).fractions[0].robust_ra.denominator();
+ coord_t denom_b0 = boost::get<0>(res).fractions[0].robust_rb.denominator();
+ BOOST_CHECK_MESSAGE(equals_relaxed(res_i0, ip0, eps_scale),
+ "IP0: " << std::setprecision(16) << bg::wkt(res_i0) << " different than expected: " << bg::wkt(ip0)
+ << " for " << bg::wkt(s1) << " and " << bg::wkt(s2));
+ BOOST_CHECK_MESSAGE(denom_a0 > coord_t(0),
+ "IP0 fraction A denominator: " << std::setprecision(16) << denom_a0 << " is incorrect");
+ BOOST_CHECK_MESSAGE(denom_b0 > coord_t(0),
+ "IP0 fraction B denominator: " << std::setprecision(16) << denom_b0 << " is incorrect");
+ }
+ if (res_count > 1 && expected_count > 1)
+ {
+ P const& res_i1 = boost::get<0>(res).intersections[1];
+ coord_t denom_a1 = boost::get<0>(res).fractions[1].robust_ra.denominator();
+ coord_t denom_b1 = boost::get<0>(res).fractions[1].robust_rb.denominator();
+ BOOST_CHECK_MESSAGE(equals_relaxed(res_i1, ip1, eps_scale),
+ "IP1: " << std::setprecision(16) << bg::wkt(res_i1) << " different than expected: " << bg::wkt(ip1)
+ << " for " << bg::wkt(s1) << " and " << bg::wkt(s2));
+ BOOST_CHECK_MESSAGE(denom_a1 > coord_t(0),
+ "IP1 fraction A denominator: " << std::setprecision(16) << denom_a1 << " is incorrect");
+ BOOST_CHECK_MESSAGE(denom_b1 > coord_t(0),
+ "IP1 fraction B denominator: " << std::setprecision(16) << denom_b1 << " is incorrect");
+ }
+
+ if (opposite_id >= 0)
+ {
+ bool opposite = opposite_id != 0;
+ BOOST_CHECK_MESSAGE(opposite == boost::get<1>(res).opposite,
+ bg::wkt(s1) << " and " << bg::wkt(s2) << (opposite_id == 0 ? " are not " : " are ") << "opposite" );
+ }
+}
+
+template <typename T>
+T translated(T v, double t)
+{
+ v += T(t);
+ if (v > 180)
+ v -= 360;
+ return v;
+}
+
+template <typename S1, typename S2, typename Strategy, typename P>
+void test_strategy(S1 const& s1, S2 const& s2,
+ Strategy const& strategy,
+ char m, std::size_t expected_count,
+ P const& ip0 = P(), P const& ip1 = P(),
+ int opposite_id = -1)
+{
+ S1 s1t = s1;
+ S2 s2t = s2;
+ P ip0t = ip0;
+ P ip1t = ip1;
+
+#ifndef BOOST_GEOMETRY_TEST_GEO_INTERSECTION_TEST_SIMILAR
+ test_strategy_one(s1t, s2t, strategy, m, expected_count, ip0t, ip1t, opposite_id);
+#else
+ double t = 0;
+ for (int i = 0; i < 4; ++i, t += 90)
+ {
+ bg::set<0, 0>(s1t, translated(bg::get<0, 0>(s1), t));
+ bg::set<1, 0>(s1t, translated(bg::get<1, 0>(s1), t));
+ bg::set<0, 0>(s2t, translated(bg::get<0, 0>(s2), t));
+ bg::set<1, 0>(s2t, translated(bg::get<1, 0>(s2), t));
+ if (expected_count > 0)
+ bg::set<0>(ip0t, translated(bg::get<0>(ip0), t));
+ if (expected_count > 1)
+ bg::set<0>(ip1t, translated(bg::get<0>(ip1), t));
+
+ test_strategy_one(s1t, s2t, strategy, m, expected_count, ip0t, ip1t, opposite_id);
+ }
+#endif
+}
+
+template <typename S1, typename S2, typename P, typename Strategy>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ Strategy const& strategy,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ S1 s1;
+ S2 s2;
+ P ip0, ip1;
+
+ bg::read_wkt(s1_wkt, s1);
+ bg::read_wkt(s2_wkt, s2);
+ if (! ip0_wkt.empty())
+ bg::read_wkt(ip0_wkt, ip0);
+ if (!ip1_wkt.empty())
+ bg::read_wkt(ip1_wkt, ip1);
+
+ test_strategy(s1, s2, strategy, m, expected_count, ip0, ip1, opposite_id);
+}
+
+template <typename S, typename P, typename Strategy>
+void test_strategy(std::string const& s1_wkt, std::string const& s2_wkt,
+ Strategy const& strategy,
+ char m, std::size_t expected_count,
+ std::string const& ip0_wkt = "", std::string const& ip1_wkt = "",
+ int opposite_id = -1)
+{
+ test_strategy<S, S, P>(s1_wkt, s2_wkt, strategy, m, expected_count, ip0_wkt, ip1_wkt, opposite_id);
+}
+
+#endif // BOOST_GEOMETRY_TEST_STRATEGIES_SEGMENT_INTERSECTION_SPH_HPP
diff --git a/src/boost/libs/geometry/test/strategies/side_of_intersection.cpp b/src/boost/libs/geometry/test/strategies/side_of_intersection.cpp
new file mode 100644
index 00000000..b42270e3
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/side_of_intersection.cpp
@@ -0,0 +1,108 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2011-2015 Barend Gehrels, Amsterdam, the Netherlands.
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/strategies/cartesian/side_of_intersection.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+
+namespace bg = boost::geometry;
+
+int test_main(int, char* [])
+{
+ typedef bg::model::d2::point_xy<boost::long_long_type> point;
+ typedef bg::model::segment<point> segment;
+
+ typedef bg::strategy::side::side_of_intersection side;
+
+ point no_fb(-99, -99);
+
+ segment a(point(20, 10), point(10, 20));
+
+ segment b1(point(11, 16), point(20, 14)); // IP with a: (14.857, 15.143)
+ segment b2(point(10, 16), point(20, 14)); // IP with a: (15, 15)
+
+ segment c1(point(15, 16), point(13, 8));
+ segment c2(point(15, 16), point(14, 8));
+ segment c3(point(15, 16), point(15, 8));
+
+
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b1, c1, no_fb));
+ BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c2, no_fb));
+ BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c3, no_fb));
+
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c1, no_fb));
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c2, no_fb));
+ BOOST_CHECK_EQUAL( 0, side::apply(a, b2, c3, no_fb));
+
+ // Collinear cases
+ // 1: segments intersecting are collinear (with a fallback point):
+ {
+ point fb(5, 5);
+ segment col1(point(0, 5), point(5, 5));
+ segment col2(point(5, 5), point(10, 5)); // One IP with col1 at (5,5)
+ segment col3(point(5, 0), point(5, 5));
+ BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
+ }
+ // 2: segment of side calculation collinear with one of the segments
+ {
+ point fb(5, 5);
+ segment col1(point(0, 5), point(10, 5));
+ segment col2(point(5, 5), point(5, 12)); // IP with col1 at (5,5)
+ segment col3(point(5, 1), point(5, 5)); // collinear with col2
+ BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
+ }
+ {
+ point fb(5, 5);
+ segment col1(point(10, 5), point(0, 5));
+ segment col2(point(5, 5), point(5, 12)); // IP with col1 at (5,5)
+ segment col3(point(5, 1), point(5, 5)); // collinear with col2
+ BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
+ }
+ {
+ point fb(5, 5);
+ segment col1(point(0, 5), point(10, 5));
+ segment col2(point(5, 12), point(5, 5)); // IP with col1 at (5,5)
+ segment col3(point(5, 1), point(5, 5)); // collinear with col2
+ BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
+ }
+
+ {
+ point fb(517248, -517236);
+ segment col1(point(-172408, -517236), point(862076, -517236));
+ segment col2(point(517248, -862064), point(517248, -172408));
+ segment col3(point(517248, -172408), point(517248, -517236));
+ BOOST_CHECK_EQUAL( 0, side::apply(col1, col2, col3, fb));
+ }
+ {
+ point fb(-221647, -830336);
+ segment col1(point(-153817, -837972), point(-222457, -830244));
+ segment col2(point(-221139, -833615), point(-290654, -384388));
+ segment col3(point(-255266, -814663), point(-264389, -811197));
+ BOOST_CHECK_EQUAL(1, side::apply(col1, col2, col3, fb)); // Left of segment...
+ }
+
+
+ {
+ point fb(27671131, 30809240);
+ segment col1(point(27671116, 30809247), point(27675474, 30807351));
+ segment col2(point(27666779, 30811130), point(27671139, 30809237));
+ segment col3(point(27671122, 30809244), point(27675480, 30807348));
+ BOOST_CHECK_EQUAL(1, side::apply(col1, col2, col3, fb)); // Left of segment...
+ }
+
+ // TODO: we might add a check calculating the IP, determining the side
+ // with the normal side strategy, and verify the results are equal
+
+ return 0;
+}
+
diff --git a/src/boost/libs/geometry/test/strategies/spherical_side.cpp b/src/boost/libs/geometry/test/strategies/spherical_side.cpp
new file mode 100644
index 00000000..b834e016
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/spherical_side.cpp
@@ -0,0 +1,173 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2015.
+// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <geometry_test_common.hpp>
+
+
+#include <boost/geometry/algorithms/assign.hpp>
+
+#include <boost/geometry/core/coordinate_type.hpp>
+#include <boost/geometry/core/cs.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/segment.hpp>
+
+#include <boost/geometry/strategies/spherical/side_by_cross_track.hpp>
+//#include <boost/geometry/strategies/spherical/side_via_plane.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+
+#include <boost/geometry/strategies/geographic/mapping_ssf.hpp>
+#include <boost/geometry/strategies/geographic/side_andoyer.hpp>
+#include <boost/geometry/strategies/geographic/side_thomas.hpp>
+#include <boost/geometry/strategies/geographic/side_vincenty.hpp>
+
+#include <boost/geometry/util/math.hpp>
+
+
+namespace boost { namespace geometry {
+
+template <typename Vector, typename Point1, typename Point2>
+static inline Vector create_vector(Point1 const& p1, Point2 const& p2)
+{
+ Vector v;
+ convert(p1, v);
+ subtract_point(v, p2);
+ return v;
+}
+
+}}
+
+inline char side_char(int side)
+{
+ return side == 1 ? 'L'
+ : side == -1 ? 'R'
+ : '-'
+ ;
+}
+
+template <typename Point>
+void test_side1(std::string const& /*case_id*/, Point const& p1, Point const& p2, Point const& p3,
+ int expected, int expected_cartesian)
+{
+ namespace bgss = bg::strategy::side;
+
+ // std::cout << case_id << ": ";
+ //int s = bgss::side_via_plane<>::apply(p1, p2, p3);
+ int side_ssf = bgss::spherical_side_formula<>::apply(p1, p2, p3);
+ //int side2 = bgss::side_via_plane<>::apply(p1, p2, p3);
+ int side_ct = bgss::side_by_cross_track<>::apply(p1, p2, p3);
+
+ // non-official
+ typedef bg::srs::spheroid<double> spheroid;
+ spheroid const sph(1.0, 1.0);
+ int side_mssf1 = bgss::mapping_spherical_side_formula<spheroid>(sph).apply(p1, p2, p3);
+ int side_mssf2 = bgss::mapping_spherical_side_formula<spheroid, bgss::mapping_reduced>(sph).apply(p1, p2, p3);
+ int side_mssf3 = bgss::mapping_spherical_side_formula<spheroid, bgss::mapping_geocentric>(sph).apply(p1, p2, p3);
+ int side_andoyer = bgss::andoyer<spheroid>(sph).apply(p1, p2, p3);
+ int side_thomas = bgss::thomas<spheroid>(sph).apply(p1, p2, p3);
+ int side_vincenty = bgss::vincenty<spheroid>(sph).apply(p1, p2, p3);
+
+ // cartesian
+ typedef bg::strategy::side::services::default_strategy<bg::cartesian_tag>::type cartesian_strategy;
+ int side_cart = cartesian_strategy::apply(p1, p2, p3);
+
+ BOOST_CHECK_EQUAL(side_ssf, expected);
+ BOOST_CHECK_EQUAL(side_ct, expected);
+ BOOST_CHECK_EQUAL(side_mssf1, expected);
+ BOOST_CHECK_EQUAL(side_mssf2, expected);
+ BOOST_CHECK_EQUAL(side_mssf3, expected);
+ BOOST_CHECK_EQUAL(side_andoyer, expected);
+ BOOST_CHECK_EQUAL(side_thomas, expected);
+ BOOST_CHECK_EQUAL(side_vincenty, expected);
+ BOOST_CHECK_EQUAL(side_cart, expected_cartesian);
+
+ /*
+ std::cout
+ << "exp: " << side_char(expected)
+ << " ssf: " << side_char(side1)
+ << " pln: " << side_char(side2)
+ << " ct: " << side_char(side3)
+ //<< " def: " << side_char(side4)
+ << " cart: " << side_char(side5)
+ << std::endl;
+ */
+}
+
+template <typename Point>
+void test_side(std::string const& case_id, Point const& p1, Point const& p2, Point const& p3,
+ int expected, int expected_cartesian = -999)
+{
+ if (expected_cartesian == -999)
+ {
+ expected_cartesian = expected;
+ }
+ test_side1(case_id, p1, p2, p3, expected, expected_cartesian);
+ test_side1(case_id, p2, p1, p3, -expected, -expected_cartesian);
+}
+
+
+template <typename Point>
+void test_all()
+{
+ typedef typename bg::coordinate_type<Point>::type CT;
+
+ Point amsterdam(bg::math::rounding_cast<CT>(5.9), bg::math::rounding_cast<CT>(52.4));
+ Point barcelona(2.0, 41.0);
+ Point paris(2.0, 48.0);
+ Point milan(7.0, 45.0);
+
+ //goto wrong;
+
+ test_side<Point>("bp-m", barcelona, paris, milan, -1);
+ test_side<Point>("bm-p", barcelona, milan, paris, 1);
+ test_side<Point>("mp-b", milan, paris, barcelona, 1);
+
+ test_side<Point>("am-p", amsterdam, milan, paris, -1);
+ test_side<Point>("pm-a", paris, milan, amsterdam, 1);
+
+ // http://www.gcmap.com/mapui?P=30N+10E-50N+50E,39N+30E
+ Point gcmap_p1(10.0, 30.0);
+ Point gcmap_p2(50.0, 50.0);
+ test_side<Point>("blog1", gcmap_p1, gcmap_p2, Point(30.0, 41.0), -1, 1);
+ test_side<Point>("blog1", gcmap_p1, gcmap_p2, Point(30.0, 42.0), -1, 1);
+ test_side<Point>("blog1", gcmap_p1, gcmap_p2, Point(30.0, 43.0), -1, 1);
+ test_side<Point>("blog1", gcmap_p1, gcmap_p2, Point(30.0, 44.0), 1);
+
+ // http://www.gcmap.com/mapui?P=50N+80E-60N+50W,65N+30E
+ Point gcmap_np1(80.0, 50.0);
+ Point gcmap_np2(-50.0, 60.0);
+ // http://www.gcmap.com/mapui?P=50N+140E-60N+10E,65N+30E
+ //Point gcmap_np1(140.0, 50.0);
+ //Point gcmap_np2(10.0, 60.0);
+ //test_side<Point>(gcmap_np1, gcmap_np2, gcmap_np, 1);
+ test_side<Point>("40", gcmap_np1, gcmap_np2, Point(30.0, 60.0), 1, -1);
+ test_side<Point>("45", gcmap_np1, gcmap_np2, Point(30.0, 65.0), 1, -1);
+ test_side<Point>("70", gcmap_np1, gcmap_np2, Point(30.0, 70.0), 1, -1);
+ test_side<Point>("75", gcmap_np1, gcmap_np2, Point(30.0, 75.0), -1);
+}
+
+int test_main(int, char* [])
+{
+ test_all<bg::model::point<int, 2, bg::cs::spherical<bg::degree> > >();
+ test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> > >();
+
+#if defined(HAVE_TTMATH)
+ typedef ttmath::Big<1,4> tt;
+ test_all<bg::model::point<tt, 2, bg::cs::spherical_equatorial<bg::degree> > >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/test_projected_point.hpp b/src/boost/libs/geometry/test/strategies/test_projected_point.hpp
new file mode 100644
index 00000000..72a0d906
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/test_projected_point.hpp
@@ -0,0 +1,185 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// 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.
+// Modifications copyright (c) 2014, 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
+
+// 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)
+
+#ifndef BOOST_GEOMETRY_TEST_STRATEGIES_TEST_PROJECTED_POINT_HPP
+#define BOOST_GEOMETRY_TEST_STRATEGIES_TEST_PROJECTED_POINT_HPP
+
+#include <geometry_test_common.hpp>
+
+#include <boost/core/ignore_unused.hpp>
+
+#include <boost/geometry/strategies/cartesian/distance_projected_point.hpp>
+#include <boost/geometry/strategies/cartesian/distance_projected_point_ax.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+
+#include <boost/geometry/io/wkt/read.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/adapted/c_array.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+
+
+template <typename P, typename PS, typename CalculationType>
+void test_services()
+{
+ PS p1, p2;
+ bg::assign_values(p1, 0, 0);
+ bg::assign_values(p2, 0, 4);
+
+ P p;
+ bg::assign_values(p, 2, 0);
+
+ CalculationType const sqr_expected = 4;
+ CalculationType const expected = 2;
+
+
+ namespace bgsd = bg::strategy::distance;
+ namespace services = bg::strategy::distance::services;
+
+ {
+ // compile-check if there is a strategy for this type
+ typedef typename services::default_strategy
+ <
+ bg::point_tag, bg::segment_tag, P, PS
+ >::type projected_point_strategy_type;
+
+ typedef typename services::default_strategy
+ <
+ bg::segment_tag, bg::point_tag, PS, P
+ >::type reversed_tags_projected_point_strategy_type;
+
+ boost::ignore_unused<projected_point_strategy_type,
+ reversed_tags_projected_point_strategy_type>();
+ }
+
+ // 1: normal, calculate distance:
+
+ typedef bgsd::projected_point<CalculationType> strategy_type;
+
+ BOOST_CONCEPT_ASSERT( (bg::concepts::PointSegmentDistanceStrategy<strategy_type, P, PS>) );
+
+ typedef typename services::return_type<strategy_type, P, PS>::type return_type;
+
+ strategy_type strategy;
+ return_type result = strategy.apply(p, p1, p2);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+ // 2: the strategy should return the same result if we reverse parameters
+ result = strategy.apply(p, p2, p1);
+ BOOST_CHECK_CLOSE(result, return_type(expected), 0.001);
+
+
+ // 3: "comparable" to construct a "comparable strategy" for P1/P2
+ // a "comparable strategy" is a strategy which does not calculate the exact distance, but
+ // which returns results which can be mutually compared (e.g. avoid sqrt)
+
+ // 3a: "comparable_type"
+ typedef typename services::comparable_type<strategy_type>::type comparable_type;
+
+ // 3b: "get_comparable"
+ comparable_type comparable = bgsd::services::get_comparable<strategy_type>::apply(strategy);
+
+ return_type c_result = comparable.apply(p, p1, p2);
+ BOOST_CHECK_CLOSE(c_result, return_type(sqr_expected), 0.001);
+}
+
+template <typename T1, typename T2>
+void test_check_close(T1 const& v1, T2 const& v2, double f)
+{
+ BOOST_CHECK_CLOSE(v1, v2, f);
+}
+
+template <typename T1, typename T2>
+void test_check_close(bg::strategy::distance::detail::projected_point_ax_result<T1> const& v1,
+ bg::strategy::distance::detail::projected_point_ax_result<T2> const& v2,
+ double f)
+{
+ BOOST_CHECK_CLOSE(v1.atd, v2.atd, f);
+ BOOST_CHECK_CLOSE(v1.xtd, v2.xtd, f);
+}
+
+template <typename P1, typename P2, typename T, typename Strategy, typename ComparableStrategy>
+void test_2d(std::string const& wkt_p,
+ std::string const& wkt_sp1,
+ std::string const& wkt_sp2,
+ T expected_distance,
+ T expected_comparable_distance,
+ Strategy strategy,
+ ComparableStrategy comparable_strategy)
+{
+ P1 p;
+ P2 sp1, sp2;
+ bg::read_wkt(wkt_p, p);
+ bg::read_wkt(wkt_sp1, sp1);
+ bg::read_wkt(wkt_sp2, sp2);
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointSegmentDistanceStrategy<Strategy, P1, P2>)
+ );
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointSegmentDistanceStrategy<ComparableStrategy, P1, P2>)
+ );
+
+ {
+ typedef typename bg::strategy::distance::services::return_type<Strategy, P1, P2>::type return_type;
+ return_type d = strategy.apply(p, sp1, sp2);
+ test_check_close(d, expected_distance, 0.001);
+ }
+
+ // Test combination with the comparable strategy
+ {
+ typedef typename bg::strategy::distance::services::return_type<ComparableStrategy, P1, P2>::type return_type;
+ return_type d = comparable_strategy.apply(p, sp1, sp2);
+ test_check_close(d, expected_comparable_distance, 0.01);
+ }
+
+}
+
+template <typename P1, typename P2, typename T>
+void test_2d(std::string const& wkt_p,
+ std::string const& wkt_sp1,
+ std::string const& wkt_sp2,
+ T expected_distance)
+{
+ typedef bg::strategy::distance::projected_point<> strategy_type;
+ typedef bg::strategy::distance::projected_point
+ <
+ void,
+ bg::strategy::distance::comparable::pythagoras<>
+ > comparable_strategy_type;
+
+ strategy_type strategy;
+ comparable_strategy_type comparable_strategy;
+
+ T expected_squared_distance = expected_distance * expected_distance;
+ test_2d<P1, P2>(wkt_p, wkt_sp1, wkt_sp2, expected_distance, expected_squared_distance, strategy, comparable_strategy);
+}
+
+#endif // BOOST_GEOMETRY_TEST_STRATEGIES_TEST_PROJECTED_POINT_HPP
diff --git a/src/boost/libs/geometry/test/strategies/test_within.hpp b/src/boost/libs/geometry/test/strategies/test_within.hpp
new file mode 100644
index 00000000..ae9b06dd
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/test_within.hpp
@@ -0,0 +1,106 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2019.
+// Modifications copyright (c) 2014, 2019 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_GEOMETRY_TEST_STRATEGIES_TEST_WITHIN_HPP
+#define BOOST_GEOMETRY_TEST_STRATEGIES_TEST_WITHIN_HPP
+
+
+#include <geometry_test_common.hpp>
+
+#include <boost/geometry/algorithms/covered_by.hpp>
+#include <boost/geometry/algorithms/within.hpp>
+
+#include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
+#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
+#include <boost/geometry/strategies/cartesian/box_in_box.hpp>
+#include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
+
+#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/strategies/spherical/ssf.hpp>
+
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/box.hpp>
+#include <boost/geometry/geometries/polygon.hpp>
+
+#include <boost/geometry/io/wkt/wkt.hpp>
+
+
+template <typename Strategy>
+inline const char * strategy_name(Strategy const&)
+{
+ return typeid(Strategy).name();
+}
+
+template <typename P, typename PoS, typename CT>
+inline const char * strategy_name(bg::strategy::within::crossings_multiply<P, PoS, CT> const&)
+{
+ return "crossings_multiply";
+}
+
+template <typename P, typename PoS, typename CT>
+inline const char * strategy_name(bg::strategy::within::franklin<P, PoS, CT> const&)
+{
+ return "franklin";
+}
+
+template <typename P, typename PoS, typename CT>
+inline const char * strategy_name(bg::strategy::within::winding<P, PoS, CT> const&)
+{
+ return "winding";
+}
+
+
+template <typename Point, typename Polygon, typename Strategy>
+void test_point_in_polygon(std::string const& case_id,
+ Point const& point,
+ Polygon const& polygon,
+ Strategy const& strategy,
+ bool expected,
+ bool use_within = true)
+{
+ BOOST_CONCEPT_ASSERT( (bg::concepts::WithinStrategyPolygonal<Point, Polygon, Strategy>) );
+ bool detected = use_within ?
+ bg::within(point, polygon, strategy) :
+ bg::covered_by(point, polygon, strategy);
+
+ BOOST_CHECK_MESSAGE(detected == expected,
+ (use_within ? "within: " : "covered_by: ") << case_id
+ << " strategy: " << strategy_name(strategy)
+ << " output expected: " << int(expected)
+ << " detected: " << int(detected)
+ );
+}
+
+
+template <typename Point, typename Polygon, typename Strategy>
+void test_geometry(std::string const& case_id,
+ std::string const& wkt_point,
+ std::string const& wkt_polygon,
+ Strategy const& strategy,
+ bool expected,
+ bool use_within = true)
+{
+ Point point;
+ Polygon polygon;
+ bg::read_wkt(wkt_point, point);
+ bg::read_wkt(wkt_polygon, polygon);
+
+ test_point_in_polygon(case_id, point, polygon, strategy, expected, use_within);
+}
+
+
+#endif // BOOST_GEOMETRY_TEST_STRATEGIES_TEST_WITHIN_HPP
diff --git a/src/boost/libs/geometry/test/strategies/thomas.cpp b/src/boost/libs/geometry/test/strategies/thomas.cpp
new file mode 100644
index 00000000..596b3504
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/thomas.cpp
@@ -0,0 +1,153 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2015, 2017.
+// Modifications copyright (c) 2015-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/geographic/distance_thomas.hpp>
+#include <boost/geometry/strategies/geographic/side_thomas.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+
+
+template <typename P1, typename P2>
+void test_distance(double lon1, double lat1, double lon2, double lat2, double expected_km)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<P1>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+
+ typedef bg::strategy::distance::thomas<stype> thomas_type;
+ typedef bg::strategy::distance::geographic<bg::strategy::thomas, stype> geographic_type;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concepts::PointDistanceStrategy<thomas_type, P1, P2>)
+ );
+
+ thomas_type thomas;
+ geographic_type geographic;
+ typedef typename bg::strategy::distance
+ ::services::return_type<thomas_type, P1, P2>::type return_type;
+
+
+ P1 p1;
+ P2 p2;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+
+ BOOST_CHECK_CLOSE(thomas.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
+ BOOST_CHECK_CLOSE(geographic.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
+ BOOST_CHECK_CLOSE(bg::distance(p1, p2, thomas), return_type(1000.0 * expected_km), 0.001);
+}
+
+template <typename PS, typename P>
+void test_side(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon, double lat,
+ int expected_side)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<PS>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+
+ typedef bg::strategy::side::thomas<stype> strategy_type;
+ typedef bg::strategy::side::geographic<bg::strategy::thomas, stype> strategy2_type;
+
+ strategy_type strategy;
+ strategy2_type strategy2;
+
+ PS p1, p2;
+ P p;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+ bg::assign_values(p, lon, lat);
+
+ int side = strategy.apply(p1, p2, p);
+ int side2 = strategy2.apply(p1, p2, p);
+
+ BOOST_CHECK_EQUAL(side, expected_side);
+ BOOST_CHECK_EQUAL(side2, expected_side);
+}
+
+template <typename P1, typename P2>
+void test_all()
+{
+ test_distance<P1, P2>(0, 90, 1, 80, 1116.825795); // polar
+ test_distance<P1, P2>(0, -90, 1, -80, 1116.825795); // polar
+ test_distance<P1, P2>(4, 52, 4, 52, 0.0); // no point difference
+ test_distance<P1, P2>(4, 52, 3, 40, 1336.025365); // normal case
+
+ test_side<P1, P2>(0, 0, 0, 1, 0, 2, 0);
+ test_side<P1, P2>(0, 0, 0, 1, 0, -2, 0);
+ test_side<P1, P2>(10, 0, 10, 1, 10, 2, 0);
+ test_side<P1, P2>(10, 0, 10, -1, 10, 2, 0);
+
+ test_side<P1, P2>(10, 0, 10, 1, 0, 2, 1); // left
+ test_side<P1, P2>(10, 0, 10, -1, 0, 2, -1); // right
+
+ test_side<P1, P2>(-10, -10, 10, 10, 10, 0, -1); // right
+ test_side<P1, P2>(-10, -10, 10, 10, -10, 0, 1); // left
+ test_side<P1, P2>(170, -10, -170, 10, -170, 0, -1); // right
+ test_side<P1, P2>(170, -10, -170, 10, 170, 0, 1); // left
+}
+
+template <typename P>
+void test_all()
+{
+ test_all<P, P>();
+}
+
+int test_main(int, char* [])
+{
+ //test_all<float[2]>();
+ //test_all<double[2]>();
+ test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
+
+#if defined(HAVE_TTMATH)
+ test_all<bg::model::point<ttmath::Big<1,4>, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<ttmath_big, 2, bg::cs::geographic<bg::degree> > >();
+#endif
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/transform_cs.cpp b/src/boost/libs/geometry/test/strategies/transform_cs.cpp
new file mode 100644
index 00000000..777104ee
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/transform_cs.cpp
@@ -0,0 +1,149 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/geometry/strategies/strategy_transform.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/point_xy.hpp>
+
+template <typename T, typename P>
+inline T check_distance(P const& p)
+{
+ T x = bg::get<0>(p);
+ T y = bg::get<1>(p);
+ T z = bg::get<2>(p);
+ return sqrt(x * x + y * y + z * z);
+}
+
+template <typename T>
+void test_transformations_spherical()
+{
+ T const input_long = 15.0;
+ T const input_lat = 5.0;
+
+ T const expected_long = 0.26179938779914943653855361527329;
+ T const expected_lat = 0.08726646259971647884618453842443;
+
+ // Can be checked using http://www.calc3d.com/ejavascriptcoordcalc.html
+ // (for phi use long, in radians, for theta use lat, in radians, they are listed there as "theta, phi")
+ T const expected_polar_x = 0.084186;
+ T const expected_polar_y = 0.0225576;
+ T const expected_polar_z = 0.996195;
+
+ // Can be checked with same URL using 90-theta for lat.
+ // So for theta use 85 degrees, in radians: 0.08726646259971647884618453842443
+ T const expected_equatorial_x = 0.962250;
+ T const expected_equatorial_y = 0.257834;
+ T const expected_equatorial_z = 0.0871557;
+
+ // 1: Spherical-polar (lat=5, so it is near the pole - on a unit sphere)
+ bg::model::point<T, 2, bg::cs::spherical<bg::degree> > sp(input_long, input_lat);
+
+ // 1a: to radian
+ bg::model::point<T, 2, bg::cs::spherical<bg::radian> > spr;
+ bg::transform(sp, spr);
+ BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
+
+ // 1b: to cartesian-3d
+ bg::model::point<T, 3, bg::cs::cartesian> pc3;
+ bg::transform(sp, pc3);
+ BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z, 0.001);
+ BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
+
+ // 1c: back
+ bg::transform(pc3, spr);
+ BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001);
+
+ // 2: Spherical-equatorial (lat=5, so it is near the equator)
+ bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::degree> > se(input_long, input_lat);
+
+ // 2a: to radian
+ bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::radian> > ser;
+ bg::transform(se, ser);
+ BOOST_CHECK_CLOSE(bg::get<0>(ser), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(ser), expected_lat, 0.001);
+
+ bg::transform(se, pc3);
+ BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z, 0.001);
+ BOOST_CHECK_CLOSE(check_distance<T>(pc3), 1.0, 0.001);
+
+ // 2c: back
+ bg::transform(pc3, ser);
+ BOOST_CHECK_CLOSE(bg::get<0>(spr), expected_long, 0.001); // expected_long
+ BOOST_CHECK_CLOSE(bg::get<1>(spr), expected_lat, 0.001); // expected_lat
+
+
+ // 3: Spherical-polar including radius
+ bg::model::point<T, 3, bg::cs::spherical<bg::degree> > sp3(input_long, input_lat, 0.5);
+
+ // 3a: to radian
+ bg::model::point<T, 3, bg::cs::spherical<bg::radian> > spr3;
+ bg::transform(sp3, spr3);
+ BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
+
+ // 3b: to cartesian-3d
+ bg::transform(sp3, pc3);
+ BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_polar_x / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_polar_y / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_polar_z / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
+
+ // 3c: back
+ bg::transform(pc3, spr3);
+ BOOST_CHECK_CLOSE(bg::get<0>(spr3), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(spr3), expected_lat, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(spr3), 0.5, 0.001);
+
+
+ // 4: Spherical-equatorial including radius
+ bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::degree> > se3(input_long, input_lat, 0.5);
+
+ // 4a: to radian
+ bg::model::point<T, 3, bg::cs::spherical_equatorial<bg::radian> > ser3;
+ bg::transform(se3, ser3);
+ BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
+
+ // 4b: to cartesian-3d
+ bg::transform(se3, pc3);
+ BOOST_CHECK_CLOSE(bg::get<0>(pc3), expected_equatorial_x / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(pc3), expected_equatorial_y / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(pc3), expected_equatorial_z / 2.0, 0.001);
+ BOOST_CHECK_CLOSE(check_distance<T>(pc3), 0.5, 0.001);
+
+ // 4c: back
+ bg::transform(pc3, ser3);
+ BOOST_CHECK_CLOSE(bg::get<0>(ser3), expected_long, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<1>(ser3), expected_lat, 0.001);
+ BOOST_CHECK_CLOSE(bg::get<2>(ser3), 0.5, 0.001);
+}
+
+int test_main(int, char* [])
+{
+ test_transformations_spherical<double>();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/transformer.cpp b/src/boost/libs/geometry/test/strategies/transformer.cpp
new file mode 100644
index 00000000..5cdc567e
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/transformer.cpp
@@ -0,0 +1,119 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/geometry/strategies/transform/inverse_transformer.hpp>
+#include <boost/geometry/strategies/transform/map_transformer.hpp>
+#include <boost/geometry/strategies/transform/matrix_transformers.hpp>
+
+
+#include <boost/geometry/algorithms/make.hpp>
+#include <boost/geometry/algorithms/transform.hpp>
+
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/geometries/adapted/c_array.hpp>
+#include <boost/geometry/geometries/adapted/boost_tuple.hpp>
+
+BOOST_GEOMETRY_REGISTER_C_ARRAY_CS(cs::cartesian)
+BOOST_GEOMETRY_REGISTER_BOOST_TUPLE_CS(cs::cartesian)
+
+
+template <typename P, typename T>
+void check_inverse(P const& p, T const& trans)
+{
+ typedef typename bg::coordinate_type<P>::type coordinate_type;
+ const std::size_t dim = bg::dimension<P>::value;
+
+ bg::strategy::transform::inverse_transformer<coordinate_type, dim, dim> inverse(trans);
+
+ P i;
+ bg::transform(p, i, inverse);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(i)), 1.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(i)), 1.0, 0.001);
+}
+
+template <typename P>
+void test_all()
+{
+ typedef typename bg::coordinate_type<P>::type coordinate_type;
+ const std::size_t dim = bg::dimension<P>::value;
+
+ P p;
+ bg::assign_values(p, 1, 1);
+
+ {
+ bg::strategy::transform::translate_transformer<coordinate_type, dim, dim> trans(1, 1);
+ P tp;
+ bg::transform(p, tp, trans);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(tp)), 2.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(tp)), 2.0, 0.001);
+
+ check_inverse(tp, trans);
+ }
+
+ {
+ bg::strategy::transform::scale_transformer<coordinate_type, dim, dim> trans(10, 10);
+ P tp;
+ bg::transform(p, tp, trans);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(tp)), 10.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(tp)), 10.0, 0.001);
+
+ check_inverse(tp, trans);
+ }
+
+ {
+ bg::strategy::transform::rotate_transformer<bg::degree, double, dim, dim> trans(90.0);
+ P tp;
+ bg::transform(p, tp, trans);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(tp)), 1.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(tp)), -1.0, 0.001);
+ check_inverse(tp, trans);
+ }
+
+ {
+ // Map from 0,0,2,2 to 0,0,500,500
+ bg::strategy::transform::map_transformer<coordinate_type, dim, dim, false> trans
+ (
+ 0.0, 0.0, 2.0, 2.0, 500, 500
+ );
+ P tp;
+ bg::transform(p, tp, trans);
+
+ BOOST_CHECK_CLOSE(double(bg::get<0>(tp)), 250.0, 0.001);
+ BOOST_CHECK_CLOSE(double(bg::get<1>(tp)), 250.0, 0.001);
+
+ check_inverse(tp, trans);
+ }
+}
+
+int test_main(int, char* [])
+{
+ //test_all<int[2]>();
+ //test_all<float[2]>();
+ //test_all<double[2]>();
+
+ test_all<boost::tuple<float, float> >();
+
+ //test_all<point<int, 2, cs::cartesian> >();
+ test_all<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_all<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/vincenty.cpp b/src/boost/libs/geometry/test/strategies/vincenty.cpp
new file mode 100644
index 00000000..279db467
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/vincenty.cpp
@@ -0,0 +1,330 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
+// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
+// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
+
+// This file was modified by Oracle on 2014, 2015, 2016, 2017.
+// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
+
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
+// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
+
+// 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 <geometry_test_common.hpp>
+
+#include <boost/concept_check.hpp>
+
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/algorithms/distance.hpp>
+#include <boost/geometry/formulas/vincenty_inverse.hpp>
+#include <boost/geometry/formulas/vincenty_direct.hpp>
+#include <boost/geometry/geometries/point.hpp>
+#include <boost/geometry/srs/spheroid.hpp>
+#include <boost/geometry/strategies/concepts/distance_concept.hpp>
+#include <boost/geometry/strategies/geographic/distance_vincenty.hpp>
+#include <boost/geometry/strategies/geographic/side_vincenty.hpp>
+
+#include <test_common/test_point.hpp>
+
+#ifdef HAVE_TTMATH
+# include <boost/geometry/extensions/contrib/ttmath_stub.hpp>
+#endif
+
+template <typename T>
+void normalize_deg(T & deg)
+{
+ while ( deg > T(180) )
+ deg -= T(360);
+ while ( deg <= T(-180) )
+ deg += T(360);
+}
+
+template <typename T>
+T difference_deg(T const& a1, T const& a2)
+{
+ T d = a1 - a2;
+ normalize_deg(d);
+ return d;
+}
+
+template <typename T>
+void check_deg(std::string const& name, T const& a1, T const& a2, T const& percent, T const& error)
+{
+ T diff = bg::math::abs(difference_deg(a1, a2));
+
+ if ( bg::math::equals(a1, T(0)) || bg::math::equals(a2, T(0)) )
+ {
+ if ( diff > error )
+ {
+ BOOST_ERROR(name << " - the difference {" << diff << "} between {" << a1 << "} and {" << a2 << "} exceeds {" << error << "}");
+ }
+ }
+ else
+ {
+ T greater = (std::max)(bg::math::abs(a1), bg::math::abs(a2));
+
+ if ( diff > greater * percent / T(100) )
+ {
+ BOOST_ERROR(name << " the difference {" << diff << "} between {" << a1 << "} and {" << a2 << "} exceeds {" << percent << "}%");
+ }
+ }
+}
+
+double azimuth(double deg, double min, double sec)
+{
+ min = fabs(min);
+ sec = fabs(sec);
+
+ if ( deg < 0 )
+ {
+ min = -min;
+ sec = -sec;
+ }
+
+ return deg + min/60.0 + sec/3600.0;
+}
+
+double azimuth(double deg, double min)
+{
+ return azimuth(deg, min, 0.0);
+}
+
+template <typename P>
+bool non_precise_ct()
+{
+ typedef typename bg::coordinate_type<P>::type ct;
+ return boost::is_integral<ct>::value || boost::is_float<ct>::value;
+}
+
+template <typename P1, typename P2, typename Spheroid>
+void test_vincenty(double lon1, double lat1, double lon2, double lat2,
+ double expected_distance,
+ double expected_azimuth_12,
+ double /*expected_azimuth_21*/,
+ Spheroid const& spheroid)
+{
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::select_calculation_type<P1, P2, void>::type
+ >::type calc_t;
+
+ calc_t tolerance = non_precise_ct<P1>() || non_precise_ct<P2>() ?
+ 5.0 : 0.001;
+ calc_t error = non_precise_ct<P1>() || non_precise_ct<P2>() ?
+ 1e-5 : 1e-12;
+
+ // formula
+ {
+ double const d2r = bg::math::d2r<double>();
+ double const r2d = bg::math::r2d<double>();
+
+ typedef bg::formula::vincenty_inverse<calc_t, true, true> inverse_formula;
+ typename inverse_formula::result_type
+ result_i = inverse_formula::apply(lon1 * d2r,
+ lat1 * d2r,
+ lon2 * d2r,
+ lat2 * d2r,
+ spheroid);
+ calc_t dist = result_i.distance;
+ calc_t az12 = result_i.azimuth;
+ //calc_t az21 = vi.azimuth21();
+
+ calc_t az12_deg = az12 * r2d;
+ //calc_t az21_deg = az21 * r2d;
+
+ BOOST_CHECK_CLOSE(dist, calc_t(expected_distance), tolerance);
+ check_deg("az12_deg", az12_deg, calc_t(expected_azimuth_12), tolerance, error);
+ //check_deg("az21_deg", az21_deg, calc_t(expected_azimuth_21), tolerance, error);
+
+ typedef bg::formula::vincenty_direct<calc_t> direct_formula;
+ typename direct_formula::result_type
+ result_d = direct_formula::apply(lon1 * d2r,
+ lat1 * d2r,
+ dist,
+ az12,
+ spheroid);
+ calc_t direct_lon2 = result_d.lon2;
+ calc_t direct_lat2 = result_d.lat2;
+ //calc_t direct_az21 = vd.azimuth21();
+
+ calc_t direct_lon2_deg = direct_lon2 * r2d;
+ calc_t direct_lat2_deg = direct_lat2 * r2d;
+ //calc_t direct_az21_deg = direct_az21 * r2d;
+
+ check_deg("direct_lon2_deg", direct_lon2_deg, calc_t(lon2), tolerance, error);
+ check_deg("direct_lat2_deg", direct_lat2_deg, calc_t(lat2), tolerance, error);
+ //check_deg("direct_az21_deg", direct_az21_deg, az21_deg, tolerance, error);
+ }
+
+ // distance strategies
+ {
+ typedef bg::strategy::distance::vincenty<Spheroid> vincenty_type;
+ typedef bg::strategy::distance::geographic<bg::strategy::vincenty, Spheroid> geographic_type;
+
+ BOOST_CONCEPT_ASSERT(
+ (
+ bg::concepts::PointDistanceStrategy<vincenty_type, P1, P2>)
+ );
+
+ vincenty_type vincenty(spheroid);
+ geographic_type geographic(spheroid);
+ typedef typename bg::strategy::distance::services::return_type<vincenty_type, P1, P2>::type return_type;
+
+ P1 p1;
+ P2 p2;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+
+ BOOST_CHECK_CLOSE(vincenty.apply(p1, p2), return_type(expected_distance), tolerance);
+ BOOST_CHECK_CLOSE(geographic.apply(p1, p2), return_type(expected_distance), tolerance);
+ BOOST_CHECK_CLOSE(bg::distance(p1, p2, vincenty), return_type(expected_distance), tolerance);
+ }
+}
+
+template <typename P1, typename P2>
+void test_vincenty(double lon1, double lat1, double lon2, double lat2,
+ double expected_distance,
+ double expected_azimuth_12,
+ double expected_azimuth_21)
+{
+ test_vincenty<P1, P2>(lon1, lat1, lon2, lat2,
+ expected_distance, expected_azimuth_12, expected_azimuth_21,
+ bg::srs::spheroid<double>());
+}
+
+template <typename PS, typename P>
+void test_side(double lon1, double lat1,
+ double lon2, double lat2,
+ double lon, double lat,
+ int expected_side)
+{
+ // Set radius type, but for integer coordinates we want to have floating point radius type
+ typedef typename bg::promote_floating_point
+ <
+ typename bg::coordinate_type<PS>::type
+ >::type rtype;
+
+ typedef bg::srs::spheroid<rtype> stype;
+
+ typedef bg::strategy::side::vincenty<stype> strategy_type;
+ typedef bg::strategy::side::geographic<bg::strategy::vincenty, stype> strategy2_type;
+
+ strategy_type strategy;
+ strategy2_type strategy2;
+
+ PS p1, p2;
+ P p;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+ bg::assign_values(p, lon, lat);
+
+ int side = strategy.apply(p1, p2, p);
+ int side2 = strategy2.apply(p1, p2, p);
+
+ BOOST_CHECK_EQUAL(side, expected_side);
+ BOOST_CHECK_EQUAL(side2, expected_side);
+}
+
+template <typename P1, typename P2>
+void test_all()
+{
+ // See:
+ // - http://www.ga.gov.au/geodesy/datums/vincenty_inverse.jsp
+ // - http://www.ga.gov.au/geodesy/datums/vincenty_direct.jsp
+ // Values in the comments below was calculated using the above pages
+ // in some cases distances may be different, previously used values was left
+
+ // use km
+ double gda_a = 6378.1370;
+ double gda_f = 1.0 / 298.25722210;
+ double gda_b = gda_a * ( 1.0 - gda_f );
+ bg::srs::spheroid<double> gda_spheroid(gda_a, gda_b);
+
+ // Test fractional coordinates only for non-integral types
+ if ( BOOST_GEOMETRY_CONDITION(
+ ! boost::is_integral<typename bg::coordinate_type<P1>::type>::value
+ && ! boost::is_integral<typename bg::coordinate_type<P2>::type>::value ) )
+ {
+ // Flinders Peak -> Buninyong
+ test_vincenty<P1, P2>(azimuth(144,25,29.52440), azimuth(-37,57,3.72030),
+ azimuth(143,55,35.38390), azimuth(-37,39,10.15610),
+ 54.972271, azimuth(306,52,5.37), azimuth(127,10,25.07),
+ gda_spheroid);
+ }
+
+ // Lodz -> Trondheim
+ test_vincenty<P1, P2>(azimuth(19,28), azimuth(51,47),
+ azimuth(10,21), azimuth(63,23),
+ 1399.032724, azimuth(340,54,25.14), azimuth(153,10,0.19),
+ gda_spheroid);
+ // London -> New York
+ test_vincenty<P1, P2>(azimuth(0,7,39), azimuth(51,30,26),
+ azimuth(-74,0,21), azimuth(40,42,46),
+ 5602.044851, azimuth(288,31,36.82), azimuth(51,10,33.43),
+ gda_spheroid);
+
+ // Shanghai -> San Francisco
+ test_vincenty<P1, P2>(azimuth(121,30), azimuth(31,12),
+ azimuth(-122,25), azimuth(37,47),
+ 9899.698550, azimuth(45,12,44.76), azimuth(309,50,20.88),
+ gda_spheroid);
+
+ test_vincenty<P1, P2>(0, 0, 0, 50, 5540.847042, 0, 180, gda_spheroid); // N
+ test_vincenty<P1, P2>(0, 0, 0, -50, 5540.847042, 180, 0, gda_spheroid); // S
+ test_vincenty<P1, P2>(0, 0, 50, 0, 5565.974540, 90, -90, gda_spheroid); // E
+ test_vincenty<P1, P2>(0, 0, -50, 0, 5565.974540, -90, 90, gda_spheroid); // W
+
+ test_vincenty<P1, P2>(0, 0, 50, 50, 7284.879297, azimuth(32,51,55.87), azimuth(237,24,50.12), gda_spheroid); // NE
+
+ // The original distance values, azimuths calculated using the web form mentioned above
+ // Using default spheroid units (meters)
+ test_vincenty<P1, P2>(0, 89, 1, 80, 1005153.5769, azimuth(178,53,23.85), azimuth(359,53,18.35)); // sub-polar
+ test_vincenty<P1, P2>(4, 52, 4, 52, 0.0, 0, 0); // no point difference
+ test_vincenty<P1, P2>(4, 52, 3, 40, 1336039.890, azimuth(183,41,29.08), azimuth(2,58,5.13)); // normal case
+
+ test_side<P1, P2>(0, 0, 0, 1, 0, 2, 0);
+ test_side<P1, P2>(0, 0, 0, 1, 0, -2, 0);
+ test_side<P1, P2>(10, 0, 10, 1, 10, 2, 0);
+ test_side<P1, P2>(10, 0, 10, -1, 10, 2, 0);
+
+ test_side<P1, P2>(10, 0, 10, 1, 0, 2, 1); // left
+ test_side<P1, P2>(10, 0, 10, -1, 0, 2, -1); // right
+
+ test_side<P1, P2>(-10, -10, 10, 10, 10, 0, -1); // right
+ test_side<P1, P2>(-10, -10, 10, 10, -10, 0, 1); // left
+ test_side<P1, P2>(170, -10, -170, 10, -170, 0, -1); // right
+ test_side<P1, P2>(170, -10, -170, 10, 170, 0, 1); // left
+}
+
+template <typename P>
+void test_all()
+{
+ test_all<P, P>();
+}
+
+int test_main(int, char* [])
+{
+ //test_all<float[2]>();
+ //test_all<double[2]>();
+ test_all<bg::model::point<double, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<float, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<int, 2, bg::cs::geographic<bg::degree> > >();
+
+#if defined(HAVE_TTMATH)
+ test_all<bg::model::point<ttmath::Big<1,4>, 2, bg::cs::geographic<bg::degree> > >();
+ test_all<bg::model::point<ttmath_big, 2, bg::cs::geographic<bg::degree> > >();
+#endif
+
+
+ return 0;
+}
diff --git a/src/boost/libs/geometry/test/strategies/winding.cpp b/src/boost/libs/geometry/test/strategies/winding.cpp
new file mode 100644
index 00000000..d19244ae
--- /dev/null
+++ b/src/boost/libs/geometry/test/strategies/winding.cpp
@@ -0,0 +1,218 @@
+// Boost.Geometry (aka GGL, Generic Geometry Library)
+// Unit Test
+
+// Copyright (c) 2010-2012 Barend Gehrels, Amsterdam, the Netherlands.
+
+// This file was modified by Oracle on 2014, 2016.
+// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates.
+// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
+
+// Use, modification and distribution is subject to the Boost Software License,
+// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+
+
+#include <strategies/test_within.hpp>
+
+
+template <typename Point>
+void test_cartesian()
+{
+ typedef bg::model::polygon<Point> polygon;
+
+ std::string const box = "POLYGON((0 0,0 2,2 2,2 0,0 0))";
+ std::string const triangle = "POLYGON((0 0,0 4,6 0,0 0))";
+ std::string const with_hole = "POLYGON((0 0,0 3,3 3,3 0,0 0),(1 1,2 1,2 2,1 2,1 1))";
+
+ bg::strategy::within::winding<Point> s;
+
+
+ test_geometry<Point, polygon>("b1", "POINT(1 1)", box, s, true);
+ test_geometry<Point, polygon>("b2", "POINT(3 3)", box, s, false);
+
+ // Test ALL corners (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b3a", "POINT(0 0)", box, s, false);
+ test_geometry<Point, polygon>("b3b", "POINT(0 2)", box, s, false);
+ test_geometry<Point, polygon>("b3c", "POINT(2 2)", box, s, false);
+ test_geometry<Point, polygon>("b3d", "POINT(2 0)", box, s, false);
+
+ // Test ALL sides (officialy false but some strategies might answer true)
+ test_geometry<Point, polygon>("b4a", "POINT(0 1)", box, s, false);
+ test_geometry<Point, polygon>("b4b", "POINT(1 2)", box, s, false);
+ test_geometry<Point, polygon>("b4c", "POINT(2 1)", box, s, false);
+ test_geometry<Point, polygon>("b4d", "POINT(1 0)", box, s, false);
+
+
+ test_geometry<Point, polygon>("t1", "POINT(1 1)", triangle, s, true);
+ test_geometry<Point, polygon>("t2", "POINT(3 3)", triangle, s, false);
+
+ test_geometry<Point, polygon>("t3a", "POINT(0 0)", triangle, s, false);
+ test_geometry<Point, polygon>("t3b", "POINT(0 4)", triangle, s, false);
+ test_geometry<Point, polygon>("t3c", "POINT(5 0)", triangle, s, false);
+
+ test_geometry<Point, polygon>("t4a", "POINT(0 2)", triangle, s, false);
+ test_geometry<Point, polygon>("t4b", "POINT(3 2)", triangle, s, false);
+ test_geometry<Point, polygon>("t4c", "POINT(2 0)", triangle, s, false);
+
+
+ test_geometry<Point, polygon>("h1", "POINT(0.5 0.5)", with_hole, s, true);
+ test_geometry<Point, polygon>("h2a", "POINT(1.5 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h2b", "POINT(5 5)", with_hole, s, false);
+
+ test_geometry<Point, polygon>("h3a", "POINT(1 1)", with_hole, s, false);
+ test_geometry<Point, polygon>("h3b", "POINT(2 2)", with_hole, s, false);
+ test_geometry<Point, polygon>("h3c", "POINT(0 0)", with_hole, s, false);
+
+ test_geometry<Point, polygon>("h4a", "POINT(1 1.5)", with_hole, s, false);
+ test_geometry<Point, polygon>("h4b", "POINT(1.5 2)", with_hole, s, false);
+
+ // Lying ON (one of the sides of) interior ring
+ test_geometry<Point, polygon>("#77-1", "POINT(6 3.5)",
+ "POLYGON((5 3,5 4,4 4,4 5,3 5,3 6,5 6,5 5,7 5,7 6,8 6,8 5,9 5,9 2,8 2,8 1,7 1,7 2,5 2,5 3),(6 3,8 3,8 4,6 4,6 3))",
+ s, false);
+}
+
+template <typename T>
+void test_spherical()
+{
+ typedef bg::model::point<T, 2, bg::cs::spherical_equatorial<bg::degree> > point;
+ typedef bg::model::polygon<point> polygon;
+
+ bg::strategy::within::winding<point> s;
+
+
+ // Ticket #9354
+ test_geometry<point, polygon>(
+ "#9354",
+ "POINT(-78.1239 25.9556)",
+ "POLYGON((-97.08466667 25.95683333, -97.13683333 25.954, -97.1 26, -97.08466667 25.95683333))",
+ s,
+ false);
+
+ test_geometry<point, polygon>(
+ "sph1N",
+ "POINT(0 10.001)",
+ "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))",
+ s,
+ bg::strategy::side::spherical_side_formula<>::apply(
+ point(-10, 10),
+ point(10, 10),
+ point(0, (T)10.001)) == -1 // right side
+ /*true*/);
+ test_geometry<point, polygon>(
+ "sph1S",
+ "POINT(0 -10.001)",
+ "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))",
+ s,
+ bg::strategy::side::spherical_side_formula<>::apply(
+ point(10, -10),
+ point(-10, -10),
+ point(0, (T)-10.001)) == -1 // right side
+ /*true*/);
+
+ test_geometry<point, polygon>(
+ "sph2S",
+ "POINT(0 10.001)",
+ "POLYGON((-10 20, 10 20, 10 10, -10 10, -10 20))",
+ s,
+ bg::strategy::side::spherical_side_formula<>::apply(
+ point(10, 10),
+ point(-10, 10),
+ point(0, (T)10.001)) == -1 // right side
+ /*false*/);
+
+ test_geometry<point, polygon>(
+ "sph3N",
+ "POINT(0 10)",
+ "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))",
+ s,
+ bg::strategy::side::spherical_side_formula<>::apply(
+ point(-10, 10),
+ point(10, 10),
+ point(0, (T)10.001)) == -1 // right side
+ /*true*/);
+ test_geometry<point, polygon>(
+ "sph3S",
+ "POINT(0 -10)",
+ "POLYGON((-10 10, 10 10, 10 -10, -10 -10, -10 10))",
+ s,
+ bg::strategy::side::spherical_side_formula<>::apply(
+ point(10, -10),
+ point(-10, -10),
+ point(0, (T)-10.001)) == -1 // right side
+ /*true*/);
+
+ test_geometry<point, polygon>(
+ "sphEq1",
+ "POINT(179 10)",
+ "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))",
+ s,
+ true,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq2",
+ "POINT(179 10)",
+ "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))",
+ s,
+ false,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq3",
+ "POINT(-179 10)",
+ "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))",
+ s,
+ true,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq4",
+ "POINT(-179 10)",
+ "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))",
+ s,
+ false,
+ false);
+
+ test_geometry<point, polygon>(
+ "sphEq5",
+ "POINT(169 10)",
+ "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))",
+ s,
+ false,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq6",
+ "POINT(-169 10)",
+ "POLYGON((170 20, -170 20, -170 10, 170 10, 170 20))",
+ s,
+ false,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq7",
+ "POINT(169 10)",
+ "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))",
+ s,
+ false,
+ false);
+ test_geometry<point, polygon>(
+ "sphEq8",
+ "POINT(-169 10)",
+ "POLYGON((170 10, -170 10, -170 0, 170 0, 170 10))",
+ s,
+ false,
+ false);
+}
+
+int test_main(int, char* [])
+{
+ test_cartesian<bg::model::point<float, 2, bg::cs::cartesian> >();
+ test_cartesian<bg::model::point<double, 2, bg::cs::cartesian> >();
+
+ test_spherical<float>();
+ test_spherical<double>();
+
+#if defined(HAVE_TTMATH)
+ test_cartesian<bg::model::point<ttmath_big, 2, bg::cs::cartesian> >();
+ test_spherical<ttmath_big>();
+#endif
+
+ return 0;
+}