]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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> | |
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> | |
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> | |
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 | ||
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 | ||
7c673cae FG |
175 | return 0; |
176 | } |