From ffb90fcc48c656236731a540966d9b08b4fe0834 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 12:34:03 +0200 Subject: [PATCH 1/8] [strategies][spherical][cross_track] fix return type in result_from_distance meta-struct --- .../geometry/strategies/spherical/distance_cross_track.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp index a40f03dba..943e51976 100644 --- a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp @@ -223,7 +223,10 @@ template struct result_from_distance, P, PS> { private : - typedef typename cross_track::template return_type return_type; + typedef typename cross_track + < + CalculationType, Strategy + >::template return_type::type return_type; public : template static inline return_type apply(cross_track const& , T const& distance) From 6defb7643a110025d85de7dafa4c78f727ec8695 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 12:35:42 +0200 Subject: [PATCH 2/8] [strategies][concepts][distance strategies] polish code in various places; add missing checks in point-segment distance strategy concept; add BOOST_MPL_ASSERTs to check for the possible value(s) of the strategy tags; --- .../strategies/concepts/distance_concept.hpp | 66 ++++++++++++++++--- 1 file changed, 56 insertions(+), 10 deletions(-) diff --git a/include/boost/geometry/strategies/concepts/distance_concept.hpp b/include/boost/geometry/strategies/concepts/distance_concept.hpp index a0cbbd21e..6d3b7c85f 100644 --- a/include/boost/geometry/strategies/concepts/distance_concept.hpp +++ b/include/boost/geometry/strategies/concepts/distance_concept.hpp @@ -1,8 +1,13 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// 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) 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. @@ -19,6 +24,8 @@ #include #include +#include +#include #include @@ -26,13 +33,15 @@ #include #include +#include + namespace boost { namespace geometry { namespace concept { /*! - \brief Checks strategy for point-segment-distance + \brief Checks strategy for point-point or point-box or box-box distance \ingroup distance */ template @@ -57,7 +66,7 @@ private : ApplyMethod, 1 >::type ptype2; - // 2) must define meta-function return_type + // 2) must define meta-function "return_type" typedef typename strategy::distance::services::return_type < Strategy, ptype1, ptype2 @@ -75,6 +84,16 @@ private : Strategy >::type tag; + static const bool is_correct_strategy_tag = + boost::is_same::value + || boost::is_same::value + || boost::is_same::value; + + BOOST_MPL_ASSERT_MSG + ((is_correct_strategy_tag), + INCORRECT_STRATEGY_TAG, + (types)); + // 5) must implement apply with arguments Strategy* str = 0; ptype1 *p1 = 0; @@ -111,7 +130,7 @@ public : /*! - \brief Checks strategy for point-segment-distance + \brief Checks strategy for point-segment distance \ingroup strategy_concepts */ template @@ -125,6 +144,7 @@ private : template static void apply(ApplyMethod) { + // 1) inspect and define both arguments of apply typedef typename parameter_type_of < ApplyMethod, 0 @@ -135,10 +155,28 @@ private : ApplyMethod, 1 >::type sptype; - // must define meta-function return_type - typedef typename strategy::distance::services::return_type::type rtype; + namespace services = strategy::distance::services; + // 2) must define meta-function "tag" + typedef typename services::tag::type tag; + BOOST_MPL_ASSERT_MSG + ((boost::is_same + < + tag, strategy_tag_distance_point_segment + >::value), + INCORRECT_STRATEGY_TAG, + (types)); + // 3) must define meta-function "return_type" + typedef typename services::return_type + < + Strategy, ptype, sptype + >::type rtype; + + // 4) must define meta-function "comparable_type" + typedef typename services::comparable_type::type ctype; + + // 5) must implement apply with arguments Strategy *str = 0; ptype *p = 0; sptype *sp1 = 0; @@ -146,8 +184,16 @@ private : rtype r = str->apply(*p, *sp1, *sp2); - boost::ignore_unused_variable_warning(str); - boost::ignore_unused_variable_warning(r); + // 6) must define (meta-)struct "get_comparable" with apply + ctype cstrategy = services::get_comparable::apply(*str); + + // 7) must define (meta-)struct "result_from_distance" with apply + r = services::result_from_distance + < + Strategy, ptype, sptype + >::apply(*str, rtype(1.0)); + + boost::ignore_unused(str, r); } }; From 2c3d9e898b91536b0bbcb6e4f6791d2d457a0690 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 23:24:19 +0200 Subject: [PATCH 3/8] [test][distance] cleanup common code for distance unit tests in the spherical_equatorial coordinate system --- .../distance/test_distance_se_common.hpp | 450 +++++------------- 1 file changed, 125 insertions(+), 325 deletions(-) diff --git a/test/algorithms/distance/test_distance_se_common.hpp b/test/algorithms/distance/test_distance_se_common.hpp index 8294ea934..e6a9e8a15 100644 --- a/test/algorithms/distance/test_distance_se_common.hpp +++ b/test/algorithms/distance/test_distance_se_common.hpp @@ -42,219 +42,13 @@ #include #include - -#ifndef BOOST_GEOMETRY_TEST_DISTANCE_HPP +#include "distance_brute_force.hpp" namespace bg = ::boost::geometry; static const double earth_radius_km = 6371.0; static const double earth_radius_miles = 3959.0; -// function copied from BG's test_distance.hpp - -template -void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2) -{ - try - { - bg::distance(geometry1, geometry2); - } - catch(bg::empty_input_exception const& ) - { - return; - } - BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); -} -#endif // BOOST_GEOMETRY_TEST_DISTANCE_HPP - - - -//======================================================================== - - - -template -< - typename PointLike1, - typename PointLike2, - typename Strategy, - typename Tag1 = typename bg::tag::type, - typename Tag2 = typename bg::tag::type -> -struct distance_brute_force -{}; - -template -< - typename PointLike1, - typename PointLike2, - typename Strategy -> -struct distance_brute_force -< - PointLike1, PointLike2, Strategy, - bg::point_tag, bg::point_tag -> -{ - typedef typename bg::distance_result - < - PointLike1, PointLike2, Strategy - >::type distance_type; - - static inline distance_type apply(PointLike1 const& p1, - PointLike2 const& p2, - Strategy const& strategy) - { - return bg::distance(p1, p2, strategy); - } -}; - -template -< - typename PointLike1, - typename PointLike2, - typename Strategy -> -struct distance_brute_force -< - PointLike1, PointLike2, Strategy, - bg::point_tag, bg::multi_point_tag -> -{ - typedef typename bg::distance_result - < - PointLike1, PointLike2, Strategy - >::type distance_type; - - static inline distance_type apply(PointLike1 const& p, - PointLike2 const& mp, - Strategy const& strategy) - { - typedef typename boost::range_iterator::type iterator; - - bool first = true; - distance_type d_min; - for (iterator it = boost::begin(mp); it != boost::end(mp); - ++it, first = false) - { - distance_type d = bg::distance(p, *it, strategy); - - if ( first || d < d_min ) - { - d_min = d; - } - } - return d_min; - } -}; - -template -< - typename PointLike1, - typename PointLike2, - typename Strategy -> -struct distance_brute_force -< - PointLike1, PointLike2, Strategy, - bg::multi_point_tag, bg::multi_point_tag -> -{ - typedef typename bg::distance_result - < - PointLike1, PointLike2, Strategy - >::type distance_type; - - static inline distance_type apply(PointLike1 const& mp1, - PointLike2 const& mp2, - Strategy const& strategy) - { - typedef typename boost::range_iterator - < - PointLike1 const - >::type iterator1; - - typedef typename boost::range_iterator - < - PointLike2 const - >::type iterator2; - - bool first = true; - distance_type d_min; - for (iterator1 it1 = boost::begin(mp1); it1 != boost::end(mp1); ++it1) - { - for (iterator2 it2 = boost::begin(mp2); it2 != boost::end(mp2); - ++it2, first = false) - { - distance_type d = bg::distance(*it1, *it2, strategy); - - if ( first || d < d_min ) - { - d_min = d; - } - } - } - return d_min; - } -}; - - - -//======================================================================== - - - -#ifdef BOOST_GEOMETRY_TEST_DEBUG -// pretty print geometry -- START -template -struct pretty_print_geometry_dispatch -{ - template - static inline Stream& apply(Geometry const& geometry, Stream& os) - { - os << bg::wkt(geometry); - return os; - } -}; - -template -struct pretty_print_geometry_dispatch -{ - template - static inline Stream& apply(Geometry const& geometry, Stream& os) - { - os << "SEGMENT" << bg::dsv(geometry); - return os; - } -}; - -template -struct pretty_print_geometry_dispatch -{ - template - static inline Stream& apply(Geometry const& geometry, Stream& os) - { - os << "BOX" << bg::dsv(geometry); - return os; - } -}; - - -template -struct pretty_print_geometry -{ - template - static inline Stream& apply(Geometry const& geometry, Stream& os) - { - return pretty_print_geometry_dispatch - < - Geometry, typename bg::tag::type - >::apply(geometry, os); - } -}; -// pretty print geometry -- END -#endif // BOOST_GEOMETRY_TEST_DEBUG - //======================================================================== @@ -262,22 +56,42 @@ struct pretty_print_geometry template struct check_equal { - static inline void apply(T const& value1, T const& value2) + template + struct equal_to { - BOOST_CHECK( value1 == value2 ); + static inline bool apply(Value const& x, Value const& y) + { + return x == y; + } + }; + + template + struct equal_to + { + static inline bool apply(double x, double y) + { + return boost::test_tools::check_is_close_t()(x, y, 0.0001); + } + }; + + template + static inline void apply(std::string const& case_id, + std::string const& subcase_id, + Geometry1 const& geometry1, + Geometry2 const& geometry2, + T const& detected, + T const& expected) + { + BOOST_CHECK_MESSAGE(equal_to::apply(expected, detected), + "case ID: " << case_id << "-" << subcase_id << "; " + << "G1: " << bg::wkt(geometry1) + << " - " + << "G2: " << bg::wkt(geometry2) + << " -> Detected: " << detected + << "; Expected: " << expected); } }; -template <> -struct check_equal -{ - static inline void apply(double value1, double value2) - { - BOOST_CHECK_CLOSE( value1, value2, 0.0001 ); - } -}; - - //======================================================================== template @@ -301,7 +115,8 @@ struct test_distance_of_geometries typename Strategy > static inline - void apply(std::string const& wkt1, + void apply(std::string const& case_id, + std::string const& wkt1, std::string const& wkt2, DistanceType const& expected_distance, ComparableDistanceType const& expected_comparable_distance, @@ -311,11 +126,28 @@ struct test_distance_of_geometries Geometry1 geometry1 = from_wkt(wkt1); Geometry2 geometry2 = from_wkt(wkt2); - apply(geometry1, geometry2, + apply(case_id, geometry1, geometry2, expected_distance, expected_comparable_distance, strategy, test_reversed); } + template + static inline + void apply(std::string const& case_id, + std::string const& wkt1, + std::string const& wkt2, + DistanceType const& expected_distance, + Strategy const& strategy, + bool test_reversed = true) + { + Geometry1 geometry1 = from_wkt(wkt1); + Geometry2 geometry2 = from_wkt(wkt2); + + apply(case_id, geometry1, geometry2, + expected_distance, expected_distance, + strategy, test_reversed); + } + template < @@ -324,7 +156,8 @@ struct test_distance_of_geometries typename Strategy > static inline - void apply(Geometry1 const& geometry1, + void apply(std::string const& case_id, + Geometry1 const& geometry1, Geometry2 const& geometry2, DistanceType const& expected_distance, ComparableDistanceType const& expected_comparable_distance, @@ -332,19 +165,22 @@ struct test_distance_of_geometries bool test_reversed = true) { #ifdef BOOST_GEOMETRY_TEST_DEBUG - typedef pretty_print_geometry PPG1; - typedef pretty_print_geometry PPG2; - PPG1::apply(geometry1, std::cout); - std::cout << " - "; - PPG2::apply(geometry2, std::cout); - std::cout << std::endl; + std::cout << "case ID: " << case_id << "; " + << "G1: " << bg::wkt(geometry1) + << " - " + << "G2: " << bg::wkt(geometry2) + << std::endl; #endif + namespace services = bg::strategy::distance::services; + + using bg::unit_test::distance_brute_force; + typedef typename bg::default_distance_result < Geometry1, Geometry2 >::type default_distance_result; - typedef typename bg::strategy::distance::services::return_type + typedef typename services::return_type < Strategy, Geometry1, Geometry2 >::type distance_result_from_strategy; @@ -355,20 +191,16 @@ struct test_distance_of_geometries distance_result_from_strategy >::type::value; - BOOST_CHECK( same_regular ); - + BOOST_CHECK(same_regular); typedef typename bg::default_comparable_distance_result < Geometry1, Geometry2 >::type default_comparable_distance_result; - typedef typename bg::strategy::distance::services::return_type + typedef typename services::return_type < - typename bg::strategy::distance::services::comparable_type - < - Strategy - >::type, + typename services::comparable_type::type, Geometry1, Geometry2 >::type comparable_distance_result_from_strategy; @@ -381,47 +213,26 @@ struct test_distance_of_geometries BOOST_CHECK( same_comparable ); - - // check distance with default strategy - default_distance_result dist_def = bg::distance(geometry1, geometry2); - - check_equal - < - default_distance_result - >::apply(dist_def, expected_distance); - - // check distance with passed strategy distance_result_from_strategy dist = bg::distance(geometry1, geometry2, strategy); check_equal < - default_distance_result - >::apply(dist, expected_distance * strategy.radius()); + distance_result_from_strategy + >::apply(case_id, "a", geometry1, geometry2, + dist, expected_distance); // check against the comparable distance computed in a // brute-force manner - default_distance_result dist_brute_force = distance_brute_force - < - Geometry1, Geometry2, Strategy - >::apply(geometry1, geometry2, strategy); + default_distance_result dist_brute_force + = distance_brute_force(geometry1, geometry2, strategy); check_equal < default_distance_result - >::apply(dist_brute_force, expected_distance * strategy.radius()); - - - // check comparable distance with default strategy - default_comparable_distance_result cdist_def = - bg::comparable_distance(geometry1, geometry2); - - check_equal - < - default_comparable_distance_result - >::apply(cdist_def, expected_comparable_distance); - + >::apply(case_id, "b", geometry1, geometry2, + dist_brute_force, expected_distance); // check comparable distance with passed strategy comparable_distance_result_from_strategy cdist = @@ -430,30 +241,24 @@ struct test_distance_of_geometries check_equal < default_comparable_distance_result - >::apply(cdist, expected_comparable_distance); + >::apply(case_id, "c", geometry1, geometry2, + cdist, expected_comparable_distance); // check against the comparable distance computed in a // brute-force manner default_comparable_distance_result cdist_brute_force - = distance_brute_force - < - Geometry1, - Geometry2, - typename bg::strategy::distance::services::comparable_type - < - Strategy - >::type - >::apply(geometry1, - geometry2, - bg::strategy::distance::services::get_comparable - < - Strategy - >::apply(strategy)); + = distance_brute_force(geometry1, + geometry2, + services::get_comparable + < + Strategy + >::apply(strategy)); check_equal < default_comparable_distance_result - >::apply(cdist_brute_force, expected_comparable_distance); + >::apply(case_id, "d", geometry1, geometry2, + cdist_brute_force, expected_comparable_distance); #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << string_from_type::type>::name() @@ -462,19 +267,16 @@ struct test_distance_of_geometries << string_from_type::name() << string_from_type::name() << std::endl; - std::cout << "expected distance (default strategy) = " + std::cout << "expected distance = " << expected_distance << " ; " - << "expected distance (passed strategy) = " - << (expected_distance * strategy.radius()) << " ; " << "expected comp. distance = " << expected_comparable_distance << std::endl; - std::cout << "distance (default strategy) = " << dist_def << " ; " - << "distance (passed strategy) = " << dist << " ; " - << "comp. distance (default strategy) = " - << cdist_def << " ; " - << "comp. distance (passed strategy) = " - << cdist << std::endl; + std::cout << "distance = " + << dist << " ; " + << "comp. distance = " + << cdist + << std::endl; if ( !test_reversed ) { @@ -484,31 +286,14 @@ struct test_distance_of_geometries if ( test_reversed ) { - // check distance with default strategy - dist_def = bg::distance(geometry2, geometry1); - - check_equal - < - default_distance_result - >::apply(dist_def, expected_distance); - - // check distance with given strategy dist = bg::distance(geometry2, geometry1, strategy); check_equal < default_distance_result - >::apply(dist, expected_distance * strategy.radius()); - - - // check comparable distance with default strategy - cdist_def = bg::comparable_distance(geometry2, geometry1); - - check_equal - < - default_comparable_distance_result - >::apply(cdist_def, expected_comparable_distance); + >::apply(case_id, "ra", geometry2, geometry1, + dist, expected_distance); // check comparable distance with given strategy cdist = bg::comparable_distance(geometry2, geometry1, strategy); @@ -516,24 +301,15 @@ struct test_distance_of_geometries check_equal < default_comparable_distance_result - >::apply(cdist, expected_comparable_distance); + >::apply(case_id, "rb", geometry2, geometry1, + cdist, expected_comparable_distance); #ifdef BOOST_GEOMETRY_TEST_DEBUG - std::cout << "expected distance (default strategy) = " - << expected_distance << " ; " - << "expected distance (passed strategy) = " - << (expected_distance * strategy.radius()) << " ; " - << "expected comp. distance = " - << expected_comparable_distance - << std::endl; - std::cout << "distance[reversed args] (def. startegy) = " - << dist_def << " ; " - << "distance[reversed args] (passed startegy) = " + std::cout << "distance[reversed args] = " << dist << " ; " - << "comp. distance[reversed args] (def. strategy) = " - << cdist_def << " ; " - << "comp. distance[reversed args] (passed strategy) = " - << cdist << std::endl; + << "comp. distance[reversed args] = " + << cdist + << std::endl; std::cout << std::endl; #endif } @@ -549,6 +325,28 @@ void test_empty_input(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy) { + try + { + bg::distance(geometry1, geometry2); + } + catch(bg::empty_input_exception const& ) + { + return; + } + BOOST_CHECK_MESSAGE(false, + "A empty_input_exception should have been thrown"); + + try + { + bg::distance(geometry2, geometry1); + } + catch(bg::empty_input_exception const& ) + { + return; + } + BOOST_CHECK_MESSAGE(false, + "A empty_input_exception should have been thrown"); + try { bg::distance(geometry1, geometry2, strategy); @@ -557,7 +355,8 @@ void test_empty_input(Geometry1 const& geometry1, { return; } - BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); + BOOST_CHECK_MESSAGE(false, + "A empty_input_exception should have been thrown"); try { @@ -567,7 +366,8 @@ void test_empty_input(Geometry1 const& geometry1, { return; } - BOOST_CHECK_MESSAGE(false, "A empty_input_exception should have been thrown" ); + BOOST_CHECK_MESSAGE(false, + "A empty_input_exception should have been thrown"); } #endif // BOOST_GEOMETRY_TEST_DISTANCE_SE_COMMON_HPP From 111d9537a13f0935805d702e2915b8d43458829a Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 23:25:11 +0200 Subject: [PATCH 4/8] [test][distance] add algorithm (used in unit tests) for computing the distance in a brute force manner, using BG's distance only for the following combinations: * point/point * point/segment * segment/segment --- .../distance/distance_brute_force.hpp | 493 ++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 test/algorithms/distance/distance_brute_force.hpp diff --git a/test/algorithms/distance/distance_brute_force.hpp b/test/algorithms/distance/distance_brute_force.hpp new file mode 100644 index 000000000..ccea5cbac --- /dev/null +++ b/test/algorithms/distance/distance_brute_force.hpp @@ -0,0 +1,493 @@ +// 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_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP +#define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace unit_test +{ + +namespace detail { namespace distance_brute_force +{ + +struct distance_from_bg +{ + template + static inline + typename distance_result::type + apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + BOOST_MPL_ASSERT + ((typename boost::mpl::or_ + < + boost::is_same::type, point_tag>, + boost::is_same::type, segment_tag> + >::type)); + + BOOST_MPL_ASSERT + ((typename boost::mpl::or_ + < + boost::is_same::type, point_tag>, + boost::is_same::type, segment_tag> + >::type)); + + return geometry::distance(geometry1, geometry2, strategy); + } +}; + + +template +inline +typename distance_result::type +bg_distance(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return distance_from_bg::apply(geometry1, geometry2, strategy); +} + + +template +struct one_to_many +{ + template + static inline typename distance_result + < + Geometry, + typename std::iterator_traits::value_type, + Strategy + >::type + apply(Geometry const& geometry, Iterator begin, Iterator end, + Strategy const& strategy) + { + typedef typename distance_result + < + Geometry, + typename std::iterator_traits::value_type, + Strategy + >::type distance_type; + + bool first = true; + distance_type d_min; + for (Iterator it = begin; it != end; ++it, first = false) + { + distance_type d = Policy::apply(geometry, *it, strategy); + + if ( first || d < d_min ) + { + d_min = d; + } + } + return d_min; + } +}; + + + +}} // namespace detail::distance_brute_force + + +namespace dispatch +{ + +template +< + typename Geometry1, + typename Geometry2, + typename Strategy, + typename Tag1 = typename tag_cast + < + typename tag::type, + segment_tag, + linear_tag + >::type, + typename Tag2 = typename tag_cast + < + typename tag::type, + segment_tag, + linear_tag + >::type, + bool Reverse = reverse_dispatch::type::value +> +struct distance_brute_force + : not_implemented +{}; + + +template +< + typename Geometry1, + typename Geometry2, + typename Strategy, + typename Tag1, + typename Tag2 +> +struct distance_brute_force +{ + static inline typename distance_result::type + apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) + { + return distance_brute_force + < + Geometry2, Geometry1, Strategy + >::apply(geometry2, geometry1, strategy); + } +}; + + +template +< + typename Point1, + typename Point2, + typename Strategy +> +struct distance_brute_force +< + Point1, Point2, Strategy, + point_tag, point_tag, false +> : detail::distance_brute_force::distance_from_bg +{}; + + +template +< + typename Point, + typename Segment, + typename Strategy +> +struct distance_brute_force +< + Point, Segment, Strategy, + point_tag, segment_tag, false +> : detail::distance_brute_force::distance_from_bg +{}; + + +template +< + typename Segment1, + typename Segment2, + typename Strategy +> +struct distance_brute_force +< + Segment1, Segment2, Strategy, + segment_tag, segment_tag, false +> : detail::distance_brute_force::distance_from_bg +{}; + + +template +< + typename Point, + typename Linear, + typename Strategy +> +struct distance_brute_force +< + Point, Linear, Strategy, + point_tag, linear_tag, false +> +{ + typedef typename distance_result + < + Point, Linear, Strategy + >::type distance_type; + + static inline distance_type apply(Point const& point, + Linear const& linear, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + detail::distance_brute_force::distance_from_bg + >::apply(point, + geometry::segments_begin(linear), + geometry::segments_end(linear), + strategy); + } +}; + + +template +< + typename Point, + typename MultiPoint, + typename Strategy +> +struct distance_brute_force +< + Point, MultiPoint, Strategy, + point_tag, multi_point_tag, false +> +{ + typedef typename distance_result + < + Point, MultiPoint, Strategy + >::type distance_type; + + static inline distance_type apply(Point const& p, + MultiPoint const& mp, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + detail::distance_brute_force::distance_from_bg + >::apply(p, boost::begin(mp), boost::end(mp), strategy); + } +}; + +template +< + typename MultiPoint1, + typename MultiPoint2, + typename Strategy +> +struct distance_brute_force +< + MultiPoint1, MultiPoint2, Strategy, + multi_point_tag, multi_point_tag, false +> +{ + typedef typename distance_result + < + MultiPoint1, MultiPoint2, Strategy + >::type distance_type; + + static inline distance_type apply(MultiPoint1 const& mp1, + MultiPoint2 const& mp2, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + MultiPoint1, + typename boost::range_value::type, + Strategy + > + >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy); + } +}; + + +template +< + typename MultiPoint, + typename Linear, + typename Strategy +> +struct distance_brute_force +< + MultiPoint, Linear, Strategy, + multi_point_tag, linear_tag, false +> +{ + typedef typename distance_result + < + MultiPoint, Linear, Strategy + >::type distance_type; + + static inline distance_type apply(MultiPoint const& mp, + Linear const& linear, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + Linear, + typename boost::range_value::type, + Strategy + > + >::apply(linear, boost::begin(mp), boost::end(mp), strategy); + } +}; + + +template +< + typename Linear, + typename MultiPoint, + typename Strategy +> +struct distance_brute_force +< + Linear, MultiPoint, Strategy, + linear_tag, multi_point_tag, false +> +{ + typedef typename distance_result + < + Linear, MultiPoint, Strategy + >::type distance_type; + + static inline distance_type apply(Linear const& linear, + MultiPoint const& multipoint, + Strategy const& strategy) + { + return distance_brute_force + < + MultiPoint, Linear, Strategy, + multi_point_tag, linear_tag, false + >::apply(multipoint, linear, strategy); + } +}; + + +template +< + typename MultiPoint, + typename Segment, + typename Strategy +> +struct distance_brute_force +< + MultiPoint, Segment, Strategy, + multi_point_tag, segment_tag, false +> +{ + typedef typename distance_result + < + MultiPoint, Segment, Strategy + >::type distance_type; + + static inline distance_type apply(MultiPoint const& mp, + Segment const& segment, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + detail::distance_brute_force::distance_from_bg + >::apply(segment, boost::begin(mp), boost::end(mp), strategy); + } +}; + + +template +< + typename Linear, + typename Segment, + typename Strategy +> +struct distance_brute_force +< + Linear, Segment, Strategy, + linear_tag, segment_tag, false +> +{ + typedef typename distance_result + < + Linear, Segment, Strategy + >::type distance_type; + + static inline distance_type apply(Linear const& linear, + Segment const& segment, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + detail::distance_brute_force::distance_from_bg + >::apply(segment, + geometry::segments_begin(linear), + geometry::segments_end(linear), + strategy); + } +}; + + +template +< + typename Linear1, + typename Linear2, + typename Strategy +> +struct distance_brute_force +< + Linear1, Linear2, Strategy, + linear_tag, linear_tag, false +> +{ + typedef typename distance_result + < + Linear1, Linear2, Strategy + >::type distance_type; + + static inline distance_type apply(Linear1 const& linear1, + Linear2 const& linear2, + Strategy const& strategy) + { + return detail::distance_brute_force::one_to_many + < + distance_brute_force + < + Linear1, + typename std::iterator_traits + < + segment_iterator + >::value_type, + Strategy + > + >::apply(linear1, + geometry::segments_begin(linear2), + geometry::segments_end(linear2), + strategy); + } +}; + +} // namespace dispatch + + + + + +template +inline typename distance_result::type +distance_brute_force(Geometry1 const& geometry1, + Geometry2 const& geometry2, + Strategy const& strategy) +{ + return dispatch::distance_brute_force + < + Geometry1, Geometry2, Strategy + >::apply(geometry1, geometry2, strategy); +} + +} // namespace unit_test + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP From 3f19ebab7513f26ba72783fc1c40f91753336606 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 23:26:54 +0200 Subject: [PATCH 5/8] [test][algorithms][distance] cleanup unit test for distances of pointlike/pointlike geometries in the spherical equatorial coordinate system; add testing when a comparable strategy is passed; --- .../algorithms/distance/distance_se_pl_pl.cpp | 128 +++++++++++++----- 1 file changed, 97 insertions(+), 31 deletions(-) diff --git a/test/algorithms/distance/distance_se_pl_pl.cpp b/test/algorithms/distance/distance_se_pl_pl.cpp index 630d33794..ea0c5174c 100644 --- a/test/algorithms/distance/distance_se_pl_pl.cpp +++ b/test/algorithms/distance/distance_se_pl_pl.cpp @@ -26,24 +26,30 @@ typedef bg::cs::spherical_equatorial cs_type; typedef bg::model::point point_type; typedef bg::model::multi_point multi_point_type; -namespace services = bg::strategy::distance::services; +namespace distance = bg::strategy::distance; +namespace services = distance::services; typedef bg::default_distance_result::type return_type; -typedef bg::strategy::distance::haversine point_point_strategy; +typedef distance::haversine point_point_strategy; +typedef distance::comparable::haversine comparable_point_point_strategy; //=========================================================================== -inline bg::default_distance_result::type -distance_from_wkt(std::string const& wkt1, std::string const& wkt2) +template +inline typename bg::distance_result::type +distance_from_wkt(std::string const& wkt1, + std::string const& wkt2, + Strategy const& strategy) { point_type p1, p2; bg::read_wkt(wkt1, p1); bg::read_wkt(wkt2, p2); - return bg::distance(p1, p2); + return bg::distance(p1, p2, strategy); } inline bg::default_comparable_distance_result::type -comparable_distance_from_wkt(std::string const& wkt1, std::string const& wkt2) +comparable_distance_from_wkt(std::string const& wkt1, + std::string const& wkt2) { point_type p1, p2; bg::read_wkt(wkt1, p1); @@ -54,7 +60,8 @@ comparable_distance_from_wkt(std::string const& wkt1, std::string const& wkt2) //=========================================================================== template -void test_distance_point_point(Strategy const& strategy) +void test_distance_point_point(Strategy const& strategy, + bool is_comparable_strategy = false) { #ifdef BOOST_GEOMETRY_TEST_DEBUG std::cout << std::endl; @@ -62,19 +69,29 @@ void test_distance_point_point(Strategy const& strategy) #endif typedef test_distance_of_geometries tester; - tester::apply("POINT(10 10)", + tester::apply("p-p-01", + "POINT(10 10)", "POINT(0 0)", - 0.24619691677893202, + (is_comparable_strategy + ? 0.0150768448035229 + : (0.24619691677893202 * strategy.radius())), 0.0150768448035229, strategy); - tester::apply("POINT(10 10)", + tester::apply("p-p-02", "POINT(10 10)", - 0, 0, strategy); + "POINT(10 10)", + 0, + strategy); // antipodal points - tester::apply("POINT(0 10)", + tester::apply("p-p-03", + "POINT(0 10)", "POINT(180 -10)", - 180.0 * bg::math::d2r, 1.0, strategy); + (is_comparable_strategy + ? 1.0 + : (180.0 * bg::math::d2r * strategy.radius())), + 1.0, + strategy); } //=========================================================================== @@ -88,33 +105,45 @@ void test_distance_point_multipoint(Strategy const& strategy) #endif typedef test_distance_of_geometries tester; - tester::apply("POINT(10 10)", + tester::apply("p-mp-01", + "POINT(10 10)", "MULTIPOINT(10 10,20 10,20 20,10 20)", - 0, 0, strategy); - tester::apply("POINT(10 10)", + 0, + strategy); + tester::apply("p-mp-02", + "POINT(10 10)", "MULTIPOINT(20 20,20 30,30 20,30 30)", - distance_from_wkt("POINT(10 10)", "POINT(20 20)"), + distance_from_wkt("POINT(10 10)", "POINT(20 20)", strategy), comparable_distance_from_wkt("POINT(10 10)", "POINT(20 20)"), strategy); - tester::apply("POINT(3 0)", + tester::apply("p-mp-03", + "POINT(3 0)", "MULTIPOINT(20 20,20 40,40 20,40 40)", - distance_from_wkt("POINT(3 0)", "POINT(20 20)"), + distance_from_wkt("POINT(3 0)", "POINT(20 20)", strategy), comparable_distance_from_wkt("POINT(3 0)", "POINT(20 20)"), strategy); // almost antipodal points - tester::apply("POINT(179 2)", + tester::apply("p-mp-04", + "POINT(179 2)", "MULTIPOINT(3 3,4 3,4 4,3 4)", - distance_from_wkt("POINT(179 2)", "POINT(4 4)"), + distance_from_wkt("POINT(179 2)", "POINT(4 4)", strategy), comparable_distance_from_wkt("POINT(179 2)", "POINT(4 4)"), strategy); // minimum distance across the dateline - tester::apply("POINT(355 5)", + tester::apply("p-mp-05", + "POINT(355 5)", "MULTIPOINT(10 10,20 10,20 20,10 20)", - distance_from_wkt("POINT(355 5)", "POINT(10 10)"), + distance_from_wkt("POINT(355 5)", "POINT(10 10)", strategy), comparable_distance_from_wkt("POINT(355 5)", "POINT(10 10)"), strategy); + tester::apply("p-mp-06", + "POINT(-5 5)", + "MULTIPOINT(10 10,20 10,20 20,10 20)", + distance_from_wkt("POINT(-5 5)", "POINT(10 10)", strategy), + comparable_distance_from_wkt("POINT(-5 5)", "POINT(10 10)"), + strategy); } //=========================================================================== @@ -131,19 +160,22 @@ void test_distance_multipoint_multipoint(Strategy const& strategy) multi_point_type, multi_point_type > tester; - tester::apply("MULTIPOINT(10 10,11 10,10 11,11 11)", + tester::apply("mp-mp-01", + "MULTIPOINT(10 10,11 10,10 11,11 11)", "MULTIPOINT(11 11,12 11,12 12,11 12)", - 0, 0, strategy); - tester::apply("MULTIPOINT(10 10,11 10,10 11,11 11)", + 0, + strategy); + tester::apply("mp-mp-02", + "MULTIPOINT(10 10,11 10,10 11,11 11)", "MULTIPOINT(12 12,12 13,13 12,13 13)", - distance_from_wkt("POINT(11 11)", "POINT(12 12)"), + distance_from_wkt("POINT(11 11)", "POINT(12 12)", strategy), comparable_distance_from_wkt("POINT(11 11)", "POINT(12 12)"), strategy); // example with many points in each multi-point so that the r-tree // does some splitting. - - tester::apply("MULTIPOINT(1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 8,1 9,1 10,\ + tester::apply("mp-mp-03", + "MULTIPOINT(1 1,1 2,1 3,1 4,1 5,1 6,1 7,1 8,1 9,1 10,\ 2 1,2 2,2 3,2 4,2 5,2 6,2 7,2 8,2 9,2 10,\ 3 1,3 2,3 3,3 4,3 5,3 6,3 7,3 8,3 9,3 10,\ 10 1,10 10)", @@ -154,7 +186,7 @@ void test_distance_multipoint_multipoint(Strategy const& strategy) 13 11,13 12,13 13,13 24,13 15,\ 13 16,13 17,13 18,13 29,13 20,\ 20 11,20 20)", - distance_from_wkt("POINT(10 10)", "POINT(11 11)"), + distance_from_wkt("POINT(10 10)", "POINT(11 11)", strategy), comparable_distance_from_wkt("POINT(10 10)", "POINT(11 11)"), strategy); @@ -194,6 +226,12 @@ BOOST_AUTO_TEST_CASE( test_all_point_point ) test_distance_point_point(point_point_strategy()); test_distance_point_point(point_point_strategy(earth_radius_km)); test_distance_point_point(point_point_strategy(earth_radius_miles)); + + test_distance_point_point(comparable_point_point_strategy(), true); + test_distance_point_point + (comparable_point_point_strategy(earth_radius_km), true); + test_distance_point_point + (comparable_point_point_strategy(earth_radius_miles), true); } BOOST_AUTO_TEST_CASE( test_all_point_multipoint ) @@ -201,13 +239,26 @@ BOOST_AUTO_TEST_CASE( test_all_point_multipoint ) test_distance_point_multipoint(point_point_strategy()); test_distance_point_multipoint(point_point_strategy(earth_radius_km)); test_distance_point_multipoint(point_point_strategy(earth_radius_miles)); + + test_distance_point_multipoint(comparable_point_point_strategy()); + test_distance_point_multipoint + (comparable_point_point_strategy(earth_radius_km)); + test_distance_point_multipoint + (comparable_point_point_strategy(earth_radius_miles)); } BOOST_AUTO_TEST_CASE( test_all_multipoint_multipoint ) { test_distance_multipoint_multipoint(point_point_strategy()); test_distance_multipoint_multipoint(point_point_strategy(earth_radius_km)); - test_distance_multipoint_multipoint(point_point_strategy(earth_radius_miles)); + test_distance_multipoint_multipoint + (point_point_strategy(earth_radius_miles)); + + test_distance_multipoint_multipoint(comparable_point_point_strategy()); + test_distance_multipoint_multipoint + (comparable_point_point_strategy(earth_radius_km)); + test_distance_multipoint_multipoint + (comparable_point_point_strategy(earth_radius_miles)); } BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike ) @@ -226,4 +277,19 @@ BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_pointlike ) < point_type >(point_point_strategy(earth_radius_miles)); + + test_more_empty_input_pointlike_pointlike + < + point_type + >(comparable_point_point_strategy()); + + test_more_empty_input_pointlike_pointlike + < + point_type + >(comparable_point_point_strategy(earth_radius_km)); + + test_more_empty_input_pointlike_pointlike + < + point_type + >(comparable_point_point_strategy(earth_radius_miles)); } From 46bb719a6310435d7fec9b63949401e6c30423bc Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Fri, 7 Nov 2014 23:28:05 +0200 Subject: [PATCH 6/8] [test][algorithms][distance] add unit test for testing distance computations for pointlike/linear geometries in the spherical equatorial coordinate system --- test/algorithms/distance/Jamfile.v2 | 1 + test/algorithms/distance/distance_se_pl_l.cpp | 435 ++++++++++++++++++ 2 files changed, 436 insertions(+) create mode 100644 test/algorithms/distance/distance_se_pl_l.cpp diff --git a/test/algorithms/distance/Jamfile.v2 b/test/algorithms/distance/Jamfile.v2 index 8d755c94a..1eb679dd7 100644 --- a/test/algorithms/distance/Jamfile.v2 +++ b/test/algorithms/distance/Jamfile.v2 @@ -23,5 +23,6 @@ test-suite boost-geometry-algorithms-distance [ run distance_pointlike_areal.cpp ] [ run distance_pointlike_linear.cpp ] [ run distance_pointlike_pointlike.cpp ] + [ run distance_se_pl_l.cpp ] [ run distance_se_pl_pl.cpp ] ; diff --git a/test/algorithms/distance/distance_se_pl_l.cpp b/test/algorithms/distance/distance_se_pl_l.cpp new file mode 100644 index 000000000..e5d0bf6ed --- /dev/null +++ b/test/algorithms/distance/distance_se_pl_l.cpp @@ -0,0 +1,435 @@ +// 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 + +#include + +#ifndef BOOST_TEST_MODULE +#define BOOST_TEST_MODULE test_distance_spherical_equatorial_pl_l +#endif + +#include + +#include "test_distance_se_common.hpp" + + +typedef bg::cs::spherical_equatorial cs_type; +typedef bg::model::point point_type; +typedef bg::model::segment segment_type; +typedef bg::model::multi_point multi_point_type; +typedef bg::model::segment segment_type; +typedef bg::model::linestring linestring_type; +typedef bg::model::multi_linestring multi_linestring_type; + +namespace services = bg::strategy::distance::services; +typedef bg::default_distance_result::type return_type; + +typedef bg::strategy::distance::haversine point_point_strategy; +typedef bg::strategy::distance::cross_track<> point_segment_strategy; + + +//=========================================================================== + +template +inline bg::default_distance_result::type +pp_distance_from_wkt(std::string const& wkt1, + std::string const& wkt2, + Strategy const& strategy) +{ + point_type p1, p2; + bg::read_wkt(wkt1, p1); + bg::read_wkt(wkt2, p2); + return bg::distance(p1, p2) * strategy.radius(); +} + +template +inline bg::default_distance_result::type +ps_distance_from_wkt(std::string const& wkt1, + std::string const& wkt2, + Strategy const& strategy) +{ + point_type p; + segment_type s; + bg::read_wkt(wkt1, p); + bg::read_wkt(wkt2, s); + return bg::distance(p, s, strategy); +} + +//=========================================================================== + +template +void test_distance_point_segment(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/segment distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + tester::apply("p-s-01", + "POINT(0 0)", + "SEGMENT(2 0,3 0)", + 2.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-s-02", + "POINT(2.5 3)", + "SEGMENT(2 0,3 0)", + 3.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-s-03", + "POINT(2 0)", + "SEGMENT(2 0,3 0)", + 0, strategy); + tester::apply("p-s-04", + "POINT(3 0)", + "SEGMENT(2 0,3 0)", + 0, strategy); + tester::apply("p-s-05", + "POINT(2.5 0)", + "SEGMENT(2 0,3 0)", + 0, strategy); + tester::apply("p-s-06", + "POINT(3.5 3)", + "SEGMENT(2 0,3 0)", + pp_distance_from_wkt("POINT(3 0)", "POINT(3.5 3)", strategy), + strategy); +} + +//=========================================================================== + +template +void test_distance_point_linestring(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/linestring distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + tester::apply("p-l-01", + "POINT(0 0)", + "LINESTRING(2 0,2 0)", + 2.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-l-02", + "POINT(0 0)", + "LINESTRING(2 0,3 0)", + 2.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-l-03", + "POINT(2.5 3)", + "LINESTRING(2 0,3 0)", + 3.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-l-04", + "POINT(2 0)", + "LINESTRING(2 0,3 0)", + 0, + strategy); + tester::apply("p-l-05", + "POINT(3 0)", + "LINESTRING(2 0,3 0)", + 0, + strategy); + tester::apply("p-l-06", + "POINT(2.5 0)", + "LINESTRING(2 0,3 0)", + 0, + strategy); + tester::apply("p-l-07", + "POINT(7.5 10)", + "LINESTRING(1 0,2 0,3 0,4 0,5 0,6 0,7 0,8 0,9 0)", + 10.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-l-08", + "POINT(7.5 10)", + "LINESTRING(1 1,2 1,3 1,4 1,5 1,6 1,7 1,20 2,21 2)", + ps_distance_from_wkt("POINT(7.5 10)", + "SEGMENT(7 1,20 2)", + strategy), + strategy); +} + +//=========================================================================== + +template +void test_distance_point_multilinestring(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "point/multilinestring distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + point_type, multi_linestring_type + > tester; + + tester::apply("p-ml-01", + "POINT(0 0)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))", + 2.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-ml-02", + "POINT(2.5 3)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))", + 3.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("p-ml-03", + "POINT(2 0)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))", + 0, + strategy); + tester::apply("p-ml-04", + "POINT(3 0)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))", + 0, + strategy); + tester::apply("p-ml-05", + "POINT(2.5 0)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0))", + 0, + strategy); + tester::apply("p-ml-06", + "POINT(7.5 10)", + "MULTILINESTRING((-5 0,-3 0),(2 0,3 0,4 0,5 0,6 0,20 1,21 1))", + ps_distance_from_wkt("POINT(7.5 10)", + "SEGMENT(6 0,20 1)", + strategy), + strategy); + tester::apply("p-ml-07", + "POINT(-8 10)", + "MULTILINESTRING((-20 10,-19 11,-18 10,-6 0,-5 0,-3 0),(2 0,6 0,20 1,21 1))", + ps_distance_from_wkt("POINT(-8 10)", + "SEGMENT(-6 0,-18 10)", + strategy), + strategy); +} + +//=========================================================================== + +template +void test_distance_linestring_multipoint(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "linestring/multipoint distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + linestring_type, multi_point_type + > tester; + + tester::apply("l-mp-01", + "LINESTRING(2 0,0 2,100 80)", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + ps_distance_from_wkt("POINT(1 1)", + "SEGMENT(2 0,0 2)", + strategy), + strategy); + tester::apply("l-mp-02", + "LINESTRING(4 0,0 4,100 80)", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + ps_distance_from_wkt("POINT(1 1)", + "SEGMENT(0 4,4 0)", + strategy), + strategy); + tester::apply("l-mp-03", + "LINESTRING(1 1,2 2,100 80)", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + 0, + strategy); + tester::apply("l-mp-04", + "LINESTRING(3 3,4 4,100 80)", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + pp_distance_from_wkt("POINT(1 1)", "POINT(3 3)", strategy), + strategy); + tester::apply("l-mp-05", + "LINESTRING(0 0,10 0,10 10,0 10,0 0)", + "MULTIPOINT(1 -1,80 80,5 0,150 90)", + 0, + strategy); +} + +//=========================================================================== + +template +void test_distance_multipoint_multilinestring(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "multipoint/multilinestring distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + multi_point_type, multi_linestring_type + > tester; + + tester::apply("mp-ml-01", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "MULTILINESTRING((2 0,0 2),(2 2,3 3))", + ps_distance_from_wkt("POINT(1 1)", + "SEGMENT(2 0,0 2)", + strategy), + strategy); + tester::apply("mp-ml-02", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "MULTILINESTRING((3 0,0 3),(4 4,5 5))", + ps_distance_from_wkt("POINT(1 1)", + "SEGMENT(3 0,0 3)", + strategy), + strategy); + tester::apply("mp-ml-03", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "MULTILINESTRING((4 4,5 5),(1 1,2 2))", + 0, + strategy); + tester::apply("mp-ml-04", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "MULTILINESTRING((4 4,3 3),(4 4,5 5))", + pp_distance_from_wkt("POINT(1 1)", "POINT(3 3)", strategy), + strategy); +} + +//=========================================================================== + +template +void test_distance_multipoint_segment(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "multipoint/segment distance tests" << std::endl; +#endif + typedef test_distance_of_geometries tester; + + tester::apply("mp-s-01", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "SEGMENT(2 0,0 2)", + ps_distance_from_wkt("POINT(1 1)", + "SEGMENT(2 0,0 2)", + strategy), + strategy); + tester::apply("mp-s-02", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "SEGMENT(0 -3,1 -10)", + 3.0 * bg::math::d2r * strategy.radius(), + strategy); + tester::apply("mp-s-03", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "SEGMENT(1 1,2 2)", + 0, + strategy); + tester::apply("mp-s-04", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "SEGMENT(3 3,4 4)", + pp_distance_from_wkt("POINT(1 1)", "POINT(3 3)", strategy), + strategy); + tester::apply("mp-s-05", + "MULTIPOINT(0 0,1 0,0 1,1 1)", + "SEGMENT(0.5 -3,1 -10)", + pp_distance_from_wkt("POINT(1 0)", "POINT(0.5 -3)", strategy), + strategy); +} + +//=========================================================================== + +template +void test_more_empty_input_pointlike_linear(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "testing on empty inputs... " << std::flush; +#endif + bg::model::linestring line_empty; + bg::model::multi_point multipoint_empty; + bg::model::multi_linestring > multiline_empty; + + Point point = from_wkt("POINT(0 0)"); + bg::model::linestring line = + from_wkt >("LINESTRING(0 0,1 1)"); + + // 1st geometry is empty + test_empty_input(multipoint_empty, line, strategy); + + // 2nd geometry is empty + test_empty_input(point, line_empty, strategy); + test_empty_input(point, multiline_empty, strategy); + + // both geometries are empty + test_empty_input(multipoint_empty, line_empty, strategy); + test_empty_input(multipoint_empty, multiline_empty, strategy); + +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << "done!" << std::endl; +#endif +} + + +//=========================================================================== +//=========================================================================== +//=========================================================================== + +BOOST_AUTO_TEST_CASE( test_all_point_segment ) +{ + test_distance_point_segment(point_segment_strategy()); + test_distance_point_segment(point_segment_strategy(earth_radius_km)); + test_distance_point_segment(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_point_linestring ) +{ + test_distance_point_linestring(point_segment_strategy()); + test_distance_point_linestring(point_segment_strategy(earth_radius_km)); + test_distance_point_linestring(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_point_multilinestring ) +{ + test_distance_point_multilinestring(point_segment_strategy()); + test_distance_point_multilinestring(point_segment_strategy(earth_radius_km)); + test_distance_point_multilinestring(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_linestring_multipoint ) +{ + test_distance_linestring_multipoint(point_segment_strategy()); + test_distance_linestring_multipoint(point_segment_strategy(earth_radius_km)); + test_distance_linestring_multipoint(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_multipoint_multilinestring ) +{ + test_distance_multipoint_multilinestring(point_segment_strategy()); + test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_km)); + test_distance_multipoint_multilinestring(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_multipoint_segment ) +{ + test_distance_multipoint_segment(point_segment_strategy()); + test_distance_multipoint_segment(point_segment_strategy(earth_radius_km)); + test_distance_multipoint_segment(point_segment_strategy(earth_radius_miles)); +} + +BOOST_AUTO_TEST_CASE( test_all_empty_input_pointlike_linear ) +{ + test_more_empty_input_pointlike_linear + < + point_type + >(point_segment_strategy()); + + test_more_empty_input_pointlike_linear + < + point_type + >(point_segment_strategy(earth_radius_km)); + + test_more_empty_input_pointlike_linear + < + point_type + >(point_segment_strategy(earth_radius_miles)); +} From 2fbe01ae4654aaa49a85c5258e615284f303caa8 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 12 Nov 2014 01:10:15 +0100 Subject: [PATCH 7/8] [extensions] Fix ellipsoid one-argument ctor. --- .../geometry/extensions/gis/geographic/detail/ellipsoid.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp b/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp index b7b3c69d5..8a45ed450 100644 --- a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp +++ b/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp @@ -42,9 +42,11 @@ class ellipsoid , m_b(T(6356752.314245)) , m_f((m_a - m_b) / m_a) {} - // Unit sphere + + // Unit ellipsoid ellipsoid(T const& f) : m_a(1.0) + , m_b(T(1) - f) , m_f(f) {} From 226272833bd611d918e1db9e45c308ebff07af88 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 12 Nov 2014 11:46:24 +0100 Subject: [PATCH 8/8] [extensions] Remove unneeded constructors from andoyer strategy and ellipsoid. --- .../extensions/gis/geographic/detail/ellipsoid.hpp | 7 ------- .../extensions/gis/geographic/strategies/andoyer.hpp | 4 ---- 2 files changed, 11 deletions(-) diff --git a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp b/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp index 8a45ed450..a2b7b4703 100644 --- a/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp +++ b/include/boost/geometry/extensions/gis/geographic/detail/ellipsoid.hpp @@ -42,13 +42,6 @@ class ellipsoid , m_b(T(6356752.314245)) , m_f((m_a - m_b) / m_a) {} - - // Unit ellipsoid - ellipsoid(T const& f) - : m_a(1.0) - , m_b(T(1) - f) - , m_f(f) - {} T a() const { return m_a; } T b() const { return m_b; } diff --git a/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp b/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp index ee75b033f..b20a9aa0a 100644 --- a/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp +++ b/include/boost/geometry/extensions/gis/geographic/strategies/andoyer.hpp @@ -69,10 +69,6 @@ public : : m_ellipsoid() {} - explicit inline andoyer(RadiusType f) - : m_ellipsoid(f) - {} - explicit inline andoyer(geometry::detail::ellipsoid const& e) : m_ellipsoid(e) {}