// Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // This file was modified by Oracle on 2014. // Modifications copyright (c) 2014, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #include #include #include #include #include #include #include #include #include #include // This test is GIS oriented. template void test_distance( typename bg::coordinate_type::type const& lon1, typename bg::coordinate_type::type const& lat1, typename bg::coordinate_type::type const& lon2, typename bg::coordinate_type::type const& lat2, typename bg::coordinate_type::type const& lon3, typename bg::coordinate_type::type const& lat3, typename bg::coordinate_type::type const& radius, typename bg::coordinate_type::type const& expected, typename bg::coordinate_type::type const& tolerance) { typedef bg::strategy::distance::cross_track < typename bg::coordinate_type::type > strategy_type; typedef typename bg::strategy::distance::services::return_type < strategy_type, Point, Point >::type return_type; { // compile-check if there is a strategy for this type typedef typename bg::strategy::distance::services::default_strategy < bg::point_tag, bg::segment_tag, Point, Point >::type cross_track_strategy_type; typedef typename bg::strategy::distance::services::default_strategy < bg::segment_tag, bg::point_tag, Point, Point >::type reversed_tags_cross_track_strategy_type; boost::ignore_unused(); } BOOST_CONCEPT_ASSERT ( (bg::concepts::PointSegmentDistanceStrategy) ); Point p1, p2, p3; bg::assign_values(p1, lon1, LatitudePolicy::apply(lat1)); bg::assign_values(p2, lon2, LatitudePolicy::apply(lat2)); bg::assign_values(p3, lon3, LatitudePolicy::apply(lat3)); strategy_type strategy; return_type d = strategy.apply(p1, p2, p3); BOOST_CHECK_CLOSE(radius * d, expected, tolerance); // The strategy should return the same result if we reverse the parameters d = strategy.apply(p1, p3, p2); BOOST_CHECK_CLOSE(radius * d, expected, tolerance); // Test specifying radius explicitly strategy_type strategy_radius(radius); d = strategy_radius.apply(p1, p2, p3); BOOST_CHECK_CLOSE(d, expected, tolerance); // Test the "default strategy" registration bg::model::referring_segment segment(p2, p3); d = bg::distance(p1, segment); BOOST_CHECK_CLOSE(radius * d, expected, tolerance); } template void test_case_boost_geometry_list_20120625() { // This function tests the bug submitted by Karsten Ahnert // on Boost.Geometry list at 2012-06-25, and wherefore he // submitted a patch a few days later. Point p1, p2; bg::model::segment s1, s2; bg::read_wkt("POINT(1 1)", p1); bg::read_wkt("POINT(5 1)", p2); bg::read_wkt("LINESTRING(0 2,2 2)", s1); bg::read_wkt("LINESTRING(2 2,4 2)", s2); BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s1), 0.0174586, 0.0001); BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s2), 0.0246783, 0.0001); BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s1), 0.0551745, 0.0001); BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s2), 0.0246783, 0.0001); // Check degenerated segments bg::model::segment s3; bg::read_wkt("LINESTRING(2 2,2 2)", s3); BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s3), 0.0246783, 0.0001); BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s3), 0.0551745, 0.0001); // Point/Point distance should be identical: Point p3; bg::read_wkt("POINT(2 2)", p3); BOOST_CHECK_CLOSE(boost::geometry::distance(p1, p3), 0.0246783, 0.0001); BOOST_CHECK_CLOSE(boost::geometry::distance(p2, p3), 0.0551745, 0.0001); } template void test_all() { typename bg::coordinate_type::type const average_earth_radius = 6372795.0; // distance (Paris <-> Amsterdam/Barcelona), // with coordinates rounded as below ~87 km // is equal to distance (Paris <-> Barcelona/Amsterdam) typename bg::coordinate_type::type const p_to_ab = 86.798321 * 1000.0; test_distance(2, 48, 4, 52, 2, 41, average_earth_radius, p_to_ab, 0.1); test_distance(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 0.1); test_case_boost_geometry_list_20120625(); } int test_main(int, char* []) { test_all >, geographic_policy >(); // NYI: haversine for mathematical spherical coordinate systems // test_all >, mathematical_policya >(); #if defined(HAVE_TTMATH) typedef ttmath::Big<1,4> tt; //test_all >, geographic_policy>(); #endif return 0; }