From e4a587c0f4a3f7fbb36ae18a09e5f643dd743089 Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Fri, 1 Dec 2017 14:58:16 +0200 Subject: [PATCH] [strategies] [tests] Test degenerate pt/box and box/box cases; fix a bug in pt-sgmt distance strategy --- example/test/segment_pt_swap_bug.cpp | 38 +++++++ .../geometry/formulas/elliptic_arc_length.hpp | 3 +- .../strategies/geographic/distance.hpp | 6 +- .../geographic/distance_cross_track.hpp | 11 +++ .../util/normalize_spheroidal_coordinates.hpp | 2 +- .../distance/distance_geo_box_box.cpp | 80 ++++++++++++++- .../algorithms/distance/distance_geo_pl_l.cpp | 98 +++++++++---------- .../distance/distance_geo_point_box.cpp | 54 +++++++++- .../distance/test_distance_geo_common.hpp | 74 ++++++++++++-- 9 files changed, 301 insertions(+), 65 deletions(-) create mode 100644 example/test/segment_pt_swap_bug.cpp diff --git a/example/test/segment_pt_swap_bug.cpp b/example/test/segment_pt_swap_bug.cpp new file mode 100644 index 000000000..76cd9a236 --- /dev/null +++ b/example/test/segment_pt_swap_bug.cpp @@ -0,0 +1,38 @@ +#include +#include + + +#define BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK +#include + +namespace bg = boost::geometry; + +int main() +{ + //Spherical pt-box and box-box + { + double const earth_radius = 6372795; + typedef bg::model::point > point; + + typedef bg::model::segment segment; + + std::cout << "ps1=" << bg::distance(segment(point(0,2),point(0,3)), point(2.5,3)) << std::endl; + std::cout << "ps2=" << bg::distance(segment(point(0,3),point(0,2)), point(2.5,3)) << std::endl; + + } + //Geo pt-box and box-box + { + typedef bg::model::point > point; + + typedef bg::model::segment segment; + + std::cout << "ps1=" << bg::distance(segment(point(2,0),point(3,0)), point(2.5,3)) << std::endl; + std::cout << "ps2=" << bg::distance(segment(point(3,0),point(2,0)), point(2.5,3)) << std::endl; + + } + + return 0; +} + diff --git a/include/boost/geometry/formulas/elliptic_arc_length.hpp b/include/boost/geometry/formulas/elliptic_arc_length.hpp index 75881f3d0..561e79e75 100644 --- a/include/boost/geometry/formulas/elliptic_arc_length.hpp +++ b/include/boost/geometry/formulas/elliptic_arc_length.hpp @@ -65,7 +65,8 @@ public : (math::equals(lat2, half_pi) && math::equals(lat1, -half_pi)) ) { // single meridian not crossing pole - res.distance = apply(lat2, spheroid) - apply(lat1, spheroid); + res.distance = apply(lat2, spheroid) + - apply(lat1, spheroid); res.meridian = true; } diff --git a/include/boost/geometry/strategies/geographic/distance.hpp b/include/boost/geometry/strategies/geographic/distance.hpp index aa7d4348f..c8cd74b89 100644 --- a/include/boost/geometry/strategies/geographic/distance.hpp +++ b/include/boost/geometry/strategies/geographic/distance.hpp @@ -76,7 +76,7 @@ public : template static inline CT apply(CT lon1, CT lat1, CT lon2, CT lat2, - Spheroid const& spheroid) const + Spheroid const& spheroid) { typedef typename formula::elliptic_arc_length < @@ -120,8 +120,8 @@ public : CT, strategy::default_order::value > elliptic_arc_length; - return elliptic_arc_length::apply(lat2, m_spheroid) - - elliptic_arc_length::apply(lat1, m_spheroid); + return math::abs(elliptic_arc_length::apply(lat2, m_spheroid) + - elliptic_arc_length::apply(lat1, m_spheroid)); } inline Spheroid const& model() const diff --git a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp index 8c58badd4..4777ea016 100644 --- a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp @@ -242,6 +242,12 @@ private : { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK std::cout << "Equatorial segment" << std::endl; + std::cout << "segment=(" << lon1 * math::r2d(); + std::cout << "," << lat1 * math::r2d(); + std::cout << "),(" << lon2 * math::r2d(); + std::cout << "," << lat2 * math::r2d(); + std::cout << ")\np=(" << lon3 * math::r2d(); + std::cout << "," << lat3 * math::r2d() << ")\n"; #endif if (lon3 <= lon1) { @@ -254,6 +260,11 @@ private : return non_iterative_case(lon3, lat1, lon3, lat3, spheroid); } + if ((lon1 == lon2 || math::equals(math::abs(diff), pi) )&& lat1 > lat2) + { + std::swap(lat1,lat2); + } + if (math::equals(math::abs(diff), pi)) { #ifdef BOOST_GEOMETRY_DEBUG_GEOGRAPHIC_CROSS_TRACK diff --git a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp index eaa686ed1..96905888d 100644 --- a/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp +++ b/include/boost/geometry/util/normalize_spheroidal_coordinates.hpp @@ -198,7 +198,7 @@ template struct latitude_convert_if_polar { template - static inline void apply(T & lat) {} + static inline void apply(T &) {} }; template diff --git a/test/algorithms/distance/distance_geo_box_box.cpp b/test/algorithms/distance/distance_geo_box_box.cpp index 01ac3c97f..c44816e3c 100644 --- a/test/algorithms/distance/distance_geo_box_box.cpp +++ b/test/algorithms/distance/distance_geo_box_box.cpp @@ -21,7 +21,6 @@ #include "test_distance_geo_common.hpp" - typedef bg::cs::geographic cs_type; typedef bg::model::point point_type; typedef bg::model::segment segment_type; @@ -96,7 +95,7 @@ ps_distance(std::string const& wkt1, segment_type s; bg::read_wkt(wkt1, p); bg::read_wkt(wkt2, s); - return bg::distance(p, s); + return bg::distance(p, s, strategy); } //=========================================================================== @@ -456,11 +455,86 @@ void test_distance_box_box_negative(Strategy_pp const& strategy_pp, strategy_bb); } +template +void test_distance_box_box_deg(Strategy_pp const& strategy_pp, + Strategy_ps const& strategy_ps, + Strategy_pb const& strategy_bb) +{ + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "box/box distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + //--- + //1st box degenerates to a meridian segment + std::string const box1 = "BOX(0 10,0 20)"; + + //2nd box generic + tester::apply("pbd1", box1, "BOX(1 15, 2 25)", + ps_distance("POINT(0 20)", "SEGMENT(1 15, 1 25)", strategy_ps), + strategy_bb); + + //2nd box degenerates to a meridian segment + tester::apply("pbd2", box1, "BOX(1 15, 1 25)", + ps_distance("POINT(0 20)", "SEGMENT(1 15, 1 25)", strategy_ps), + strategy_bb); + + //2nd box degenerates to a horizontal line + //test fails for thomas strategy; test only for andoyer + tester::apply("pbd3", box1, "BOX(1 15, 2 15)", + pp_distance("POINT(1 15)", "POINT(0 15)", andoyer_pp()), + andoyer_bb()); + + //2nd box degenerates to a point + tester::apply("pbd4", box1, "BOX(1 15, 1 15)", + ps_distance("POINT(1 15)", "SEGMENT(0 10, 0 20)", strategy_ps), + strategy_bb); + + //--- + //1st box degenerates to a horizontal line; that is not a geodesic segment + std::string const box2 = "BOX(10 10,20 10)"; + + //2nd box generic + tester::apply("pbd5", box2, "BOX(15 15, 25 20)", + pp_distance("POINT(15 15)", "POINT(15 10)", strategy_pp), + strategy_bb); + + //2nd box degenerates to a horizontal line + tester::apply("pbd6", box2, "BOX(15 15, 25 15)", + pp_distance("POINT(15 15)", "POINT(15 10)", strategy_pp), + strategy_bb); + + //2nd box degenerates to a point + tester::apply("pbd7", box2, "BOX(15 15, 15 15)", + pp_distance("POINT(15 15)", "POINT(15 10)", strategy_pp), + strategy_bb); + + //--- + //1st box degenerates to a point + std::string const box3 = "BOX(0 6,0 6)"; + + //2nd box generic + tester::apply("pbd8", box3, "BOX(15 15, 25 20)", + ps_distance("POINT(0 6)", "SEGMENT(15 15, 15 20)", strategy_ps), + strategy_bb); + + //2nd box degenerates to a point + tester::apply("pbd9", box3, "BOX(15 15, 15 15)", + pp_distance("POINT(0 6)", "POINT(15 15)", strategy_pp), + strategy_bb); +} + //=========================================================================== BOOST_AUTO_TEST_CASE( test_all_point_segment ) { test_distance_box_box(vincenty_pp(), vincenty_ps(), vincenty_bb()); - //test_distance_box_box(thomas_pp(), thomas_ps(), thomas_bb()); + test_distance_box_box(thomas_pp(), thomas_ps(), thomas_bb()); test_distance_box_box(andoyer_pp(), andoyer_ps(), andoyer_bb()); + + test_distance_box_box_deg(vincenty_pp(), vincenty_ps(), vincenty_bb()); + test_distance_box_box_deg(thomas_pp(), thomas_ps(), thomas_bb()); + test_distance_box_box_deg(andoyer_pp(), andoyer_ps(), andoyer_bb()); } diff --git a/test/algorithms/distance/distance_geo_pl_l.cpp b/test/algorithms/distance/distance_geo_pl_l.cpp index 4fff9da4d..b7417bf57 100644 --- a/test/algorithms/distance/distance_geo_pl_l.cpp +++ b/test/algorithms/distance/distance_geo_pl_l.cpp @@ -91,243 +91,243 @@ void test_distance_point_segment(Strategy_pp const& strategy_pp, "POINT(0 0)", "SEGMENT(2 0,3 0)", pp_distance("POINT(0 0)", "POINT(2 0)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-02", "POINT(2.5 3)", "SEGMENT(2 0,3 0)", pp_distance("POINT(2.5 3)", "POINT(2.49777 0)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-03", "POINT(2 0)", "SEGMENT(2 0,3 0)", 0, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-04", "POINT(3 0)", "SEGMENT(2 0,3 0)", 0, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-05", "POINT(2.5 0)", "SEGMENT(2 0,3 0)", 0, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-06", "POINT(3.5 3)", "SEGMENT(2 0,3 0)", pp_distance("POINT(3 0)", "POINT(3.5 3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-07", "POINT(15 80)", "SEGMENT(10 15,30 15)", 7204174.8264546748, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-08", "POINT(15 10)", "SEGMENT(10 15,30 15)", 571412.71247283253, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-09", "POINT(5 10)", "SEGMENT(10 15,30 15)", pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-10", "POINT(35 10)", "SEGMENT(10 15,30 15)", pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-11", "POINT(5 10)", "SEGMENT(30 15,10 15)", pp_distance("POINT(5 10)", "POINT(10 15)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-12", "POINT(35 10)", "SEGMENT(30 15,10 15)", pp_distance("POINT(35 10)", "POINT(30 15)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-right-up", "POINT(3.5 3)", "SEGMENT(2 2,3 2)", pp_distance("POINT(3 2)", "POINT(3.5 3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-left-up", "POINT(1.5 3)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2 2)", "POINT(1.5 3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-up-1", "POINT(2 3)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2.0003 2)", "POINT(2 3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-up-2", "POINT(3 3)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2.9997 2)", "POINT(3 3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-right-down", "POINT(3.5 1)", "SEGMENT(2 2,3 2)", pp_distance("POINT(3 2)", "POINT(3.5 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-left-down", "POINT(1.5 1)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2 2)", "POINT(1.5 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-down-1", "POINT(2 1)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2.0003 2)", "POINT(2 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-down-2", "POINT(3 1)", "SEGMENT(2 2,3 2)", pp_distance("POINT(2.9997 2)", "POINT(3 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-south", "POINT(3 -1)", "SEGMENT(2 -2,3 -2)", pp_distance("POINT(2.9997 -2)", "POINT(3 -1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-antimeridian-1", "POINT(3 1)", "SEGMENT(220 2,3 2)", pp_distance("POINT(3 2)", "POINT(3 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-antimeridian-2", "POINT(220 1)", "SEGMENT(220 2,3 2)", pp_distance("POINT(220 2)", "POINT(220 1)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // equator special case tester::apply("p-s-eq1", "POINT(2.5 0)", "SEGMENT(2 0,3 0)", 0, - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-eq2", "POINT(2.5 2)", "SEGMENT(2 0,3 0)", pp_distance("POINT(2.5 0)", "POINT(2.5 2)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-eq3", "POINT(2 2)", "SEGMENT(2 0,3 0)", pp_distance("POINT(2 0)", "POINT(2 2)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-eq4", "POINT(3 2)", "SEGMENT(2 0,3 0)", pp_distance("POINT(3 0)", "POINT(3 2)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // meridian special case tester::apply("p-s-mer1", "POINT(2.5 2)", "SEGMENT(2 2,2 4)", pp_distance("POINT(2.5 2)", "POINT(2 2)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-mer3", "POINT(2.5 5)", "SEGMENT(2 2,2 4)", pp_distance("POINT(2.5 5)", "POINT(2 4)", strategy_pp), - strategy_ps); + strategy_ps, true, true); //degenerate segment tester::apply("p-s-deg", "POINT(1 80)", "SEGMENT(0 0,0 0)", pp_distance("POINT(0 0)", "POINT(1 80)", strategy_pp), - strategy_ps); + strategy_ps, true, true); //point on segment tester::apply("p-s-deg", "POINT(0 80)", "SEGMENT(0 0,0 90)", 0, - strategy_ps); + strategy_ps, true, true); // very small distances to segment tester::apply("p-s-07", "POINT(90 1e-3)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-3)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-08", "POINT(90 1e-4)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-4)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-09", "POINT(90 1e-5)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-5)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-10", "POINT(90 1e-6)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-6)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-11", "POINT(90 1e-7)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-7)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-12", "POINT(90 1e-8)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 1e-8)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // very large distance to segment tester::apply("p-s-13", "POINT(90 90)", "SEGMENT(0.5 0,175.5 0)", pp_distance("POINT(90 0)", "POINT(90 90)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-14", "POINT(90 90)", "SEGMENT(0.5 -89,175.5 -89)", pp_distance("POINT(90 -89)", "POINT(90 90)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // degenerate segment tester::apply("p-s-15", "POINT(90 90)", "SEGMENT(0.5 -90,175.5 -90)", pp_distance("POINT(0.5 -90)", "POINT(90 90)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-16", "POINT(90 90)", "SEGMENT(0.5 -90,175.5 -90)", pp_distance("POINT(90 -90)", "POINT(90 90)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // equatorial segment tester::apply("p-s-17", "POINT(90 90)", "SEGMENT(0 0,175.5 0)", pp_distance("POINT(90 90)", "POINT(0 0)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // segment pass by pole tester::apply("p-s-18", "POINT(90 90)", "SEGMENT(0 0,180 0)", 0, - strategy_ps); + strategy_ps, true, true); } @@ -349,32 +349,32 @@ void test_distance_point_segment_no_thomas(Strategy_pp const& strategy_pp, "POINT(2.5 3)", "SEGMENT(2 2,2 4)", pp_distance("POINT(2.5 3)", "POINT(2 3.000114792872075)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-mer4", "POINT(1 80)", "SEGMENT(0 0,0 90)", pp_distance("POINT(1 80)", "POINT(0 80.00149225834545)", strategy_pp), - strategy_ps); + strategy_ps, true, true); // Half meridian segment passing through pole tester::apply("p-s-19", "POINT(90 89)", "SEGMENT(0 0,180 0)", pp_distance("POINT(90 89)", "POINT(90 90)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-20", "POINT(80 89)", "SEGMENT(0 0,180 0)", pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp), - strategy_ps); + strategy_ps, true, true); tester::apply("p-s-20", "POINT(80 89)", "SEGMENT(0 -1,180 1)", pp_distance("POINT(80 89)", "POINT(0 89.82633489283377)", strategy_pp), - strategy_ps); + strategy_ps, true, true); } //=========================================================================== @@ -671,7 +671,7 @@ BOOST_AUTO_TEST_CASE( test_all_point_segment ) test_distance_point_segment(andoyer_pp(), andoyer_strategy()); test_distance_point_segment_no_thomas(vincenty_pp(), vincenty_strategy()); - //test_distance_point_segment_no_thomas(thomas_pp(), thomas_strategy()); + ///test_distance_point_segment_no_thomas(thomas_pp(), thomas_strategy()); test_distance_point_segment_no_thomas(andoyer_pp(), andoyer_strategy()); test_distance_point_linestring(vincenty_pp(), vincenty_strategy()); diff --git a/test/algorithms/distance/distance_geo_point_box.cpp b/test/algorithms/distance/distance_geo_point_box.cpp index 7f92d14e8..c21288fb8 100644 --- a/test/algorithms/distance/distance_geo_point_box.cpp +++ b/test/algorithms/distance/distance_geo_point_box.cpp @@ -23,7 +23,6 @@ #include "test_distance_geo_common.hpp" - typedef bg::cs::geographic cs_type; typedef bg::model::point point_type; typedef bg::model::segment segment_type; @@ -371,6 +370,55 @@ void test_distance_point_box(Strategy_pp const& strategy_pp, strategy_pb); } +template +void test_distance_point_deg_box(Strategy_pp const& strategy_pp, + Strategy_ps const& strategy_ps, + Strategy_pb const& strategy_pb) +{ + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/box distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + //box degenerates to a meridian segment + std::string const box1 = "BOX(0 10,0 20)"; + + tester::apply("pbd1", "POINT(1 10)", box1, + ps_distance("POINT(1 10)", "SEGMENT(0 10, 0 20)", strategy_ps), + strategy_pb); + tester::apply("pbd2", "POINT(1 5)", box1, + ps_distance("POINT(1 5)", "SEGMENT(0 10, 0 20)", strategy_ps), + strategy_pb); + tester::apply("pbd3", "POINT(1 15)", box1, + ps_distance("POINT(1 15)", "SEGMENT(0 10, 0 20)", strategy_ps), + strategy_pb); + tester::apply("pbd4", "POINT(1 25)", box1, + ps_distance("POINT(1 25)", "SEGMENT(0 10, 0 20)", strategy_ps), + strategy_pb); + + //box degenerates to a horizontal line; that is not a geodesic segment + std::string const box2 = "BOX(10 10,20 10)"; + + tester::apply("pbd5", "POINT(15 15)", box2, + pp_distance("POINT(15 15)", "POINT(15 10)", strategy_pp), + strategy_pb); + tester::apply("pbd6", "POINT(5 15)", box2, + pp_distance("POINT(5 15)", "POINT(10 10)", strategy_pp), + strategy_pb); + tester::apply("pbd7", "POINT(25 15)", box2, + pp_distance("POINT(25 15)", "POINT(20 10)", strategy_pp), + strategy_pb); + + //box degenerates to a point + std::string const box3 = "BOX(0 10,0 10)"; + + tester::apply("pbd8", "POINT(1 11)", box3, + pp_distance("POINT(1 11)", "POINT(0 10)", strategy_pp), + strategy_pb); +} + //=========================================================================== //=========================================================================== //=========================================================================== @@ -380,4 +428,8 @@ BOOST_AUTO_TEST_CASE( test_all_point_segment ) test_distance_point_box(vincenty_pp(), vincenty_ps(), vincenty_pb()); test_distance_point_box(thomas_pp(), thomas_ps(), thomas_pb()); test_distance_point_box(andoyer_pp(), andoyer_ps(), andoyer_pb()); + + test_distance_point_deg_box(vincenty_pp(), vincenty_ps(), vincenty_pb()); + test_distance_point_deg_box(thomas_pp(), thomas_ps(), thomas_pb()); + test_distance_point_deg_box(andoyer_pp(), andoyer_ps(), andoyer_pb()); } diff --git a/test/algorithms/distance/test_distance_geo_common.hpp b/test/algorithms/distance/test_distance_geo_common.hpp index f1a06e0a2..a81af7ad1 100644 --- a/test/algorithms/distance/test_distance_geo_common.hpp +++ b/test/algorithms/distance/test_distance_geo_common.hpp @@ -44,6 +44,35 @@ namespace bg = ::boost::geometry; +//=================================================================== +//tag dispatching for swaping arguments in segments + +template struct dispatch +{ + template + static inline T swap(T const& t) + { + return t; + } +}; + +// Specialization for segments +template <> struct dispatch +{ + template + static inline Segment swap(Segment const& s) + { + Segment s_swaped; + + bg::set<0, 0>(s_swaped, bg::get<1, 0>(s)); + bg::set<0, 1>(s_swaped, bg::get<1, 1>(s)); + bg::set<1, 0>(s_swaped, bg::get<0, 0>(s)); + bg::set<1, 1>(s_swaped, bg::get<0, 1>(s)); + + return s_swaped; + } +}; + //======================================================================== @@ -103,14 +132,15 @@ struct test_distance_of_geometries std::string const& wkt2, DistanceType const& expected_distance, Strategy const& strategy, - bool test_reversed = true) + bool test_reversed = true, + bool swap_geometry_args = false) { Geometry1 geometry1 = from_wkt(wkt1); Geometry2 geometry2 = from_wkt(wkt2); apply(case_id, geometry1, geometry2, expected_distance, - strategy, test_reversed); + strategy, test_reversed, swap_geometry_args); } @@ -125,7 +155,8 @@ struct test_distance_of_geometries Geometry2 const& geometry2, DistanceType const& expected_distance, Strategy const& strategy, - bool test_reversed = true) + bool test_reversed = true, + bool swap_geometry_args = false) { #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << "case ID: " << case_id << "; " @@ -209,13 +240,42 @@ struct test_distance_of_geometries #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << "distance[reversed args] = " - << dist << " ; " - << "comp. distance[reversed args] = " - //<< cdist + << dist + << std::endl; +#endif + } + + if (swap_geometry_args) + { + Geometry1 g1 = dispatch + < + typename boost::geometry::tag::type + >::swap(geometry1); + + Geometry2 g2 = dispatch + < + typename boost::geometry::tag::type + >::swap(geometry2); + + // check distance with given strategy + dist = bg::distance(g1, g2, strategy); + + check_equal + < + default_distance_result + >::apply(case_id, "swap", g1, g2, + dist, expected_distance); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << "distance[swap geometry args] = " + << dist << std::endl; std::cout << std::endl; #endif - } + } +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; +#endif } };