• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3 
4 // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
5 // Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
6 // Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
7 
8 // This file was modified by Oracle on 2014.
9 // Modifications copyright (c) 2014, Oracle and/or its affiliates.
10 
11 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
12 
13 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
14 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
15 
16 // Use, modification and distribution is subject to the Boost Software License,
17 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
18 // http://www.boost.org/LICENSE_1_0.txt)
19 
20 
21 #include <geometry_test_common.hpp>
22 
23 #include <boost/core/ignore_unused.hpp>
24 
25 #include <boost/geometry/io/wkt/read.hpp>
26 
27 #include <boost/geometry/algorithms/assign.hpp>
28 #include <boost/geometry/algorithms/distance.hpp>
29 
30 #include <boost/geometry/strategies/spherical/distance_haversine.hpp>
31 #include <boost/geometry/strategies/spherical/distance_cross_track.hpp>
32 
33 #include <boost/geometry/strategies/concepts/distance_concept.hpp>
34 
35 #include <boost/geometry/geometries/point.hpp>
36 #include <boost/geometry/geometries/segment.hpp>
37 
38 
39 // This test is GIS oriented.
40 
41 
42 template <typename Point, typename LatitudePolicy>
test_distance(typename bg::coordinate_type<Point>::type const & lon1,typename bg::coordinate_type<Point>::type const & lat1,typename bg::coordinate_type<Point>::type const & lon2,typename bg::coordinate_type<Point>::type const & lat2,typename bg::coordinate_type<Point>::type const & lon3,typename bg::coordinate_type<Point>::type const & lat3,typename bg::coordinate_type<Point>::type const & radius,typename bg::coordinate_type<Point>::type const & expected,typename bg::coordinate_type<Point>::type const & tolerance)43 void test_distance(
44             typename bg::coordinate_type<Point>::type const& lon1,
45             typename bg::coordinate_type<Point>::type const& lat1,
46             typename bg::coordinate_type<Point>::type const& lon2,
47             typename bg::coordinate_type<Point>::type const& lat2,
48             typename bg::coordinate_type<Point>::type const& lon3,
49             typename bg::coordinate_type<Point>::type const& lat3,
50             typename bg::coordinate_type<Point>::type const& radius,
51             typename bg::coordinate_type<Point>::type const& expected,
52             typename bg::coordinate_type<Point>::type const& tolerance)
53 {
54     typedef bg::strategy::distance::cross_track
55         <
56             typename bg::coordinate_type<Point>::type
57         > strategy_type;
58 
59     typedef typename bg::strategy::distance::services::return_type
60         <
61             strategy_type,
62             Point,
63             Point
64         >::type return_type;
65 
66 
67     {
68         // compile-check if there is a strategy for this type
69         typedef typename bg::strategy::distance::services::default_strategy
70             <
71                 bg::point_tag, bg::segment_tag, Point, Point
72             >::type cross_track_strategy_type;
73 
74         typedef typename bg::strategy::distance::services::default_strategy
75             <
76                 bg::segment_tag, bg::point_tag, Point, Point
77             >::type reversed_tags_cross_track_strategy_type;
78 
79         boost::ignore_unused<cross_track_strategy_type,
80                              reversed_tags_cross_track_strategy_type>();
81     }
82 
83 
84     BOOST_CONCEPT_ASSERT
85         (
86             (bg::concepts::PointSegmentDistanceStrategy<strategy_type, Point, Point>)
87         );
88 
89 
90     Point p1, p2, p3;
91     bg::assign_values(p1, lon1, LatitudePolicy::apply(lat1));
92     bg::assign_values(p2, lon2, LatitudePolicy::apply(lat2));
93     bg::assign_values(p3, lon3, LatitudePolicy::apply(lat3));
94 
95 
96     strategy_type strategy;
97     return_type d = strategy.apply(p1, p2, p3);
98 
99     BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
100 
101     // The strategy should return the same result if we reverse the parameters
102     d = strategy.apply(p1, p3, p2);
103     BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
104 
105     // Test specifying radius explicitly
106     strategy_type strategy_radius(radius);
107     d = strategy_radius.apply(p1, p2, p3);
108     BOOST_CHECK_CLOSE(d, expected, tolerance);
109 
110 
111     // Test the "default strategy" registration
112     bg::model::referring_segment<Point const> segment(p2, p3);
113     d = bg::distance(p1, segment);
114     BOOST_CHECK_CLOSE(radius * d, expected, tolerance);
115 }
116 
117 
118 template <typename Point>
test_case_boost_geometry_list_20120625()119 void test_case_boost_geometry_list_20120625()
120 {
121     // This function tests the bug submitted by Karsten Ahnert
122     // on Boost.Geometry list at 2012-06-25, and wherefore he
123     // submitted a patch a few days later.
124 
125     Point p1, p2;
126     bg::model::segment<Point> s1, s2;
127 
128     bg::read_wkt("POINT(1 1)", p1);
129     bg::read_wkt("POINT(5 1)", p2);
130     bg::read_wkt("LINESTRING(0 2,2 2)", s1);
131     bg::read_wkt("LINESTRING(2 2,4 2)", s2);
132 
133     BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s1), 0.0174586, 0.0001);
134     BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s2), 0.0246783, 0.0001);
135     BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s1), 0.0551745, 0.0001);
136     BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s2), 0.0246783, 0.0001);
137 
138     // Check degenerated segments
139     bg::model::segment<Point> s3;
140     bg::read_wkt("LINESTRING(2 2,2 2)", s3);
141     BOOST_CHECK_CLOSE(boost::geometry::distance(p1, s3), 0.0246783, 0.0001);
142     BOOST_CHECK_CLOSE(boost::geometry::distance(p2, s3), 0.0551745, 0.0001);
143 
144     // Point/Point distance should be identical:
145     Point p3;
146     bg::read_wkt("POINT(2 2)", p3);
147     BOOST_CHECK_CLOSE(boost::geometry::distance(p1, p3), 0.0246783, 0.0001);
148     BOOST_CHECK_CLOSE(boost::geometry::distance(p2, p3), 0.0551745, 0.0001);
149 }
150 
151 
152 template <typename Point, typename LatitudePolicy>
test_all()153 void test_all()
154 {
155     typename bg::coordinate_type<Point>::type const average_earth_radius = 6372795.0;
156 
157     // distance (Paris <-> Amsterdam/Barcelona),
158     // with coordinates rounded as below ~87 km
159     // is equal to distance (Paris <-> Barcelona/Amsterdam)
160     typename bg::coordinate_type<Point>::type const p_to_ab = 86.798321 * 1000.0;
161     test_distance<Point, LatitudePolicy>(2, 48, 4, 52, 2, 41, average_earth_radius, p_to_ab, 0.1);
162     test_distance<Point, LatitudePolicy>(2, 48, 2, 41, 4, 52, average_earth_radius, p_to_ab, 0.1);
163 
164     test_case_boost_geometry_list_20120625<Point>();
165 }
166 
167 
test_main(int,char * [])168 int test_main(int, char* [])
169 {
170     test_all<bg::model::point<double, 2, bg::cs::spherical_equatorial<bg::degree> >, geographic_policy >();
171 
172     // NYI: haversine for mathematical spherical coordinate systems
173     // test_all<bg::model::point<double, 2, bg::cs::spherical<bg::degree> >, mathematical_policya >();
174 
175 #if defined(HAVE_TTMATH)
176     typedef ttmath::Big<1,4> tt;
177     //test_all<bg::model::point<tt, 2, bg::cs::geographic<bg::degree> >, geographic_policy>();
178 #endif
179 
180     return 0;
181 }
182