diff --git a/include/boost/geometry/algorithms/detail/distance/linear_to_box.hpp b/include/boost/geometry/algorithms/detail/distance/linear_to_box.hpp index 8eef7b835..833dbf5f6 100644 --- a/include/boost/geometry/algorithms/detail/distance/linear_to_box.hpp +++ b/include/boost/geometry/algorithms/detail/distance/linear_to_box.hpp @@ -101,6 +101,20 @@ struct distance {}; +template +struct distance + < + Areal, Box, Strategy, + areal_tag, box_tag, + strategy_tag_distance_segment_box, false + > + : detail::distance::linear_to_box + < + Areal, Box, Strategy + > +{}; + + } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/test/algorithms/distance/distance_brute_force.hpp b/test/algorithms/distance/distance_brute_force.hpp index ed02a4442..4814244df 100644 --- a/test/algorithms/distance/distance_brute_force.hpp +++ b/test/algorithms/distance/distance_brute_force.hpp @@ -749,6 +749,45 @@ struct distance_brute_force } }; +template +< + typename Polygon, + typename Box, + typename Strategy +> +struct distance_brute_force +< + Polygon, Box, Strategy, + polygon_tag, box_tag, false +> +{ + typedef typename distance_result + < + Polygon, Box, Strategy + >::type distance_type; + + static inline distance_type apply(Polygon const& polygon, + Box const& box, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + Box, + typename std::iterator_traits + < + segment_iterator + >::value_type, + Strategy + > + >::apply(box, + geometry::segments_begin(polygon), + geometry::segments_end(polygon), + strategy); + } +}; + //======================================================================== template @@ -987,6 +1026,81 @@ struct distance_brute_force } }; +template +< + typename MultiPolygon, + typename Box, + typename Strategy +> +struct distance_brute_force +< + MultiPolygon, Box, Strategy, + multi_polygon_tag, box_tag, false +> +{ + typedef typename distance_result + < + MultiPolygon, Box, Strategy + >::type distance_type; + + static inline distance_type apply(MultiPolygon const& mp, + Box const& box, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + Box, + typename boost::range_value::type, + Strategy + > + >::apply(box, boost::begin(mp), boost::end(mp), strategy); + } +}; + + +//======================================================================== + +template +< + typename Ring, + typename Box, + typename Strategy +> +struct distance_brute_force +< + Ring, Box, Strategy, + ring_tag, box_tag, false +> +{ + typedef typename distance_result + < + Ring, Box, Strategy + >::type distance_type; + + static inline distance_type apply(Ring const& ring, + Box const& box, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + Box, + typename std::iterator_traits + < + segment_iterator + >::value_type, + Strategy + > + >::apply(box, + geometry::segments_begin(ring), + geometry::segments_end(ring), + strategy); + } +}; + //======================================================================== template diff --git a/test/algorithms/distance/distance_geo_ar_ar.cpp b/test/algorithms/distance/distance_geo_ar_ar.cpp index d05733c95..3548c17d2 100644 --- a/test/algorithms/distance/distance_geo_ar_ar.cpp +++ b/test/algorithms/distance/distance_geo_ar_ar.cpp @@ -1,15 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017, 2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html -#define BOOST_GEOMETRY_TEST_DEBUG - #ifndef BOOST_TEST_MODULE #define BOOST_TEST_MODULE test_distance_geographic_areal_areal #endif @@ -23,83 +21,78 @@ #include "test_distance_geo_common.hpp" -typedef bg::cs::geographic cs_type; -typedef bg::model::point point_type; -typedef bg::model::segment segment_type; -typedef bg::model::box box_type; - -namespace services = bg::strategy::distance::services; -typedef bg::default_distance_result::type return_type; - -typedef bg::srs::spheroid stype; - -// Strategies for point-point distance - -typedef bg::strategy::distance::andoyer andoyer_pp; -typedef bg::strategy::distance::thomas thomas_pp; -typedef bg::strategy::distance::vincenty vincenty_pp; - -// Strategies for point-segment distance - -typedef bg::strategy::distance::geographic_cross_track - andoyer_ps; - -typedef bg::strategy::distance::geographic_cross_track - thomas_ps; - -typedef bg::strategy::distance::geographic_cross_track - vincenty_ps; - -// Strategies for point-box distance - -typedef bg::strategy::distance::geographic_cross_track_box_box - < - bg::strategy::andoyer, - stype, - double - > andoyer_bb; - -typedef bg::strategy::distance::geographic_cross_track_box_box - < - bg::strategy::thomas, - stype, - double - > thomas_bb; - -typedef bg::strategy::distance::geographic_cross_track_box_box - < - bg::strategy::vincenty, - stype, - double - > vincenty_bb; - -//=========================================================================== - -template -inline bg::default_distance_result::type -pp_distance(std::string const& wkt1, - std::string const& wkt2, - Strategy const& strategy) +template +void test_distance_ring_box(Strategy_pp const& strategy_pp, + Strategy_ps const& strategy_ps, + Strategy_sb const& strategy_sb) { - point_type p1, p2; - bg::read_wkt(wkt1, p1); - bg::read_wkt(wkt2, p2); - return bg::distance(p1, p2, strategy); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "ring/box distance tests" << std::endl; +#endif + typedef bg::model::box box_type; + typedef bg::model::ring ring_type; + + typedef test_distance_of_geometries tester; + + std::string const ring = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))"; + + // case 1 + tester::apply("bb1", ring, "BOX(10 10,20 20)", + sb_distance("SEGMENT(11 2,12 3)", "BOX(10 10,20 20)", strategy_sb), + strategy_sb, true, false, false); } -template -inline bg::default_distance_result::type -ps_distance(std::string const& wkt1, - std::string const& wkt2, - Strategy const& strategy) +template +void test_distance_polygon_box(Strategy_pp const& strategy_pp, + Strategy_ps const& strategy_ps, + Strategy_sb const& strategy_sb) { - point_type p; - segment_type s; - bg::read_wkt(wkt1, p); - bg::read_wkt(wkt2, s); - return bg::distance(p, s, strategy); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "polygon/box distance tests" << std::endl; +#endif + typedef bg::model::box box_type; + typedef bg::model::polygon polygon_type; + + typedef test_distance_of_geometries tester; + + std::string const polygon = "POLYGON((11 0,10 1,11 2,12 3,13 1,11 0))"; + + // case 1 + tester::apply("pb1", polygon, "BOX(10 10,20 20)", + sb_distance("SEGMENT(11 2,12 3)", "BOX(10 10,20 20)", strategy_sb), + strategy_sb, true, false, false); } +template +void test_distance_multi_polygon_box(Strategy_pp const& strategy_pp, + Strategy_ps const& strategy_ps, + Strategy_sb const& strategy_sb) +{ + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "multi_polygon/box distance tests" << std::endl; +#endif + typedef bg::model::box box_type; + typedef bg::model::polygon polygon_type; + typedef bg::model::multi_polygon multi_polygon_type; + + typedef test_distance_of_geometries tester; + + std::string const multi_polygon = "MULTIPOLYGON(((20 20,20 30,30 40,20 20)),\ + ((10 10,0 20,15 30,20 15,15 10,10 10)))"; + + tester::apply("mpb1", multi_polygon, "BOX(0 0,5 5)", + sb_distance("SEGMENT(10 10,0 20)", "BOX(0 0,5 5)", strategy_sb), + strategy_sb, true, false, false); +} + + + //=========================================================================== // Cases for relative location of box2 wrt to box1 // @@ -120,7 +113,7 @@ ps_distance(std::string const& wkt1, // southern hemisphere picture is mirrored wrt the equator -template +template void test_distance_box_box(Strategy_pp const& strategy_pp, Strategy_ps const& strategy_ps, Strategy_bb const& strategy_bb) @@ -130,430 +123,429 @@ void test_distance_box_box(Strategy_pp const& strategy_pp, std::cout << std::endl; std::cout << "box/box distance tests" << std::endl; #endif + typedef bg::model::box box_type; + typedef test_distance_of_geometries tester; std::string const box1 = "BOX(10 10,20 20)"; // case 1 tester::apply("bb1", box1, "BOX(30 0,40 5)", - pp_distance("POINT(20 10)", "POINT(30 5)", strategy_pp), + pp_distance("POINT(20 10)", "POINT(30 5)", strategy_pp), strategy_bb); // case 2 tester::apply("bb2-a", box1, "BOX(30 12, 40 17)", - ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), + ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), strategy_bb); tester::apply("bb2-b", box1, "BOX(30 10, 40 17)", - ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), + ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), strategy_bb); tester::apply("bb2-c", box1, "BOX(30 8, 40 17)", - ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), + ps_distance("POINT(30 17)", "SEGMENT(20 10,20 20)", strategy_ps), strategy_bb); // case 3 tester::apply("bb3-a", box1, "BOX(30 15, 40 25)", - ps_distance("POINT(20 20)", "SEGMENT(30 15,30 25)", strategy_ps), + ps_distance("POINT(20 20)", "SEGMENT(30 15,30 25)", strategy_ps), strategy_bb); tester::apply("bb3-b", box1, "BOX(30 20, 40 40)", - ps_distance("POINT(20 20)", "SEGMENT(30 20,30 40)", strategy_ps), + ps_distance("POINT(20 20)", "SEGMENT(30 20,30 40)", strategy_ps), strategy_bb); // case 4 tester::apply("bb4", box1, "BOX(30 25, 40 40)", - pp_distance("POINT(20 20)", "POINT(30 25)", strategy_pp), + pp_distance("POINT(20 20)", "POINT(30 25)", strategy_pp), strategy_bb); // case 5 tester::apply("bb5", box1, "BOX(12 2, 17 7)", - pp_distance("POINT(17 7)", "POINT(17 10)", strategy_pp), + pp_distance("POINT(17 7)", "POINT(17 10)", strategy_pp), strategy_bb); // case 6, boxes intersect thus distance is 0 tester::apply("bb6-a", box1, "BOX(12 2, 17 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-b", box1, "BOX(12 2, 17 17)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-c", box1, "BOX(20 2, 30 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-d", box1, "BOX(20 11, 30 15)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-e", box1, "BOX(20 20, 30 30)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-f", box1, "BOX(15 20, 17 30)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-g", box1, "BOX(8 20, 10 25)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-h", box1, "BOX(8 15 , 10 17)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-i", box1, "BOX(8 8, 10 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-j", box1, "BOX(15 8, 17 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); // case 7 tester::apply("bb7", box1, "BOX(12 22, 17 27)", - pp_distance("POINT(17 20)", "POINT(17 22)", strategy_pp), + pp_distance("POINT(17 20)", "POINT(17 22)", strategy_pp), strategy_bb); // case 8 tester::apply("bb8", box1, "BOX(4 4, 8 8)", - pp_distance("POINT(8 8)", "POINT(10 10)", strategy_pp), + pp_distance("POINT(8 8)", "POINT(10 10)", strategy_pp), strategy_bb); // case 9 tester::apply("bb9-a", box1, "BOX(4 14, 8 18)", - ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), + ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), strategy_bb); tester::apply("bb9-b", box1, "BOX(4 10, 8 18)", - ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), + ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), strategy_bb); tester::apply("bb9-c", box1, "BOX(4 8, 8 18)", - ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), + ps_distance("POINT(8 18)", "SEGMENT(10 10, 10 20)", strategy_ps), strategy_bb); // case 10 tester::apply("bb10a", box1, "BOX(4 18, 8 22)", - ps_distance("POINT(10 20)", "SEGMENT(8 18, 8 22)", strategy_ps), + ps_distance("POINT(10 20)", "SEGMENT(8 18, 8 22)", strategy_ps), strategy_bb); std::string const box1m = "BOX(10 -20,20 -10)"; tester::apply("bb10am", box1m, "BOX(4 -22, 8 -18)", - ps_distance("POINT(10 20)", "SEGMENT(8 18, 8 22)", strategy_ps), + ps_distance("POINT(10 20)", "SEGMENT(8 18, 8 22)", strategy_ps), strategy_bb); tester::apply("bb10b", box1, "BOX(4 20, 8 22)", - ps_distance("POINT(10 20)", "SEGMENT(8 20, 8 22)", strategy_ps), + ps_distance("POINT(10 20)", "SEGMENT(8 20, 8 22)", strategy_ps), strategy_bb); tester::apply("bb10bm", box1m, "BOX(4 -22, 8 -20)", - ps_distance("POINT(10 20)", "SEGMENT(8 22, 8 20)", strategy_ps), + ps_distance("POINT(10 20)", "SEGMENT(8 22, 8 20)", strategy_ps), strategy_bb); // case 11 tester::apply("bb11", box1, "BOX(4 22, 8 24)", - pp_distance("POINT(8 22)", "POINT(10 20)", strategy_pp), + pp_distance("POINT(8 22)", "POINT(10 20)", strategy_pp), strategy_bb); // far away boxes tester::apply("bb-far", "BOX(150 15, 170 25)", box1, - ps_distance("POINT(20 20)", "SEGMENT(150 15, 150 25)", strategy_ps), + ps_distance("POINT(20 20)", "SEGMENT(150 15, 150 25)", strategy_ps), strategy_bb); // crosses antimeridian tester::apply("bb-anti1", "BOX(170 15, -160 25)", box1, - ps_distance("POINT(20 20)", "SEGMENT(170 15, 170 25)", strategy_ps), + ps_distance("POINT(20 20)", "SEGMENT(170 15, 170 25)", strategy_ps), strategy_bb); tester::apply("bb-anti2", "BOX(170 15, -160 25)", "BOX(160 10, -170 20)", - pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp), + pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp), strategy_bb); tester::apply("bb-anti3", "BOX(170 15, -160 25)", "BOX(160 10, 170 20)", - pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp), + pp_distance("POINT(20 20)", "POINT(20 20)", strategy_pp), strategy_bb); tester::apply("bb-anti4", "BOX(170 10, -160 20)", "BOX(160 30, -170 40)", - pp_distance("POINT(180 20)", "POINT(180 30)", strategy_pp), + pp_distance("POINT(180 20)", "POINT(180 30)", strategy_pp), strategy_bb); // South hemisphere tester::apply("bb-south1", "BOX(10 -20, 20 -10)", "BOX(30 -15, 40 -12)", - ps_distance("POINT(30 -15)", "SEGMENT(20 -10, 20 -20)", strategy_ps), + ps_distance("POINT(30 -15)", "SEGMENT(20 -10, 20 -20)", strategy_ps), strategy_bb); tester::apply("bb-south2", "BOX(10 -20, 20 -10)", "BOX(30 -30, 40 -25)", - pp_distance("POINT(30 -25)", "POINT(20 -20)", strategy_pp), + pp_distance("POINT(30 -25)", "POINT(20 -20)", strategy_pp), strategy_bb); tester::apply("bb-south3", "BOX(10 -20, 20 -10)", "BOX(30 -25, 40 -15)", - ps_distance("POINT(20 -20)", "SEGMENT(30 -15, 30 -25)", strategy_ps), + ps_distance("POINT(20 -20)", "SEGMENT(30 -15, 30 -25)", strategy_ps), strategy_bb); tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -30, 30 -25)", - pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp), + pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp), strategy_bb); tester::apply("bb-south4", "BOX(10 -20, 20 -10)", "BOX(5 -7, 30 -5)", - pp_distance("POINT(10 -7)", "POINT(10 -10)", strategy_pp), + pp_distance("POINT(10 -7)", "POINT(10 -10)", strategy_pp), strategy_bb); // Crosses equator tester::apply("bb-eq1", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 25)", - ps_distance("POINT(20 25)", "SEGMENT(30 -15, 30 30)", strategy_ps), + ps_distance("POINT(20 25)", "SEGMENT(30 -15, 30 30)", strategy_ps), strategy_bb); tester::apply("bb-eq1b", "BOX(30 -15, 40 30)", "BOX(10 -20, 20 10)", - ps_distance("POINT(30 -15)", "SEGMENT(20 10, 20 -20)", strategy_ps), + ps_distance("POINT(30 -15)", "SEGMENT(20 10, 20 -20)", strategy_ps), strategy_bb); tester::apply("bb-eq1bm", "BOX(30 -30, 40 15)", "BOX(10 -10, 20 20)", - ps_distance("POINT(30 15)", "SEGMENT(20 -10, 20 20)", strategy_ps), + ps_distance("POINT(30 15)", "SEGMENT(20 -10, 20 20)", strategy_ps), strategy_bb); tester::apply("bb-eq2", "BOX(30 -15, 40 20)", "BOX(10 -20, 20 25)", - ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps), + ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps), strategy_bb); tester::apply("bb-eq3", "BOX(30 5, 40 20)", "BOX(10 -20, 20 25)", - ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps), + ps_distance("POINT(30 20)", "SEGMENT(20 -20, 20 25)", strategy_ps), strategy_bb); tester::apply("bb-eq4", "BOX(5 -30, 40 -25)", "BOX(10 -20, 20 25)", - pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp), + pp_distance("POINT(10 -25)", "POINT(10 -20)", strategy_pp), strategy_bb); tester::apply("bb-eq5", "BOX(30 5, 40 20)", "BOX(10 -20, 50 25)", - pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp), + pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp), strategy_bb); tester::apply("bb-eq6", "BOX(30 5, 40 20)", "BOX(10 -20, 35 25)", - pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp), + pp_distance("POINT(30 20)", "POINT(30 20)", strategy_pp), strategy_bb); // One box in the north and one in the south hemisphere tester::apply("bb-ns1", "BOX(30 15, 40 20)", "BOX(10 -20, 20 -15)", - pp_distance("POINT(30 15)", "POINT(20 -15)", strategy_pp), + pp_distance("POINT(30 15)", "POINT(20 -15)", strategy_pp), strategy_bb); tester::apply("bb-ns2", "BOX(30 15, 40 20)", "BOX(25 -20, 50 -15)", - pp_distance("POINT(30 15)", "POINT(30 -15)", strategy_pp), + pp_distance("POINT(30 15)", "POINT(30 -15)", strategy_pp), strategy_bb); -} -template -void test_distance_box_box_negative(Strategy_pp const& strategy_pp, - Strategy_ps const& strategy_ps, - Strategy_bb const& strategy_bb) -{ - typedef test_distance_of_geometries tester; + //negative coordinates + std::string const box1neg = "BOX(-20 10,-10 20)"; // case 1 tester::apply("bb1", box1neg, "BOX(-40 0,-30 5)", - pp_distance("POINT(-20 10)", "POINT(-30 5)", strategy_pp), + pp_distance("POINT(-20 10)", "POINT(-30 5)", strategy_pp), strategy_bb); // case 2 tester::apply("bb2-a", box1neg, "BOX(-40 12, -30 17)", - ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), + ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), strategy_bb); tester::apply("bb2-b", box1neg, "BOX(-40 10, -30 17)", - ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), + ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), strategy_bb); tester::apply("bb2-c", box1neg, "BOX(-40 8, -30 17)", - ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), + ps_distance("POINT(-30 17)", "SEGMENT(-20 10,-20 20)", strategy_ps), strategy_bb); // case 3 tester::apply("bb3-a", box1neg, "BOX(-40 15, -30 25)", - ps_distance("POINT(-20 20)", "SEGMENT(-30 15,-30 25)", strategy_ps), + ps_distance("POINT(-20 20)", "SEGMENT(-30 15,-30 25)", strategy_ps), strategy_bb); tester::apply("bb3-b", box1neg, "BOX(-40 20, -30 40)", - ps_distance("POINT(-20 20)", "SEGMENT(-30 20,-30 40)", strategy_ps), + ps_distance("POINT(-20 20)", "SEGMENT(-30 20,-30 40)", strategy_ps), strategy_bb); // case 4 tester::apply("bb4", box1neg, "BOX(-40 25, -30 40)", - pp_distance("POINT(-20 20)", "POINT(-30 25)", strategy_pp), + pp_distance("POINT(-20 20)", "POINT(-30 25)", strategy_pp), strategy_bb); // case 5 tester::apply("bb5", box1neg, "BOX(-17 2,-12 7)", - pp_distance("POINT(-17 7)", "POINT(-17 10)", strategy_pp), + pp_distance("POINT(-17 7)", "POINT(-17 10)", strategy_pp), strategy_bb); // case 6, boxes intersect thus distance is 0 tester::apply("bb6-a", box1neg, "BOX(-17 2, -12 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-b", box1neg, "BOX(-17 2, -12 17)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-c", box1neg, "BOX(-30 2, -20 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-d", box1neg, "BOX(-30 11, -20 15)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-e", box1neg, "BOX(-30 20, -20 30)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-f", box1neg, "BOX(-17 20, -15 30)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-g", box1neg, "BOX(-10 20, -8 25)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-h", box1neg, "BOX(-10 15 , -8 17)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-i", box1neg, "BOX(-10 8, -8 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); tester::apply("bb6-j", box1neg, "BOX(-17 8, -15 10)", - pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), + pp_distance("POINT(0 0)", "POINT(0 0)", strategy_pp), strategy_bb); // case 7 tester::apply("bb7", box1neg, "BOX(-17 22, -12 27)", - pp_distance("POINT(-17 20)", "POINT(-17 22)", strategy_pp), + pp_distance("POINT(-17 20)", "POINT(-17 22)", strategy_pp), strategy_bb); // case 8 tester::apply("bb8", box1neg, "BOX(-8 4, -4 8)", - pp_distance("POINT(-8 8)", "POINT(-10 10)", strategy_pp), + pp_distance("POINT(-8 8)", "POINT(-10 10)", strategy_pp), strategy_bb); // case 9 tester::apply("bb9-a", box1neg, "BOX(-8 14, -4 18)", - ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), + ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), strategy_bb); tester::apply("bb9-b", box1neg, "BOX(-8 10, -4 18)", - ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), + ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), strategy_bb); tester::apply("bb9-c", box1neg, "BOX(-8 8, -4 18)", - ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), + ps_distance("POINT(-8 18)", "SEGMENT(-10 10, -10 20)", strategy_ps), strategy_bb); // case 10 tester::apply("bb10", box1neg, "BOX(-8 18, -4 22)", - ps_distance("POINT(-10 20)", "SEGMENT(-8 18, -8 22)", strategy_ps), + ps_distance("POINT(-10 20)", "SEGMENT(-8 18, -8 22)", strategy_ps), strategy_bb); tester::apply("bb10", box1neg, "BOX(-8 20, -4 22)", - ps_distance("POINT(-10 20)", "SEGMENT(-8 20, -8 22)", strategy_ps), + ps_distance("POINT(-10 20)", "SEGMENT(-8 20, -8 22)", strategy_ps), strategy_bb); // case 11 tester::apply("bb11", box1neg, "BOX(-8 22, -4 24)", - pp_distance("POINT(-8 22)", "POINT(-10 20)", strategy_pp), + pp_distance("POINT(-8 22)", "POINT(-10 20)", 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; + //Degenerate cases - //--- //1st box degenerates to a meridian segment - std::string const box1 = "BOX(0 10,0 20)"; + std::string const box1deg = "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), + tester::apply("pbd1", box1deg, "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), + tester::apply("pbd2", box1deg, "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()), + tester::apply("pbd3", box1deg, "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), + tester::apply("pbd4", box1deg, "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)"; + std::string const box2deg = "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), + tester::apply("pbd5", box2deg, "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), + tester::apply("pbd6", box2deg, "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), + tester::apply("pbd7", box2deg, "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)"; + std::string const box3deg = "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), + tester::apply("pbd8", box3deg, "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), + tester::apply("pbd9", box3deg, "BOX(15 15, 15 15)", + pp_distance("POINT(0 6)", "POINT(15 15)", strategy_pp), strategy_bb); } //=========================================================================== +template +void test_all_ar_ar(Strategy_pp pp_strategy, Strategy_ps ps_strategy, Strategy_bb bb_strategy, Strategy_sb sb_strategy) +{ + test_distance_polygon_box(pp_strategy, ps_strategy, sb_strategy); + test_distance_multi_polygon_box(pp_strategy, ps_strategy, sb_strategy); + test_distance_ring_box(pp_strategy, ps_strategy, sb_strategy); + test_distance_box_box(pp_strategy, ps_strategy, bb_strategy); + + //test_more_empty_input_areal_areal(ps_strategy); +} + BOOST_AUTO_TEST_CASE( test_all_areal_areal ) { - test_distance_box_box(vincenty_pp(), vincenty_ps(), vincenty_bb()); - test_distance_box_box(thomas_pp(), thomas_ps(), thomas_bb()); - test_distance_box_box(andoyer_pp(), andoyer_ps(), andoyer_bb()); + typedef bg::model::point > + sph_point; + test_all_ar_ar(spherical_pp(), spherical_ps(), spherical_bb(), spherical_sb()); - 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()); + typedef bg::model::point > geo_point; + + test_all_ar_ar(vincenty_pp(), vincenty_ps(), vincenty_bb(), vincenty_sb()); + test_all_ar_ar(thomas_pp(), thomas_ps(), thomas_bb(), thomas_sb()); + test_all_ar_ar(andoyer_pp(), andoyer_ps(), andoyer_bb(), andoyer_sb()); } diff --git a/test/algorithms/distance/test_distance_geo_common.hpp b/test/algorithms/distance/test_distance_geo_common.hpp index cacfb2461..00e495c66 100644 --- a/test/algorithms/distance/test_distance_geo_common.hpp +++ b/test/algorithms/distance/test_distance_geo_common.hpp @@ -113,6 +113,30 @@ typedef bg::strategy::distance::geographic_segment_box vincenty_sb; +// Strategies for box-box distance + +typedef bg::strategy::distance::cross_track_box_box<> spherical_bb; + +typedef bg::strategy::distance::geographic_cross_track_box_box + < + bg::strategy::andoyer, + stype, + double + > andoyer_bb; + +typedef bg::strategy::distance::geographic_cross_track_box_box + < + bg::strategy::thomas, + stype, + double + > thomas_bb; + +typedef bg::strategy::distance::geographic_cross_track_box_box + < + bg::strategy::vincenty, + stype, + double + > vincenty_bb; //=========================================================================== @@ -144,6 +168,24 @@ ps_distance(std::string const& wkt1, return bg::distance(p, s, strategy); } +//=========================================================================== + +template +inline typename bg::default_distance_result::type +sb_distance(std::string const& wkt1, + std::string const& wkt2, + Strategy const& strategy) +{ + Point p; + typedef bg::model::segment segment_type; + typedef bg::model::box box_type; + segment_type s; + box_type b; + bg::read_wkt(wkt1, s); + bg::read_wkt(wkt2, b); + return bg::distance(s, b, strategy); +} + //=================================================================== template struct dispatch