summaryrefslogtreecommitdiff
path: root/libs/geometry/test/strategies
diff options
context:
space:
mode:
Diffstat (limited to 'libs/geometry/test/strategies')
-rw-r--r--libs/geometry/test/strategies/Jamfile.v214
-rw-r--r--libs/geometry/test/strategies/andoyer.cpp108
-rw-r--r--libs/geometry/test/strategies/distance_default_result.cpp36
-rw-r--r--libs/geometry/test/strategies/douglas_peucker.cpp422
-rw-r--r--libs/geometry/test/strategies/pythagoras.cpp24
-rw-r--r--libs/geometry/test/strategies/pythagoras_point_box.cpp28
-rw-r--r--libs/geometry/test/strategies/side_of_intersection.cpp61
-rw-r--r--libs/geometry/test/strategies/spherical_side.cpp37
-rw-r--r--libs/geometry/test/strategies/vincenty.cpp271
9 files changed, 951 insertions, 50 deletions
diff --git a/libs/geometry/test/strategies/Jamfile.v2 b/libs/geometry/test/strategies/Jamfile.v2
index d32c10737..beb772b2a 100644
--- a/libs/geometry/test/strategies/Jamfile.v2
+++ b/libs/geometry/test/strategies/Jamfile.v2
@@ -1,11 +1,11 @@
# Boost.Geometry (aka GGL, Generic Geometry Library)
#
-# Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
-# Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
-# Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
+# 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.
-# Modifications copyright (c) 2014, Oracle and/or its affiliates.
+# This file was modified by Oracle on 2014, 2015.
+# Modifications copyright (c) 2014-2015, 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
@@ -16,9 +16,11 @@
test-suite boost-geometry-strategies
:
+ [ run andoyer.cpp ]
[ run cross_track.cpp ]
[ run crossings_multiply.cpp ]
[ run distance_default_result.cpp ]
+ [ run douglas_peucker.cpp ]
[ run franklin.cpp ]
[ run haversine.cpp ]
[ run point_in_box.cpp ]
@@ -28,7 +30,9 @@ test-suite boost-geometry-strategies
[ run pythagoras_point_box.cpp ]
[ run spherical_side.cpp ]
[ run segment_intersection_collinear.cpp ]
+ [ run side_of_intersection.cpp ]
[ run transform_cs.cpp ]
[ run transformer.cpp ]
+ [ run vincenty.cpp ]
[ run winding.cpp ]
;
diff --git a/libs/geometry/test/strategies/andoyer.cpp b/libs/geometry/test/strategies/andoyer.cpp
new file mode 100644
index 000000000..c1fe0293b
--- /dev/null
+++ b/libs/geometry/test/strategies/andoyer.cpp
@@ -0,0 +1,108 @@
+// 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.
+// Modifications copyright (c) 2014 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/strategies/geographic/distance_andoyer.hpp>
+
+#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/geometries/point.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_andoyer(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;
+
+ BOOST_CONCEPT_ASSERT
+ (
+ (bg::concept::PointDistanceStrategy<andoyer_type, P1, P2>)
+ );
+
+ andoyer_type andoyer;
+ typedef typename bg::strategy::distance
+ ::services::return_type<andoyer_type, P1, P2>::type return_type;
+
+
+ P1 p1, p2;
+
+ bg::assign_values(p1, lon1, lat1);
+ bg::assign_values(p2, lon2, lat2);
+
+ BOOST_CHECK_CLOSE(andoyer.apply(p1, p2), return_type(1000.0 * expected_km), 0.001);
+ BOOST_CHECK_CLOSE(bg::distance(p1, p2, andoyer), return_type(1000.0 * expected_km), 0.001);
+}
+
+template <typename P1, typename P2>
+void test_all()
+{
+ test_andoyer<P1, P2>(0, 90, 1, 80, 1116.814237); // polar
+ test_andoyer<P1, P2>(4, 52, 4, 52, 0.0); // no point difference
+ test_andoyer<P1, P2>(4, 52, 3, 40, 1336.039890); // normal case
+
+ /* 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))
+ */
+}
+
+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/libs/geometry/test/strategies/distance_default_result.cpp b/libs/geometry/test/strategies/distance_default_result.cpp
index 40315d207..e862d3313 100644
--- a/libs/geometry/test/strategies/distance_default_result.cpp
+++ b/libs/geometry/test/strategies/distance_default_result.cpp
@@ -180,7 +180,7 @@ struct test_distance_result_box
//=========================================================================
-template <std::size_t D, typename CS>
+template <std::size_t D, typename CoordinateSystem>
inline void test_segment_all()
{
#if defined(HAVE_TTMATH)
@@ -189,32 +189,32 @@ inline void test_segment_all()
#endif
typedef typename boost::mpl::if_
<
- typename boost::is_same<CS, bg::cs::cartesian>::type,
+ typename boost::is_same<CoordinateSystem, bg::cs::cartesian>::type,
double,
float
>::type float_return_type;
- test_distance_result_segment<short, short, D, CS, double>();
- test_distance_result_segment<int, int, D, CS, double>();
- test_distance_result_segment<int, long, D, CS, double>();
- test_distance_result_segment<long, long, D, CS, double>();
+ 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, CS, float_return_type>();
- test_distance_result_segment<float, float, D, CS, float_return_type>();
+ 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, CS, double>();
- test_distance_result_segment<double, int, D, CS, double>();
- test_distance_result_segment<float, double, D, CS, double>();
- test_distance_result_segment<double, float, D, CS, double>();
- test_distance_result_segment<double, double, D, CS, double>();
+ 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, CS, tt>();
- test_distance_result_segment<tt, default_integral, D, CS, tt>();
+ 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, CS, tt>();
- test_distance_result_segment<tt, double, D, CS, tt>();
- test_distance_result_segment<tt, tt, D, CS, 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
}
diff --git a/libs/geometry/test/strategies/douglas_peucker.cpp b/libs/geometry/test/strategies/douglas_peucker.cpp
new file mode 100644
index 000000000..b8b09f348
--- /dev/null
+++ b/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/assign/list_of.hpp>
+#include <boost/core/ignore_unused.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/tuple/tuple.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>
+
+
+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/libs/geometry/test/strategies/pythagoras.cpp b/libs/geometry/test/strategies/pythagoras.cpp
index b8bcfed3c..3b81bf144 100644
--- a/libs/geometry/test/strategies/pythagoras.cpp
+++ b/libs/geometry/test/strategies/pythagoras.cpp
@@ -20,7 +20,6 @@
#endif
#include <boost/timer.hpp>
-#include <boost/typeof/typeof.hpp>
#include <boost/concept/requires.hpp>
#include <boost/concept_check.hpp>
@@ -239,21 +238,28 @@ void test_integer(bool check_types)
bg::assign_values(p2, 98765432, 87654321);
typedef bg::strategy::distance::pythagoras<> pythagoras_type;
- pythagoras_type pythagoras;
- BOOST_AUTO(distance, pythagoras.apply(p1, p2));
- BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
-
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;
- BOOST_AUTO(cdistance, comparable.apply(p1, p2));
+ cdistance_type cdistance = comparable.apply(p1, p2);
BOOST_CHECK_EQUAL(cdistance, 11589696996311540);
- typedef BOOST_TYPEOF(cdistance) cdistance_type;
- typedef BOOST_TYPEOF(distance) distance_type;
-
distance_type distance2 = sqrt(distance_type(cdistance));
BOOST_CHECK_CLOSE(distance, distance2, 0.001);
diff --git a/libs/geometry/test/strategies/pythagoras_point_box.cpp b/libs/geometry/test/strategies/pythagoras_point_box.cpp
index d11e96e1c..9b1e817f3 100644
--- a/libs/geometry/test/strategies/pythagoras_point_box.cpp
+++ b/libs/geometry/test/strategies/pythagoras_point_box.cpp
@@ -29,7 +29,6 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/timer.hpp>
-#include <boost/typeof/typeof.hpp>
#include <boost/concept/requires.hpp>
#include <boost/concept_check.hpp>
@@ -336,22 +335,29 @@ inline void test_integer(bool check_types)
bg::assign_values(b, 0, 0, 12345678, 23456789);
bg::assign_values(p, 98765432, 87654321);
- typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_pb_type;
- pythagoras_pb_type pythagoras_pb;
- BOOST_AUTO(distance, pythagoras_pb.apply(p, b));
- BOOST_CHECK_CLOSE(distance, 107655455.02347542, 0.001);
-
+ typedef bg::strategy::distance::pythagoras_point_box<> pythagoras_type;
typedef typename bg::strategy::distance::services::comparable_type
<
- pythagoras_pb_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;
- BOOST_AUTO(cdistance, comparable.apply(p, b));
+ cdistance_type cdistance = comparable.apply(p, b);
BOOST_CHECK_EQUAL(cdistance, 11589696996311540);
- typedef BOOST_TYPEOF(cdistance) cdistance_type;
- typedef BOOST_TYPEOF(distance) distance_type;
-
distance_type distance2 = sqrt(distance_type(cdistance));
BOOST_CHECK_CLOSE(distance, distance2, 0.001);
diff --git a/libs/geometry/test/strategies/side_of_intersection.cpp b/libs/geometry/test/strategies/side_of_intersection.cpp
new file mode 100644
index 000000000..c5de7e0ea
--- /dev/null
+++ b/libs/geometry/test/strategies/side_of_intersection.cpp
@@ -0,0 +1,61 @@
+// 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<int> point;
+ typedef bg::model::segment<point> segment;
+
+ 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));
+
+ typedef bg::strategy::side::side_of_intersection side;
+
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b1, c1));
+ BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c2));
+ BOOST_CHECK_EQUAL(-1, side::apply(a, b1, c3));
+
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c1));
+ BOOST_CHECK_EQUAL( 1, side::apply(a, b2, c2));
+ BOOST_CHECK_EQUAL( 0, side::apply(a, b2, c3));
+
+ // Check internal calculation-method:
+ BOOST_CHECK_EQUAL(-1400, side::side_value<int>(a, b1, c2));
+ BOOST_CHECK_EQUAL( 2800, side::side_value<int>(a, b1, c1));
+
+ BOOST_CHECK_EQUAL (2800, side::side_value<int>(a, b1, c1));
+ BOOST_CHECK_EQUAL(-1400, side::side_value<int>(a, b1, c2));
+ BOOST_CHECK_EQUAL(-5600, side::side_value<int>(a, b1, c3));
+
+ BOOST_CHECK_EQUAL(12800, side::side_value<int>(a, b2, c1));
+ BOOST_CHECK_EQUAL( 6400, side::side_value<int>(a, b2, c2));
+ BOOST_CHECK_EQUAL( 0, side::side_value<int>(a, b2, c3));
+
+ // 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/libs/geometry/test/strategies/spherical_side.cpp b/libs/geometry/test/strategies/spherical_side.cpp
index a183a141b..6965692ea 100644
--- a/libs/geometry/test/strategies/spherical_side.cpp
+++ b/libs/geometry/test/strategies/spherical_side.cpp
@@ -3,6 +3,11 @@
// Copyright (c) 2007-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)
@@ -19,6 +24,9 @@
#include <boost/geometry/strategies/spherical/ssf.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
+#include <boost/geometry/strategies/agnostic/side_by_azimuth.hpp>
+#include <boost/geometry/strategies/geographic/mapping_ssf.hpp>
+
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/geometries/point.hpp>
@@ -47,22 +55,37 @@ inline char side_char(int side)
}
template <typename Point>
-void test_side1(std::string const& case_id, Point const& p1, Point const& p2, Point const& p3,
+void test_side1(std::string const& /*case_id*/, Point const& p1, Point const& p2, Point const& p3,
int expected, int expected_cartesian)
{
- // std::cout << case_id << ": ";
- //int s = bg::strategy::side::side_via_plane<>::apply(p1, p2, p3);
- int side_ssf = bg::strategy::side::spherical_side_formula<>::apply(p1, p2, p3);
- //int side2 = bg::strategy::side::side_via_plane<>::apply(p1, p2, p3);
- int side_ct = bg::strategy::side::side_by_cross_track<>::apply(p1, p2, p3);
+ 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_azi = bgss::side_by_azimuth<spheroid>(sph).apply(p1, p2, p3);
+ 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);
+
+ // 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_azi, expected);
+ BOOST_CHECK_EQUAL(side_mssf1, expected);
+ BOOST_CHECK_EQUAL(side_mssf2, expected);
+ BOOST_CHECK_EQUAL(side_mssf3, expected);
BOOST_CHECK_EQUAL(side_cart, expected_cartesian);
+
/*
std::cout
<< "exp: " << side_char(expected)
diff --git a/libs/geometry/test/strategies/vincenty.cpp b/libs/geometry/test/strategies/vincenty.cpp
new file mode 100644
index 000000000..b80da4bb5
--- /dev/null
+++ b/libs/geometry/test/strategies/vincenty.cpp
@@ -0,0 +1,271 @@
+// 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.
+// Modifications copyright (c) 2014 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/strategies/geographic/distance_vincenty.hpp>
+#include <boost/geometry/algorithms/detail/vincenty_inverse.hpp>
+#include <boost/geometry/algorithms/detail/vincenty_direct.hpp>
+
+#include <boost/geometry/core/srs.hpp>
+#include <boost/geometry/strategies/strategies.hpp>
+#include <boost/geometry/algorithms/assign.hpp>
+#include <boost/geometry/geometries/point.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
+ {
+ bg::detail::vincenty_inverse<calc_t> vi(lon1 * bg::math::d2r,
+ lat1 * bg::math::d2r,
+ lon2 * bg::math::d2r,
+ lat2 * bg::math::d2r,
+ spheroid);
+ calc_t dist = vi.distance();
+ calc_t az12 = vi.azimuth12();
+ calc_t az21 = vi.azimuth21();
+
+ calc_t az12_deg = az12 * bg::math::r2d;
+ calc_t az21_deg = az21 * bg::math::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);
+
+ bg::detail::vincenty_direct<calc_t> vd(lon1 * bg::math::d2r,
+ lat1 * bg::math::d2r,
+ dist,
+ az12,
+ spheroid);
+ calc_t direct_lon2 = vd.lon2();
+ calc_t direct_lat2 = vd.lat2();
+ calc_t direct_az21 = vd.azimuth21();
+
+ calc_t direct_lon2_deg = direct_lon2 * bg::math::r2d;
+ calc_t direct_lat2_deg = direct_lat2 * bg::math::r2d;
+ calc_t direct_az21_deg = direct_az21 * bg::math::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);
+ }
+
+ // strategy
+ {
+ typedef bg::strategy::distance::vincenty<Spheroid> vincenty_type;
+
+ BOOST_CONCEPT_ASSERT(
+ (
+ bg::concept::PointDistanceStrategy<vincenty_type, P1, P2>)
+ );
+
+ vincenty_type vincenty(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(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 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
+}
+
+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;
+}