]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/geometry/test/algorithms/envelope_expand/envelope_on_spheroid.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / envelope_expand / envelope_on_spheroid.cpp
CommitLineData
7c673cae
FG
1// Boost.Geometry (aka GGL, Generic Geometry Library)
2// Unit Test
3
92f5a8d4 4// Copyright (c) 2015-2018, Oracle and/or its affiliates.
7c673cae 5
b32b8144 6// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7c673cae
FG
7// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9
10// Licensed under the Boost Software License version 1.0.
11// http://www.boost.org/users/license.html
12
13
14#ifndef BOOST_TEST_MODULE
b32b8144 15#define BOOST_TEST_MODULE test_envelope_on_sphere_or_spheroid
7c673cae
FG
16#endif
17
18#include <boost/test/included/unit_test.hpp>
19
20#include <cstddef>
21#include <limits>
22#include <iostream>
23#include <string>
24
25#include <geometry_test_common.hpp>
26#include <from_wkt.hpp>
27
28#include <boost/numeric/conversion/bounds.hpp>
29#include <boost/type_traits/is_same.hpp>
30
31#include <boost/geometry/core/coordinate_dimension.hpp>
32#include <boost/geometry/core/tag.hpp>
33#include <boost/geometry/core/tags.hpp>
34
35#include <boost/geometry/geometries/geometries.hpp>
36
37#include <boost/geometry/util/condition.hpp>
38
39#include <boost/geometry/io/dsv/write.hpp>
40#include <boost/geometry/io/wkt/wkt.hpp>
41
42#include <boost/geometry/algorithms/convert.hpp>
43#include <boost/geometry/algorithms/envelope.hpp>
44#include <boost/geometry/algorithms/reverse.hpp>
45
46#include <boost/geometry/index/detail/algorithms/is_valid.hpp>
47
48#include "test_envelope_expand_on_spheroid.hpp"
49
50
b32b8144
FG
51template <typename FormulaPolicy, typename CS_Tag>
52struct test_envelope
53{
54 template <typename Geometry, typename Box>
55 static inline void apply(Geometry& geometry, Box& detected)
56 {
57 bg::envelope(geometry, detected);
58 }
59};
60
61template <typename FormulaPolicy>
62struct test_envelope<FormulaPolicy, bg::geographic_tag>
63{
64 template <typename Geometry, typename Box>
65 static inline void apply(Geometry& geometry,
66 Box& detected)
67 {
92f5a8d4
TL
68 typedef bg::strategy::envelope::spherical_point point_strategy_t;
69 typedef bg::strategy::envelope::spherical_multipoint multi_point_strategy_t;
70 typedef bg::strategy::envelope::spherical_box box_strategy_t;
71 typedef bg::strategy::envelope::geographic<FormulaPolicy, bg::srs::spheroid<double>, double> strategy_t;
b32b8144 72
92f5a8d4
TL
73 typename boost::mpl::if_c
74 <
75 boost::is_same<typename bg::tag<Geometry>::type, bg::point_tag>::value,
76 point_strategy_t,
77 typename boost::mpl::if_c
78 <
79 boost::is_same<typename bg::tag<Geometry>::type, bg::multi_point_tag>::value,
80 multi_point_strategy_t,
81 typename boost::mpl::if_c
82 <
83 boost::is_same<typename bg::tag<Geometry>::type, bg::box_tag>::value,
84 box_strategy_t,
85 strategy_t
86 >::type
87 >::type
88 >::type strategy;
89
90 bg::envelope(geometry, detected, strategy);
b32b8144
FG
91 }
92};
93
94template <typename MBR, typename FormulaPolicy = bg::strategy::thomas>
7c673cae
FG
95class envelope_on_spheroid_basic_tester
96{
97private:
98 template
99 <
100 typename Geometry,
101 typename Tag = typename bg::tag<Geometry>::type
102 >
103 struct write_geometry
104 {
105 template <typename OutputStream>
106 static inline OutputStream& apply(OutputStream& os,
107 Geometry const& geometry)
108 {
109 os << bg::wkt(geometry);
110 return os;
111 }
112 };
113
114 template <typename Segment>
115 struct write_geometry<Segment, bg::segment_tag>
116 {
117 template <typename OutputStream>
118 static inline OutputStream& apply(OutputStream& os,
119 Segment const& segment)
120 {
121 os << "SEGMENT" << bg::dsv(segment);
122 return os;
123 }
124 };
125
126 template <typename Box>
127 struct write_geometry<Box, bg::box_tag>
128 {
129 template <typename OutputStream>
130 static inline OutputStream& apply(OutputStream& os,
131 Box const& box)
132 {
133 os << "BOX" << bg::dsv(box);
134 return os;
135 }
136 };
137
138 template <typename Geometry, typename Box>
139 static inline void check_message(bool same_boxes,
140 std::string const& case_id,
141 std::string const& units_str,
142 Geometry const& geometry,
143 Box const& expected,
144 Box const& detected)
145 {
146 std::ostringstream stream;
147 stream << "case ID: " << case_id << ", "
148 << "MBR units: " << units_str << "; "
149 << "geometry: ";
150
151 write_geometry<Geometry>::apply(stream, geometry);
152
153 stream << std::setprecision(17);
154
155 stream << "; " << "expected: " << bg::dsv(expected)
156 << ", " << "detected: " << bg::dsv(detected);
157
158 BOOST_CHECK_MESSAGE(same_boxes, stream.str());
159 }
160
b32b8144
FG
161 template
162 <
163 typename Geometry, typename Box,
164 typename T1, typename T2, typename T3, typename T4
165 >
166 static inline void check_message(bool same_boxes,
167 std::string const& case_id,
168 std::string const& units_str,
169 Geometry const& geometry,
170 T1 const& lon_min, T2 const& lat_min, double height_min,
171 T3 const& lon_max, T4 const& lat_max, double height_max,
172 Box const& detected)
173 {
174 std::ostringstream stream;
175 stream << "case ID: " << case_id << ", "
176 << "MBR units: " << units_str << "; "
177 << "geometry: ";
178
179 write_geometry<Geometry>::apply(stream, geometry);
180
181 stream << std::setprecision(17);
182
183 stream << "; " << "expected: ";
184
185 if (BOOST_GEOMETRY_CONDITION(bg::dimension<Box>::value == 2))
186 {
187 stream << "(" << lon_min << " " << lat_min
188 << ", " << lon_max << " " << lat_max << ")";
189 }
190 else
191 {
192 stream << "(" << lon_min << " " << lat_min << " " << height_min
193 << ", " << lon_max << " " << lat_max << " " << height_max << ")";
194 }
195 stream << ", " << "detected: " << bg::dsv(detected);
196
197 BOOST_CHECK_MESSAGE(same_boxes, stream.str());
198 }
199
200 template
201 <
202 typename Box, typename Geometry,
203 typename T1, typename T2, typename T3, typename T4
204 >
7c673cae
FG
205 static inline void base_test(std::string const& case_id,
206 Geometry const& geometry,
b32b8144
FG
207 T1 const& lon_min, T2 const& lat_min, double height_min,
208 T3 const& lon_max, T4 const& lat_max, double height_max,
7c673cae
FG
209 double tolerance)
210 {
211 typedef typename bg::coordinate_system<Box>::type::units box_units_type;
212
213 std::string const units_str = units2string<box_units_type>();
214
215 Box detected;
b32b8144
FG
216 test_envelope<FormulaPolicy, typename bg::cs_tag<Geometry>::type>
217 ::apply(geometry, detected);
7c673cae
FG
218
219#ifdef BOOST_GEOMETRY_TEST_DEBUG
220 std::cout << "geometry: ";
221 write_geometry<Geometry>::apply(std::cout, geometry);
222
223 std::cout << std::endl
224 << "MBR units: " << units_str
b32b8144
FG
225 << std::endl;
226 std::cout << "expected: ";
227 if (BOOST_GEOMETRY_CONDITION(bg::dimension<Box>::value == 2))
228 {
229 std::cout << "(" << lon_min << " " << lat_min
230 << ", " << lon_max << " " << lat_max << ")";
231 }
232 else
233 {
234 std::cout << "(" << lon_min << " " << lat_min << " " << height_min
235 << ", " << lon_max << " " << lat_max << " " << height_max << ")";
236 }
237 std::cout << std::endl
7c673cae
FG
238 << "detected: " << bg::dsv(detected)
239 << std::endl << std::endl;
240#endif
241
b32b8144
FG
242 bool check = box_check_equals<Box>::apply(detected,
243 lon_min, lat_min, height_min,
244 lon_max, lat_max, height_max,
245 tolerance);
246
247 check_message(check,
7c673cae 248 case_id, units_str,
b32b8144
FG
249 geometry,
250 lon_min, lat_min, height_min,
251 lon_max, lat_max, height_max,
252 detected);
7c673cae
FG
253
254 // if valid box is expected, check the validity
255 if (lon_min <= lon_max && lat_min <= lat_max && height_min <= height_max)
256 {
257 BOOST_CHECK_MESSAGE(bg::index::detail::is_valid(detected),
258 "Case ID: " << case_id << ", "
259 << "MBR units: " << units_str << "; "
260 << "Invalid Box: " << bg::dsv(detected));
261 }
262 }
263
264public:
b32b8144
FG
265 template
266 <
267 typename Geometry,
268 typename T1, typename T2, typename T3, typename T4
269 >
7c673cae
FG
270 static inline void apply(std::string const& case_id,
271 Geometry const& geometry,
b32b8144
FG
272 T1 const& lon_min, T2 const& lat_min, double height_min,
273 T3 const& lon_max, T4 const& lat_max, double height_max,
7c673cae
FG
274 double tolerance)
275 {
276 typedef other_system_info
277 <
278 typename bg::coordinate_system<MBR>::type
279 > other;
280
281 typedef bg::model::box
282 <
283 bg::model::point
284 <
285 typename bg::coordinate_type<MBR>::type,
286 bg::dimension<MBR>::value,
287 typename other::type
288 >
289 > other_mbr_type;
290
291#ifdef BOOST_GEOMETRY_TEST_DEBUG
292 std::cout << std::endl << std::endl;
293 std::cout << "case ID: " << case_id << std::endl << std::endl;
294#endif
295
296 base_test<MBR>(case_id, geometry,
297 lon_min, lat_min, height_min,
298 lon_max, lat_max, height_max,
299 tolerance);
300
301 if (lon_max < lon_min)
302 {
303 // we are in the case were a special MBR is returned;
304 // makes no sense to change units
305 base_test<other_mbr_type>(case_id, geometry,
306 lon_min, lat_min, height_min,
307 lon_max, lat_max, height_max,
308 tolerance);
309 }
310 else
311 {
312 base_test<other_mbr_type>(case_id, geometry,
313 other::convert(lon_min),
314 other::convert(lat_min),
315 height_min,
316 other::convert(lon_max),
317 other::convert(lat_max),
318 height_max,
319 tolerance);
320 }
321 }
322};
323
324
325// test the reverse of a geometry if it is either linear or ring
326template <typename Geometry, typename Tag = typename bg::tag<Geometry>::type>
327struct test_reverse_geometry
328{
329 static bool const is_linear =
330 boost::is_same<Tag, bg::segment_tag>::value
331 || boost::is_same<Tag, bg::linestring_tag>::value
332 || boost::is_same<Tag, bg::multi_linestring_tag>::value;
333
334 // currently disable rings
335 static bool const is_ring = false;
336 // static bool const is_ring = boost::is_same<Tag, bg::ring_tag>::value;
337
338 typedef typename boost::mpl::if_c
339 <
340 is_linear || is_ring,
341 boost::true_type,
342 boost::false_type
343 >::type type;
344
345 static bool const value = type::value;
346};
347
348template
349<
350 typename Geometry,
351 typename MBR,
352 typename Tag = typename bg::tag<Geometry>::type,
b32b8144
FG
353 bool TestReverse = test_reverse_geometry<Geometry>::value,
354 typename FormulaPolicy = bg::strategy::thomas
7c673cae 355>
b32b8144 356struct test_envelope_on_sphere_or_spheroid
7c673cae 357{
b32b8144
FG
358 template <typename T1, typename T2, typename T3, typename T4,
359 typename T5, typename T6, typename T7, typename T8>
7c673cae
FG
360 static inline void apply(std::string const& case_id,
361 Geometry const& geometry,
b32b8144
FG
362 T1 const& lon_min1, T2 const& lat_min1, double height_min1,
363 T3 const& lon_max1, T4 const& lat_max1, double height_max1,
364 T5 const& lon_min2, T6 const& lat_min2, double height_min2,
365 T7 const& lon_max2, T8 const& lat_max2, double height_max2,
7c673cae
FG
366 double tolerance = std::numeric_limits<double>::epsilon())
367 {
368 envelope_on_spheroid_basic_tester
369 <
b32b8144 370 MBR, FormulaPolicy
7c673cae
FG
371 >::apply(case_id, geometry,
372 lon_min1, lat_min1, height_min1,
373 lon_max1, lat_max1, height_max1,
374 tolerance);
375
376 if (BOOST_GEOMETRY_CONDITION(TestReverse))
377 {
378 std::string reversed_case_id = case_id + "-reverse";
379
380 Geometry reversed_geometry = geometry;
381 bg::reverse(reversed_geometry);
382 envelope_on_spheroid_basic_tester
383 <
b32b8144 384 MBR, FormulaPolicy
7c673cae
FG
385 >::apply(reversed_case_id, reversed_geometry,
386 lon_min2, lat_min2, height_min2,
387 lon_max2, lat_max2, height_max2,
b32b8144 388 tolerance);
7c673cae
FG
389 }
390
391#ifdef BOOST_GEOMETRY_TEST_DEBUG
392 std::cout << "=================="
393 << std::endl << std::endl;
394#endif
395 }
396
b32b8144
FG
397 template <typename T1, typename T2, typename T3, typename T4,
398 typename T5, typename T6, typename T7, typename T8>
7c673cae
FG
399 static inline void apply(std::string const& case_id,
400 Geometry const& geometry,
b32b8144
FG
401 T1 const& lon_min1, T2 const& lat_min1,
402 T3 const& lon_max1, T4 const& lat_max1,
403 T5 const& lon_min2, T6 const& lat_min2,
404 T7 const& lon_max2, T8 const& lat_max2,
7c673cae
FG
405 double tolerance = std::numeric_limits<double>::epsilon())
406 {
407 apply(case_id, geometry,
408 lon_min1, lat_min1, 0, lon_max1, lat_max1, 0,
409 lon_min2, lat_min2, 0, lon_max2, lat_max2, 0,
410 tolerance);
411 }
412
b32b8144 413 template <typename T1, typename T2, typename T3, typename T4>
7c673cae
FG
414 static inline void apply(std::string const& case_id,
415 Geometry const& geometry,
b32b8144
FG
416 T1 const& lon_min, T2 const& lat_min, double height_min,
417 T3 const& lon_max, T4 const& lat_max, double height_max,
7c673cae
FG
418 double tolerance = std::numeric_limits<double>::epsilon())
419 {
420 apply(case_id, geometry,
421 lon_min, lat_min, height_min,
422 lon_max, lat_max, height_max,
423 lon_min, lat_min, height_min,
424 lon_max, lat_max, height_max,
425 tolerance);
426 }
427
b32b8144 428 template <typename T1, typename T2, typename T3, typename T4>
7c673cae
FG
429 static inline void apply(std::string const& case_id,
430 Geometry const& geometry,
b32b8144
FG
431 T1 const& lon_min, T2 const& lat_min,
432 T3 const& lon_max, T4 const& lat_max,
7c673cae
FG
433 double tolerance = std::numeric_limits<double>::epsilon())
434 {
435 apply(case_id, geometry,
436 lon_min, lat_min, 0, lon_max, lat_max, 0,
437 tolerance);
438 }
439};
440
441
442// special tester for rings
443template <typename Geometry, typename MBR, bool TestReverse>
b32b8144 444struct test_envelope_on_sphere_or_spheroid<Geometry, MBR, bg::ring_tag, TestReverse>
7c673cae 445{
b32b8144
FG
446 template <typename T1, typename T2, typename T3, typename T4,
447 typename T5, typename T6, typename T7, typename T8>
7c673cae
FG
448 static inline void apply(std::string const& case_id,
449 Geometry const& geometry,
b32b8144
FG
450 T1 const& lon_min1, T2 const& lat_min1,
451 T3 const& lon_max1, T4 const& lat_max1,
452 T5 const& lon_min2, T6 const& lat_min2,
453 T7 const& lon_max2, T8 const& lat_max2,
454 double const& tolerance = std::numeric_limits<double>::epsilon())
7c673cae
FG
455 {
456 envelope_on_spheroid_basic_tester
457 <
458 MBR
459 >::apply(case_id, geometry,
92f5a8d4
TL
460 lon_min1, lat_min1, 0,
461 lon_max1, lat_max1, 0,
7c673cae
FG
462 tolerance);
463
464 std::string ccw_case_id = case_id + "-2ccw";
465
466 bg::model::ring
467 <
468 typename bg::point_type<Geometry>::type, false
469 > ccw_ring;
470 bg::convert(geometry, ccw_ring);
b32b8144 471
7c673cae
FG
472 envelope_on_spheroid_basic_tester
473 <
474 MBR
475 >::apply(ccw_case_id, ccw_ring,
92f5a8d4
TL
476 lon_min2, lat_min2, 0,
477 lon_max2, lat_max2, 0,
7c673cae
FG
478 tolerance);
479
480#ifdef BOOST_GEOMETRY_TEST_DEBUG
481 std::cout << "=================="
482 << std::endl << std::endl;
483#endif
484 }
485
b32b8144 486 template <typename T1, typename T2, typename T3, typename T4>
7c673cae
FG
487 static inline void apply(std::string const& case_id,
488 Geometry const& geometry,
b32b8144
FG
489 T1 const& lon_min, T2 const& lat_min,
490 T3 const& lon_max, T4 const& lat_max,
7c673cae
FG
491 double tolerance = std::numeric_limits<double>::epsilon())
492 {
493 apply(case_id, geometry,
494 lon_min, lat_min, lon_max, lat_max,
495 lon_min, lat_min, lon_max, lat_max,
496 tolerance);
497 }
498};
499
500
501template <typename CoordinateSystem, typename Geometry>
502void test_empty_geometry(std::string const& case_id, std::string const& wkt)
503{
504 std::size_t const dim = bg::dimension<Geometry>::value;
505
506 typedef bg::model::point<double, dim, CoordinateSystem> point_type;
507 typedef bg::model::box<point_type> B;
b32b8144 508 typedef test_envelope_on_sphere_or_spheroid<Geometry, B> tester;
7c673cae
FG
509
510 typedef typename bg::coordinate_type<Geometry>::type ct;
511 ct high_val = boost::numeric::bounds<ct>::highest();
512 ct low_val = boost::numeric::bounds<ct>::lowest();
513
514 if (BOOST_GEOMETRY_CONDITION(dim == 2))
515 {
516 tester::apply(case_id,
517 from_wkt<Geometry>(wkt),
518 high_val, high_val, low_val, low_val);
519 }
520 else
521 {
522 tester::apply(case_id,
523 from_wkt<Geometry>(wkt),
524 high_val, high_val, high_val, low_val, low_val, low_val);
525 }
526}
527
528
529template <typename CoordinateSystem>
530void test_envelope_point()
531{
532 typedef bg::model::point<double, 2, CoordinateSystem> point_type;
533 typedef point_type G;
534 typedef bg::model::box<point_type> B;
b32b8144 535 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
536
537 tester::apply("p01",
538 from_wkt<G>("POINT(10 10)"),
539 10, 10, 10, 10);
540
541 tester::apply("p02",
542 from_wkt<G>("POINT(370 10)"),
543 10, 10, 10, 10);
544
545#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
546 tester::apply("p03",
547 from_wkt<G>("POINT(370 -350)"),
548 10, 10, 10, 10);
549#endif
550
551 // north and south poles
552 tester::apply("p04",
553 from_wkt<G>("POINT(0 90)"),
554 0, 90, 0, 90);
555
556 tester::apply("p04a",
557 from_wkt<G>("POINT(10 90)"),
558 0, 90, 0, 90);
559
560 tester::apply("p04b",
561 from_wkt<G>("POINT(270 90)"),
562 0, 90, 0, 90);
563
564#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
565 tester::apply("p04c",
566 from_wkt<G>("POINT(270 450)"),
567 0, 90, 0, 90);
568#endif
569
570 tester::apply("p04d",
571 from_wkt<G>("POINT(190 90)"),
572 0, 90, 0, 90);
573
574 tester::apply("p04e",
575 from_wkt<G>("POINT(-100 90)"),
576 0, 90, 0, 90);
577
578 tester::apply("p05",
579 from_wkt<G>("POINT(0 -90)"),
580 0, -90, 0, -90);
581
582 tester::apply("p05a",
583 from_wkt<G>("POINT(10 -90)"),
584 0, -90, 0, -90);
585
586 tester::apply("p05b",
587 from_wkt<G>("POINT(270 -90)"),
588 0, -90, 0, -90);
589
590#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
591 tester::apply("p05c",
592 from_wkt<G>("POINT(270 -450)"),
593 0, -90, 0, -90);
594#endif
595
596 tester::apply("p05d",
597 from_wkt<G>("POINT(190 -90)"),
598 0, -90, 0, -90);
599
600 tester::apply("p05e",
601 from_wkt<G>("POINT(-100 -90)"),
602 0, -90, 0, -90);
603
604 tester::apply("p05f",
605 from_wkt<G>("POINT(-100 -90)"),
606 0, -90, 0, -90);
607}
608
609BOOST_AUTO_TEST_CASE( envelope_point )
610{
611 test_envelope_point<bg::cs::spherical_equatorial<bg::degree> >();
612 test_envelope_point<bg::cs::geographic<bg::degree> >();
613}
614
615
616template <typename CoordinateSystem>
617void test_envelope_point_with_height()
618{
619 typedef bg::model::point<double, 3, CoordinateSystem> point_type;
620 typedef point_type G;
621 typedef bg::model::box<point_type> B;
b32b8144 622 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
623
624 tester::apply("ph01",
625 from_wkt<G>("POINT(10 10 1256)"),
626 10, 10, 1256, 10, 10, 1256);
627}
628
629BOOST_AUTO_TEST_CASE( envelope_point_with_height )
630{
631 test_envelope_point_with_height
632 <
633 bg::cs::spherical_equatorial<bg::degree>
634 >();
635 test_envelope_point_with_height<bg::cs::geographic<bg::degree> >();
636}
637
638
b32b8144 639BOOST_AUTO_TEST_CASE( envelope_segment_sphere )
7c673cae
FG
640{
641 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
642 typedef bg::model::point<double, 2, coordinate_system_type> P;
643 typedef bg::model::segment<P> G;
644 typedef bg::model::box<P> B;
b32b8144 645 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
646
647 double const eps = std::numeric_limits<double>::epsilon();
648
649 tester::apply("s01",
650 from_wkt<G>("SEGMENT(10 10,40 40)"),
651 10, 10, 40, 40);
652
653 tester::apply("s02",
654 from_wkt<G>("SEGMENT(10 10,40 10)"),
b32b8144
FG
655 10, 10, 40, 10.345270046149988);
656/*
657 tester::apply("s02",
658 from_wkt<G>("SEGMENT(1 2,70 1)"),
659 1, 1, 70, 2.01);
660*/
7c673cae
FG
661 tester::apply("s02a",
662 from_wkt<G>("SEGMENT(40 10,10 10)"),
663 10, 10, 40, 10.34527004614999);
664
665 tester::apply("s03",
666 from_wkt<G>("SEGMENT(160 10,-170 10)"),
667 160, 10, 190, 10.34527004614999);
668
669 tester::apply("s03a",
670 from_wkt<G>("SEGMENT(-170 10,160 10)"),
671 160, 10, 190, 10.34527004614999);
672
673 tester::apply("s03b",
674 from_wkt<G>("SEGMENT(-170 -10,160 -10)"),
675 160, -10.34527004614999, 190, -10);
676
677 tester::apply("s04",
678 from_wkt<G>("SEGMENT(-40 45,140 60)"),
679 -40, 45, 140, 90);
680
681 tester::apply("s04a",
682 from_wkt<G>("SEGMENT(-40 45,140 25)"),
683 -40, 25, 140, 90);
684
685 // segment ending at the north pole
686 tester::apply("s05",
687 from_wkt<G>("SEGMENT(40 45,80 90)"),
688 40, 45, 40, 90);
689
690 // segment starting at the north pole
691 tester::apply("s05a",
692 from_wkt<G>("SEGMENT(80 90,40 45)"),
693 40, 45, 40, 90);
694
695 // segment ending at the north pole
696 tester::apply("s06",
697 from_wkt<G>("SEGMENT(-40 45,80 90)"),
698 -40, 45, -40, 90);
699
700 // segment starting at the north pole
701 tester::apply("s06a",
702 from_wkt<G>("SEGMENT(70 90,-40 45)"),
703 -40, 45, -40, 90);
704
705 // segment ending at the north pole
706 tester::apply("s07",
707 from_wkt<G>("SEGMENT(40 -45,80 90)"),
708 40, -45, 40, 90);
709
710 // segment passing through the south pole
711 tester::apply("s08",
712 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
713 -170, -90, 10, -30);
714
715 tester::apply("s09",
716 from_wkt<G>("SEGMENT(1 -45,179 30)"),
717 1, -85.28884376852969, 179, 30,
718 3 * eps);
719
720 tester::apply("s09a",
721 from_wkt<G>("SEGMENT(2 -45,181 30)"),
722 2, -87.63659983704832, 181, 30);
723
724 // very long segment
725 tester::apply("s10",
726 from_wkt<G>("SEGMENT(0 -45,181 30)"),
b32b8144 727 -179, -87.636599837048323, 0, 30,
7c673cae
FG
728 2.0 * eps);
729
730 tester::apply("s11",
731 from_wkt<G>("SEGMENT(260 30,20 45)"),
732 -100, 30, 20, 57.93195594009233);
733
734 tester::apply("s11a",
735 from_wkt<G>("SEGMENT(260 45,20 30)"),
b32b8144 736 -100, 30, 20, 57.931955940092337);
7c673cae
FG
737
738 // segment degenerating to the north pole
739 tester::apply("s12",
740 from_wkt<G>("SEGMENT(10 90,20 90)"),
741 0, 90, 0, 90);
742
743 // segment degenerating to the south pole
744 tester::apply("s13",
745 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
746 0, -90, 0, -90);
747
748 tester::apply("s14",
749 from_wkt<G>("SEGMENT(20 20,10 30)"),
750 10, 20, 20, 30);//48.87458730907602);
751
752 tester::apply("s15",
753 from_wkt<G>("SEGMENT(50 45,185 45)"),
754 50, 45, 185, 69.05897952775615);
755
756 // segment that lies on the equator
757 tester::apply("s16",
758 from_wkt<G>("SEGMENT(0 0,50 0)"),
759 0, 0, 50, 0);
760
761 // segment that lies on the equator
762 tester::apply("s16a",
763 from_wkt<G>("SEGMENT(-50 0,50 0)"),
764 -50, 0, 50, 0);
765
766 // segment that lies on the equator and touches antimeridian
767 tester::apply("s16b",
768 from_wkt<G>("SEGMENT(50 0,180 0)"),
769 50, 0, 180, 0);
770
771 // segment that lies on the equator and crosses antimeridian
772 tester::apply("s16c",
773 from_wkt<G>("SEGMENT(-170 0,160 0)"),
774 160, 0, 190, 0);
775
776 tester::apply("s17",
777 from_wkt<G>("SEGMENT(140 10, -140 80)"),
778 140, 10, 220, 80);
779
780 tester::apply("s17-r",
781 from_wkt<G>("SEGMENT(-140 80, 140 10)"),
782 140, 10, 220, 80);
783
784 tester::apply("s18",
785 from_wkt<G>("SEGMENT(20 10, 100 80)"),
786 20, 10, 100, 80);
787
788 tester::apply("s18-r",
789 from_wkt<G>("SEGMENT(100 80, 20 10)"),
790 20, 10, 100, 80);
791
792 // segment connecting the north and south pole
793 //
794 // this should be forbidden actually, as it is not well-defined
795 // with this test we demonstrate that the algorithm still returns
796 // something meaningful
797 tester::apply("s99",
798 from_wkt<G>("SEGMENT(10 90,20 -90)"),
799 0, -90, 0, 90);
800
801 // https://svn.boost.org/trac/boost/ticket/12106
802 tester::apply("s100_ticket_12106",
803 G(P(11.488323611111111, 53.687086666666673), P(11.488324166666667, 53.687086666666673)),
804 11.488323611111111, 53.687086666666673, 11.488324166666667, 53.687086666666673);
805
806 double const heps = eps / 2;
807
808 tester::apply("s101",
809 G(P(1, 1), P(1-heps, 1-heps)),
810 1-heps, 1-heps, 1, 1);
811 tester::apply("s102",
812 G(P(1, 1), P(1, 1-heps)),
813 1, 1-heps, 1, 1);
814 tester::apply("s103",
815 G(P(1, 1), P(1-heps, 1)),
816 1-heps, 1, 1, 1);
817 tester::apply("s104",
818 G(P(2, 1), P(1, 1-heps)),
819 1, 1-heps, 2, 1.000038070652770505);
820 tester::apply("s105",
821 G(P(1, 2), P(1-heps, 1)),
822 1-heps, 1, 1, 2);
823}
824
b32b8144
FG
825BOOST_AUTO_TEST_CASE( envelope_segment_spherical_polar )
826{
827 typedef bg::cs::spherical<bg::degree> coordinate_system_type;
828 typedef bg::model::point<double, 2, coordinate_system_type> P;
829 typedef bg::model::segment<P> G;
830 typedef bg::model::box<P> B;
831 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
832
833 tester::apply("s01",
834 from_wkt<G>("SEGMENT(10 10,40 40)"),
835 10, 10, 40, 40);
836
837 tester::apply("s02",
838 from_wkt<G>("SEGMENT(10 80,40 80)"),
839 10, 90 - 10.345270046149988, 40, 80);
840
841 tester::apply("s03",
842 from_wkt<G>("SEGMENT(160 80,-170 80)"),
843 160, 90 - 10.34527004614999, 190, 80);
844
845 // segment ending at the north pole
846 tester::apply("s05",
847 from_wkt<G>("SEGMENT(40 45,80 0)"),
848 40, 0, 40, 45);
849}
850
851
852BOOST_AUTO_TEST_CASE( envelope_segment_spheroid )
853{
854 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
855 typedef bg::model::point<double, 2, coordinate_system_type> P;
856 typedef bg::model::segment<P> G;
857 typedef bg::model::box<P> B;
858 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
859
860 double const eps = std::numeric_limits<double>::epsilon();
861
862 tester::apply("s01",
863 from_wkt<G>("SEGMENT(10 10,40 40)"),
864 10, 10, 40, 40);
865
866 tester::apply("s02",
867 from_wkt<G>("SEGMENT(10 10,40 10)"),
868 10, 10, 40, 10.347587605817942);
869
870 tester::apply("s02a",
871 from_wkt<G>("SEGMENT(40 10,10 10)"),
872 10, 10, 40, 10.347587605817942);
873
874 tester::apply("s03",
875 from_wkt<G>("SEGMENT(160 10,-170 10)"),
876 160, 10, 190, 10.347587605817942);
877
878 tester::apply("s03a",
879 from_wkt<G>("SEGMENT(-170 10,160 10)"),
880 160, 10, 190, 10.347587605817942);
881
882 tester::apply("s03b",
883 from_wkt<G>("SEGMENT(-170 -10,160 -10)"),
884 160, -10.347587605817942, 190, -10);
885
886 tester::apply("s04",
887 from_wkt<G>("SEGMENT(-40 45,140 60)"),
888 -40, 45, 140, 90);
889
890 tester::apply("s04a",
891 from_wkt<G>("SEGMENT(-40 45,140 25)"),
892 -40, 25, 140, 90);
893
894 // segment ending at the north pole
895 tester::apply("s05",
896 from_wkt<G>("SEGMENT(40 45,80 90)"),
897 40, 45, 40, 90);
898
899 // segment starting at the north pole
900 tester::apply("s05a",
901 from_wkt<G>("SEGMENT(80 90,40 45)"),
902 40, 45, 40, 90);
903
904 // segment ending at the north pole
905 tester::apply("s06",
906 from_wkt<G>("SEGMENT(-40 45,80 90)"),
907 -40, 45, -40, 90);
908
909 // segment starting at the north pole
910 tester::apply("s06a",
911 from_wkt<G>("SEGMENT(70 90,-40 45)"),
912 -40, 45, -40, 90);
913
914 // segment ending at the north pole
915 tester::apply("s07",
916 from_wkt<G>("SEGMENT(40 -45,80 90)"),
917 40, -45, 40, 90);
918
919 // segment passing through the south pole
920 tester::apply("s08",
921 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
922 -170, -90, 10, -30);
923
924 tester::apply("s09",
925 from_wkt<G>("SEGMENT(1 -45,179 30)"),
926 1, rng(-85.392785243526134, -85.392785243525253), 179, 30);
927
928 tester::apply("s09a",
929 from_wkt<G>("SEGMENT(2 -45,181 30)"),
930 2, rng(-87.689300911353811, -87.689300911353371), 181, 30);
931
932 // very long segment
933 tester::apply("s10",
934 from_wkt<G>("SEGMENT(0 -45,181 30)"),
935 -179, rng(-87.689300911353797, -87.689300911353385), 0, 30);
936
937 tester::apply("s11",
938 from_wkt<G>("SEGMENT(260 30,20 45)"),
939 -100, 30, 20, rng(57.990810958016482, 57.990810958016965));
940
941 tester::apply("s11a",
942 from_wkt<G>("SEGMENT(260 45,20 30)"),
943 -100, 30, 20, rng(57.990810958016453, 57.990810958016965));
944
945 // segment degenerating to the north pole
946 tester::apply("s12",
947 from_wkt<G>("SEGMENT(10 90,20 90)"),
948 0, 90, 0, 90);
949
950 // segment degenerating to the south pole
951 tester::apply("s13",
952 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
953 0, -90, 0, -90);
954
955 tester::apply("s14",
956 from_wkt<G>("SEGMENT(20 20,10 30)"),
957 10, 20, 20, 30);//48.87458730907602);
958
959 tester::apply("s15",
960 from_wkt<G>("SEGMENT(50 45,185 45)"),
961 50, 45, 185, rng(69.098479073902851, 69.098479073903178));
962
963 // segment that lies on the equator
964 tester::apply("s16",
965 from_wkt<G>("SEGMENT(0 0,50 0)"),
966 0, 0, 50, 0);
967
968 // segment that lies on the equator
969 tester::apply("s16a",
970 from_wkt<G>("SEGMENT(-50 0,50 0)"),
971 -50, 0, 50, 0);
972
973 // segment that lies on the equator and touches antimeridian
974 tester::apply("s16b",
975 from_wkt<G>("SEGMENT(50 0,180 0)"),
976 50, 0, 180, 0);
977
978 // segment that lies on the equator and crosses antimeridian
979 tester::apply("s16c",
980 from_wkt<G>("SEGMENT(-170 0,160 0)"),
981 160, 0, 190, 0);
982
983 tester::apply("s17",
984 from_wkt<G>("SEGMENT(140 10, -140 80)"),
985 140, 10, 220, 80);
986
987 tester::apply("s17-r",
988 from_wkt<G>("SEGMENT(-140 80, 140 10)"),
989 140, 10, 220, 80);
990
991 tester::apply("s18",
992 from_wkt<G>("SEGMENT(20 10, 100 80)"),
993 20, 10, 100, 80);
994
995 tester::apply("s18-r",
996 from_wkt<G>("SEGMENT(100 80, 20 10)"),
997 20, 10, 100, 80);
998
999 // segment connecting the north and south pole
1000 //
1001 // this should be forbidden actually, as it is not well-defined
1002 // with this test we demonstrate that the algorithm still returns
1003 // something meaningful
1004 tester::apply("s99",
1005 from_wkt<G>("SEGMENT(10 90,20 -90)"),
1006 0, -90, 0, 90);
1007
1008 // https://svn.boost.org/trac/boost/ticket/12106
1009 tester::apply("s100_ticket_12106",
1010 G(P(11.488323611111111, 53.687086666666673), P(11.488324166666667, 53.687086666666673)),
1011 11.488323611111111, 53.687086666666673, 11.488324166666667, 53.687086666666673);
1012
1013 double const heps = eps / 2;
1014
1015 tester::apply("s101",
1016 G(P(1, 1), P(1-heps, 1-heps)),
1017 1-heps, 1-heps, 1, 1);
1018 tester::apply("s102",
1019 G(P(1, 1), P(1, 1-heps)),
1020 1, 1-heps, 1, 1);
1021 tester::apply("s103",
1022 G(P(1, 1), P(1-heps, 1)),
1023 1-heps, 1, 1, 1);
1024 tester::apply("s104",
1025 G(P(2, 1), P(1, 1-heps)),
1026 1, 1-heps, 2, rng(1.0000383271568751, 1.0000383271569036));
1027 tester::apply("s105",
1028 G(P(1, 2), P(1-heps, 1)),
1029 1-heps, 1, 1, 2);
1030}
1031
1032BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_thomas )
1033{
1034
1035 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
1036 typedef bg::model::point<double, 2, coordinate_system_type> P;
1037 typedef bg::model::segment<P> G;
1038 typedef bg::model::box<P> B;
1039 typedef test_envelope_on_sphere_or_spheroid
1040 <
1041 G, B,
1042 bg::tag<G>::type,
1043 test_reverse_geometry<G>::value,
1044 bg::strategy::thomas
1045 > tester;
1046
1047 tester::apply("s01",
1048 from_wkt<G>("SEGMENT(10 10,40 40)"),
1049 10, 10, 40, 40);
1050
1051 tester::apply("s02",
1052 from_wkt<G>("SEGMENT(10 10,40 10)"),
1053 10, 10, 40, 10.347587605817942);
1054
1055 tester::apply("s02a",
1056 from_wkt<G>("SEGMENT(40 10,10 10)"),
1057 10, 10, 40, 10.347587605817942);
1058
1059 tester::apply("s03",
1060 from_wkt<G>("SEGMENT(160 10,-170 10)"),
1061 160, 10, 190, 10.347587605817942);
1062
1063 tester::apply("s03a",
1064 from_wkt<G>("SEGMENT(-170 10,160 10)"),
1065 160, 10, 190, 10.347587605817942);
1066
1067 tester::apply("s03b",
1068 from_wkt<G>("SEGMENT(-170 -10,160 -10)"),
1069 160, -10.347587605817942, 190, -10);
1070
1071 tester::apply("s04",
1072 from_wkt<G>("SEGMENT(-40 45,140 60)"),
1073 -40, 45, 140, 90);
1074
1075 tester::apply("s04a",
1076 from_wkt<G>("SEGMENT(-40 45,140 25)"),
1077 -40, 25, 140, 90);
1078
1079 // segment ending at the north pole
1080 tester::apply("s05",
1081 from_wkt<G>("SEGMENT(40 45,80 90)"),
1082 40, 45, 40, 90);
1083
1084 // segment starting at the north pole
1085 tester::apply("s05a",
1086 from_wkt<G>("SEGMENT(80 90,40 45)"),
1087 40, 45, 40, 90);
1088
1089 // segment ending at the north pole
1090 tester::apply("s06",
1091 from_wkt<G>("SEGMENT(-40 45,80 90)"),
1092 -40, 45, -40, 90);
1093
1094 // segment starting at the north pole
1095 tester::apply("s06a",
1096 from_wkt<G>("SEGMENT(70 90,-40 45)"),
1097 -40, 45, -40, 90);
1098
1099 // segment ending at the north pole
1100 tester::apply("s07",
1101 from_wkt<G>("SEGMENT(40 -45,80 90)"),
1102 40, -45, 40, 90);
1103
1104 // segment passing through the south pole
1105 tester::apply("s08",
1106 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
1107 -170, -90, 10, -30);
1108
1109 tester::apply("s09",
1110 from_wkt<G>("SEGMENT(1 -45,179 30)"),
1111 1, rng(-85.392785243526134, -85.392785243525253), 179, 30);
1112
1113 tester::apply("s09a",
1114 from_wkt<G>("SEGMENT(2 -45,181 30)"),
1115 2, rng(-87.689300911353811, -87.689300911353371), 181, 30);
1116
1117 // very long segment
1118 tester::apply("s10",
1119 from_wkt<G>("SEGMENT(0 -45,181 30)"),
1120 -179, rng(-87.689300911353797, -87.689300911353385), 0, 30);
1121
1122 tester::apply("s11",
1123 from_wkt<G>("SEGMENT(260 30,20 45)"),
1124 -100, 30, 20, rng(57.990810958016482, 57.990810958016965));
1125
1126 tester::apply("s11a",
1127 from_wkt<G>("SEGMENT(260 45,20 30)"),
1128 -100, 30, 20, rng(57.990810958016453, 57.990810958016965));
1129
1130 // segment degenerating to the north pole
1131 tester::apply("s12",
1132 from_wkt<G>("SEGMENT(10 90,20 90)"),
1133 0, 90, 0, 90);
1134
1135 // segment degenerating to the south pole
1136 tester::apply("s13",
1137 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
1138 0, -90, 0, -90);
1139
1140 tester::apply("s14",
1141 from_wkt<G>("SEGMENT(20 20,10 30)"),
1142 10, 20, 20, 30);//48.87458730907602);
1143
1144 tester::apply("s15",
1145 from_wkt<G>("SEGMENT(50 45,185 45)"),
1146 50, 45, 185, rng(69.098479073902851, 69.098479073903178));
1147
1148 // segment that lies on the equator
1149 tester::apply("s16",
1150 from_wkt<G>("SEGMENT(0 0,50 0)"),
1151 0, 0, 50, 0);
1152
1153 // segment that lies on the equator
1154 tester::apply("s16a",
1155 from_wkt<G>("SEGMENT(-50 0,50 0)"),
1156 -50, 0, 50, 0);
1157
1158 // segment that lies on the equator and touches antimeridian
1159 tester::apply("s16b",
1160 from_wkt<G>("SEGMENT(50 0,180 0)"),
1161 50, 0, 180, 0);
1162
1163 // segment that lies on the equator and crosses antimeridian
1164 tester::apply("s16c",
1165 from_wkt<G>("SEGMENT(-170 0,160 0)"),
1166 160, 0, 190, 0);
1167
1168 tester::apply("s17",
1169 from_wkt<G>("SEGMENT(140 10, -140 80)"),
1170 140, 10, 220, 80);
1171
1172 tester::apply("s17-r",
1173 from_wkt<G>("SEGMENT(-140 80, 140 10)"),
1174 140, 10, 220, 80);
1175
1176 tester::apply("s18",
1177 from_wkt<G>("SEGMENT(20 10, 100 80)"),
1178 20, 10, 100, 80);
1179
1180 tester::apply("s18-r",
1181 from_wkt<G>("SEGMENT(100 80, 20 10)"),
1182 20, 10, 100, 80);
1183
1184}
1185
1186BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_andoyer )
1187{
1188
1189 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
1190 typedef bg::model::point<double, 2, coordinate_system_type> P;
1191 typedef bg::model::segment<P> G;
1192 typedef bg::model::box<P> B;
1193 typedef test_envelope_on_sphere_or_spheroid
1194 <
1195 G, B,
1196 bg::tag<G>::type,
1197 test_reverse_geometry<G>::value,
1198 bg::strategy::andoyer
1199 > tester;
1200
1201 tester::apply("s01",
1202 from_wkt<G>("SEGMENT(10 10,40 40)"),
1203 10, 10, 40, 40);
1204
1205 tester::apply("s02",
1206 from_wkt<G>("SEGMENT(10 10,40 10)"),
1207 10, 10, 40, 10.34758709960203);
1208
1209 tester::apply("s02a",
1210 from_wkt<G>("SEGMENT(40 10,10 10)"),
1211 10, 10, 40, 10.34758709960203);
1212
1213 tester::apply("s03",
1214 from_wkt<G>("SEGMENT(160 10,-170 10)"),
1215 160, 10, 190, 10.34758709960203);
1216
1217 tester::apply("s03a",
1218 from_wkt<G>("SEGMENT(-170 10,160 10)"),
1219 160, 10, 190, 10.34758709960203);
1220
1221 tester::apply("s03b",
1222 from_wkt<G>("SEGMENT(-170 -10,160 -10)"),
1223 160, -10.34758709960203, 190, -10);
1224
1225 tester::apply("s04",
1226 from_wkt<G>("SEGMENT(-40 45,140 60)"),
1227 -40, 45, 140, 90);
1228
1229 tester::apply("s04a",
1230 from_wkt<G>("SEGMENT(-40 45,140 25)"),
1231 -40, 25, 140, 90);
1232
1233 // segment ending at the north pole
1234 tester::apply("s05",
1235 from_wkt<G>("SEGMENT(40 45,80 90)"),
1236 40, 45, 40, 90);
1237
1238 // segment starting at the north pole
1239 tester::apply("s05a",
1240 from_wkt<G>("SEGMENT(80 90,40 45)"),
1241 40, 45, 40, 90);
1242
1243 // segment ending at the north pole
1244 tester::apply("s06",
1245 from_wkt<G>("SEGMENT(-40 45,80 90)"),
1246 -40, 45, -40, 90);
1247
1248 // segment starting at the north pole
1249 tester::apply("s06a",
1250 from_wkt<G>("SEGMENT(70 90,-40 45)"),
1251 -40, 45, -40, 90);
1252
1253 // segment ending at the north pole
1254 tester::apply("s07",
1255 from_wkt<G>("SEGMENT(40 -45,80 90)"),
1256 40, -45, 40, 90);
1257
1258 // segment passing through the south pole
1259 tester::apply("s08",
1260 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
1261 -170, -90, 10, -30);
1262
1263 tester::apply("s09",
1264 from_wkt<G>("SEGMENT(1 -45,179 30)"),
1265 1, rng(-85.394745211091248, -85.394745211090353), 179, 30);
1266
1267 tester::apply("s09a",
1268 from_wkt<G>("SEGMENT(2 -45,181 30)"),
1269 2, rng(-87.690317839849726, -87.690317839849271), 181, 30);
1270
1271 // very long segment
1272 tester::apply("s10",
1273 from_wkt<G>("SEGMENT(0 -45,181 30)"),
1274 -179, rng(-87.69031783984974, -87.690317839849271), 0, 30);
1275
1276 tester::apply("s11",
1277 from_wkt<G>("SEGMENT(260 30,20 45)"),
1278 -100, 30, 20, rng(57.990742552279649, 57.990742552280153));
1279
1280 tester::apply("s11a",
1281 from_wkt<G>("SEGMENT(260 45,20 30)"),
1282 -100, 30, 20, rng(57.99074255227962, 57.990742552280118));
1283
1284 // segment degenerating to the north pole
1285 tester::apply("s12",
1286 from_wkt<G>("SEGMENT(10 90,20 90)"),
1287 0, 90, 0, 90);
1288
1289 // segment degenerating to the south pole
1290 tester::apply("s13",
1291 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
1292 0, -90, 0, -90);
1293
1294 tester::apply("s14",
1295 from_wkt<G>("SEGMENT(20 20,10 30)"),
1296 10, 20, 20, 30);//48.87458730907602);
1297
1298 tester::apply("s15",
1299 from_wkt<G>("SEGMENT(50 45,185 45)"),
1300 50, 45, 185, rng(69.098446893408124, 69.09844689340845));
1301
1302 // segment that lies on the equator
1303 tester::apply("s16",
1304 from_wkt<G>("SEGMENT(0 0,50 0)"),
1305 0, 0, 50, 0);
1306
1307 // segment that lies on the equator
1308 tester::apply("s16a",
1309 from_wkt<G>("SEGMENT(-50 0,50 0)"),
1310 -50, 0, 50, 0);
1311
1312 // segment that lies on the equator and touches antimeridian
1313 tester::apply("s16b",
1314 from_wkt<G>("SEGMENT(50 0,180 0)"),
1315 50, 0, 180, 0);
1316
1317 // segment that lies on the equator and crosses antimeridian
1318 tester::apply("s16c",
1319 from_wkt<G>("SEGMENT(-170 0,160 0)"),
1320 160, 0, 190, 0);
1321
1322 tester::apply("s17",
1323 from_wkt<G>("SEGMENT(140 10, -140 80)"),
1324 140, 10, 220, 80);
1325
1326 tester::apply("s17-r",
1327 from_wkt<G>("SEGMENT(-140 80, 140 10)"),
1328 140, 10, 220, 80);
1329
1330 tester::apply("s18",
1331 from_wkt<G>("SEGMENT(20 10, 100 80)"),
1332 20, 10, 100, 80);
1333
1334 tester::apply("s18-r",
1335 from_wkt<G>("SEGMENT(100 80, 20 10)"),
1336 20, 10, 100, 80);
1337
1338 // segments intersecting pole
1339 tester::apply("s19",
1340 from_wkt<G>("SEGMENT(0 0, 180 0)"),
1341 0, 0, 180, 90);
1342 tester::apply("s20",
1343 from_wkt<G>("SEGMENT(0 0, -180 0)"),
1344 0, 0, 180, 90);
1345 tester::apply("s21",
1346 from_wkt<G>("SEGMENT(0 1, 180 1)"),
1347 0, 1, 180, 90,
1348 std::numeric_limits<double>::epsilon() * 10);
1349 tester::apply("s22",
1350 from_wkt<G>("SEGMENT(0 -1, 180 -1)"),
1351 0, -90, 180, -1,
1352 std::numeric_limits<double>::epsilon() * 10);
1353
1354}
1355
1356BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_vincenty )
1357{
1358
1359 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
1360 typedef bg::model::point<double, 2, coordinate_system_type> P;
1361 typedef bg::model::segment<P> G;
1362 typedef bg::model::box<P> B;
1363 typedef test_envelope_on_sphere_or_spheroid
1364 <
1365 G, B,
1366 bg::tag<G>::type,
1367 test_reverse_geometry<G>::value,
1368 bg::strategy::vincenty
1369 > tester;
1370
1371 tester::apply("s01",
1372 from_wkt<G>("SEGMENT(10 10,40 40)"),
1373 10, 10, 40, 40);
1374
1375 tester::apply("s02",
1376 from_wkt<G>("SEGMENT(10 10,40 10)"),
1377 10, 10, 40, rng(10.347587628821937, 10.347587628821941));
1378
1379 tester::apply("s02a",
1380 from_wkt<G>("SEGMENT(40 10,10 10)"),
1381 10, 10, 40, rng(10.347587628821937, 10.347587628821941));
1382
1383 tester::apply("s03",
1384 from_wkt<G>("SEGMENT(160 10,-170 10)"),
1385 160, 10, 190, rng(10.347587628821937, 10.347587628821941));
1386
1387 tester::apply("s03a",
1388 from_wkt<G>("SEGMENT(-170 10,160 10)"),
1389 160, 10, 190, rng(10.347587628821937, 10.347587628821941));
1390
1391 tester::apply("s03b",
1392 from_wkt<G>("SEGMENT(-170 -10,160 -10)"),
1393 160, rng(-10.347587628821941, -10.347587628821937), 190, -10);
1394
1395 tester::apply("s04",
1396 from_wkt<G>("SEGMENT(-40 45,140 60)"),
1397 -40, 45, 140, 90);
1398
1399 tester::apply("s04a",
1400 from_wkt<G>("SEGMENT(-40 45,140 25)"),
1401 -40, 25, 140, 90);
1402
1403 // segment ending at the north pole
1404 tester::apply("s05",
1405 from_wkt<G>("SEGMENT(40 45,80 90)"),
1406 40, 45, 40, 90);
1407
1408 // segment starting at the north pole
1409 tester::apply("s05a",
1410 from_wkt<G>("SEGMENT(80 90,40 45)"),
1411 40, 45, 40, 90);
1412
1413 // segment ending at the north pole
1414 tester::apply("s06",
1415 from_wkt<G>("SEGMENT(-40 45,80 90)"),
1416 -40, 45, -40, 90);
1417
1418 // segment starting at the north pole
1419 tester::apply("s06a",
1420 from_wkt<G>("SEGMENT(70 90,-40 45)"),
1421 -40, 45, -40, 90);
1422
1423 // segment ending at the north pole
1424 tester::apply("s07",
1425 from_wkt<G>("SEGMENT(40 -45,80 90)"),
1426 40, -45, 40, 90);
1427
1428 // segment passing through the south pole
1429 tester::apply("s08",
1430 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
1431 -170, -90, 10, -30);
1432
1433 tester::apply("s09",
1434 from_wkt<G>("SEGMENT(1 -45,179 30)"),
1435 1, rng(-85.392840929577218, -85.392840929576352), 179, 30);
1436
1437 tester::apply("s09a",
1438 from_wkt<G>("SEGMENT(2 -45,181 30)"),
1439 2, rng(-87.689330275867817, -87.689330275867405), 181, 30);
1440
1441 // very long segment
1442 tester::apply("s10",
1443 from_wkt<G>("SEGMENT(0 -45,181 30)"),
1444 -179, rng(-87.689330275867832, -87.689330275867405), 0, 30);
1445
1446 tester::apply("s11",
1447 from_wkt<G>("SEGMENT(260 30,20 45)"),
1448 -100, 30, 20, rng(57.990810647056549, 57.990810647057032));
1449
1450 tester::apply("s11a",
1451 from_wkt<G>("SEGMENT(260 45,20 30)"),
1452 -100, 30, 20, rng(57.990810647056541, 57.990810647057032));
1453
1454 // segment degenerating to the north pole
1455 tester::apply("s12",
1456 from_wkt<G>("SEGMENT(10 90,20 90)"),
1457 0, 90, 0, 90);
1458
1459 // segment degenerating to the south pole
1460 tester::apply("s13",
1461 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
1462 0, -90, 0, -90);
1463
1464 tester::apply("s14",
1465 from_wkt<G>("SEGMENT(20 20,10 30)"),
1466 10, 20, 20, 30);//48.87458730907602);
1467
1468 tester::apply("s15",
1469 from_wkt<G>("SEGMENT(50 45,185 45)"),
1470 50, 45, 185, rng(69.098479136978156, 69.098479136978497));
1471
1472 // segment that lies on the equator
1473 tester::apply("s16",
1474 from_wkt<G>("SEGMENT(0 0,50 0)"),
1475 0, 0, 50, 0);
1476
1477 // segment that lies on the equator
1478 tester::apply("s16a",
1479 from_wkt<G>("SEGMENT(-50 0,50 0)"),
1480 -50, 0, 50, 0);
1481
1482 // segment that lies on the equator and touches antimeridian
1483 tester::apply("s16b",
1484 from_wkt<G>("SEGMENT(50 0,180 0)"),
1485 50, 0, 180, 0);
1486
1487 // segment that lies on the equator and crosses antimeridian
1488 tester::apply("s16c",
1489 from_wkt<G>("SEGMENT(-170 0,160 0)"),
1490 160, 0, 190, 0);
1491
1492 tester::apply("s17",
1493 from_wkt<G>("SEGMENT(140 10, -140 80)"),
1494 140, 10, 220, 80);
1495
1496 tester::apply("s17-r",
1497 from_wkt<G>("SEGMENT(-140 80, 140 10)"),
1498 140, 10, 220, 80);
1499
1500 tester::apply("s18",
1501 from_wkt<G>("SEGMENT(20 10, 100 80)"),
1502 20, 10, 100, 80);
1503
1504 tester::apply("s18-r",
1505 from_wkt<G>("SEGMENT(100 80, 20 10)"),
1506 20, 10, 100, 80);
1507
1508}
1509
1510BOOST_AUTO_TEST_CASE( envelope_segment_sphere_with_height )
1511{
1512 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
1513 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
1514 typedef bg::model::segment<point_type> G;
1515 typedef bg::model::box<point_type> B;
1516 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
1517
1518 tester::apply("sh01",
1519 from_wkt<G>("SEGMENT(10 10 567,40 40 1356)"),
1520 10, 10, 567, 40, 40, 1356);
1521
1522 tester::apply("sh02",
1523 from_wkt<G>("SEGMENT(10 10 1356,40 40 567)"),
1524 10, 10, 567, 40, 40, 1356);
1525}
7c673cae 1526
b32b8144 1527BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_height )
7c673cae 1528{
b32b8144 1529 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
7c673cae
FG
1530 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
1531 typedef bg::model::segment<point_type> G;
1532 typedef bg::model::box<point_type> B;
b32b8144 1533 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1534
1535 tester::apply("sh01",
1536 from_wkt<G>("SEGMENT(10 10 567,40 40 1356)"),
1537 10, 10, 567, 40, 40, 1356);
1538
1539 tester::apply("sh02",
1540 from_wkt<G>("SEGMENT(10 10 1356,40 40 567)"),
1541 10, 10, 567, 40, 40, 1356);
1542}
1543
7c673cae
FG
1544template <typename CoordinateSystem>
1545void test_envelope_multipoint()
1546{
1547 typedef bg::model::point<double, 2, CoordinateSystem> P;
1548 typedef bg::model::multi_point<P> G;
1549 typedef bg::model::box<P> B;
b32b8144 1550 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1551
1552 // empty multipoint
1553 test_empty_geometry<CoordinateSystem, G>("mp00", "MULTIPOINT()");
1554
1555 tester::apply("mp01",
1556 from_wkt<G>("MULTIPOINT(0 0,10 10)"),
1557 0, 0, 10, 10);
1558
1559 tester::apply("mp02",
1560 from_wkt<G>("MULTIPOINT(0 10,10 0)"),
1561 0, 0, 10, 10);
1562
1563 tester::apply("mp03",
1564 from_wkt<G>("MULTIPOINT(-10 20,0 10,10 0)"),
1565 -10, 0, 10, 20);
1566
1567 tester::apply("mp04",
1568 from_wkt<G>("MULTIPOINT(-10 20,0 10,10 -15)"),
1569 -10, -15, 10, 20);
1570
1571 tester::apply("mp05",
1572 from_wkt<G>("MULTIPOINT(-85 10,85 -20)"),
1573 -85, -20, 85, 10);
1574
1575 tester::apply("mp06",
1576 from_wkt<G>("MULTIPOINT(-95 10,85 -20)"),
1577 -95, -20, 85, 10);
1578
1579 tester::apply("mp07",
1580 from_wkt<G>("MULTIPOINT(-96 10,85 -20)"),
1581 85, -20, -96+360, 10);
1582
1583 tester::apply("mp08",
1584 from_wkt<G>("MULTIPOINT(175 15,-175 -20)"),
1585 175, -20, -175+360, 15);
1586
1587 tester::apply("mp09",
1588 from_wkt<G>("MULTIPOINT(170 15,170 20,-175 10,-90 10,10 10)"),
1589 170, 10, 10+360, 20);
1590
1591 // this should fail
1592 tester::apply("mp09a",
1593 from_wkt<G>("MULTIPOINT(10 10,170 15,170 20,-175 10,-90 10)"),
1594 170, 10, 10+360, 20);
1595
1596
1597 tester::apply("mp10",
1598 from_wkt<G>("MULTIPOINT(10 10,20 90,30 -90)"),
1599 10, -90, 10, 90);
1600
1601 // this should fail
1602 tester::apply("mp11",
1603 from_wkt<G>("MULTIPOINT(179 90,-179 -90,10 10)"),
1604 10, -90, 10, 90);
1605
1606 tester::apply("mp11a",
1607 from_wkt<G>("MULTIPOINT(10 10,179 90,-179 -90)"),
1608 10, -90, 10, 90);
1609
1610 // this should fail
1611 tester::apply("mp11b",
1612 from_wkt<G>("MULTIPOINT(179 90,-179 -90,-90 0)"),
1613 -90, -90, -90, 90);
1614
1615 tester::apply("mp11c",
1616 from_wkt<G>("MULTIPOINT(-90 0,179 90,-179 -90,-90 0)"),
1617 -90, -90, -90, 90);
1618
1619 tester::apply("mp12",
1620 from_wkt<G>("MULTIPOINT(170 -30,175 60,-178 10)"),
1621 170, -30, -178+360, 60);
1622
1623 tester::apply("mp13",
1624 from_wkt<G>("MULTIPOINT(-170 -30,-175 40,178 50)"),
1625 178, -30, -170+360, 50);
1626
1627 tester::apply("mp13a",
1628 from_wkt<G>("MULTIPOINT(-170 -30,178 50)"),
1629 178, -30, -170+360, 50);
1630
1631 tester::apply("mp13b",
1632 from_wkt<G>("MULTIPOINT(-170 -30,178 50,-175 40)"),
1633 178, -30, -170+360, 50);
1634
1635 tester::apply("mp15",
1636 from_wkt<G>("MULTIPOINT(10 -20)"),
1637 10, -20, 10, -20);
1638
1639 tester::apply("mp16",
1640 from_wkt<G>("MULTIPOINT(0 90,10 90)"),
1641 0, 90, 0, 90);
1642
1643 tester::apply("mp17",
1644 from_wkt<G>("MULTIPOINT(179 80,-179 -80,10 10)"),
1645 10, -80, -179+360, 80);
1646
1647 tester::apply("mp17a",
1648 from_wkt<G>("MULTIPOINT(10 10,179 80,-179 -80)"),
1649 10, -80, -179+360, 80);
1650
1651 tester::apply("mp17b",
1652 from_wkt<G>("MULTIPOINT(179 80,-179 -80,-90 0)"),
1653 179, -80, -90+360, 80);
1654
1655 tester::apply("mp17c",
1656 from_wkt<G>("MULTIPOINT(-90 0,179 80,-179 -80,-90 0)"),
1657 179, -80, -90+360, 80);
1658
1659 tester::apply("mp18",
1660 from_wkt<G>("MULTIPOINT(-170 45,20 25,40 40)"),
1661 20, 25, 190, 45);
1662
1663#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1664 tester::apply("mp18a",
1665 from_wkt<G>("MULTIPOINT(10 135,20 25,40 40)"),
1666 20, 25, 190, 45);
1667#endif
1668
1669 tester::apply("mp19",
1670 from_wkt<G>("MULTIPOINT(350 45,20 25,40 40)"),
1671 -10, 25, 40, 45);
1672
1673#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1674 tester::apply("mp19a",
1675 from_wkt<G>("MULTIPOINT(170 135,20 25,40 40)"),
1676 -10, 25, 40, 45);
1677#endif
1678
1679 double eps = std::numeric_limits<double>::epsilon();
1680 double heps = eps / 2;
1681 {
1682 G mp;
1683 mp.push_back(P(1, 1));
1684 mp.push_back(P(1-heps, 1-heps));
1685 tester::apply("mp20", mp, 1-heps, 1-heps, 1, 1);
1686 }
1687}
1688
1689BOOST_AUTO_TEST_CASE( envelope_multipoint )
1690{
1691 test_envelope_multipoint<bg::cs::spherical_equatorial<bg::degree> >();
1692 test_envelope_multipoint<bg::cs::geographic<bg::degree> >();
1693}
1694
1695
1696template <typename CoordinateSystem>
1697void test_envelope_multipoint_with_height()
1698{
1699 typedef bg::model::point<double, 3, CoordinateSystem> point_type;
1700 typedef bg::model::multi_point<point_type> G;
1701 typedef bg::model::box<point_type> B;
b32b8144 1702 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1703
1704 // empty multipoint
1705 test_empty_geometry<CoordinateSystem, G>("mph00", "MULTIPOINT()");
1706
1707 tester::apply("mph01",
1708 from_wkt<G>("MULTIPOINT(0 0 567,10 10 1456)"),
1709 0, 0, 567, 10, 10, 1456);
1710
1711 tester::apply("mph02",
1712 from_wkt<G>("MULTIPOINT(0 0 567,10 10 1456,20 90 967)"),
1713 0, 0, 567, 10, 90, 1456);
1714}
1715
1716BOOST_AUTO_TEST_CASE( envelope_multipoint_with_height )
1717{
1718 test_envelope_multipoint_with_height
1719 <
1720 bg::cs::spherical_equatorial<bg::degree>
1721 >();
1722 test_envelope_multipoint_with_height<bg::cs::geographic<bg::degree> >();
1723}
1724
1725
1726template <typename CoordinateSystem>
1727void test_envelope_box()
1728{
b32b8144 1729 typedef bg::model::point<double, 2, CoordinateSystem> P;
7c673cae
FG
1730 typedef bg::model::box<P> G;
1731 typedef bg::model::box<P> B;
b32b8144 1732 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1733
1734 tester::apply("b01",
1735 from_wkt<G>("BOX(10 10,20 20)"),
1736 10, 10, 20, 20);
1737
1738#ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1739 tester::apply("b02",
1740 from_wkt<G>("BOX(10 370,20 20)"),
1741 10, 10, 20, 20);
1742#endif
1743
1744 // box crosses anti-meridian
1745 tester::apply("b02a",
1746 from_wkt<G>("BOX(170 10,-170 20)"),
1747 170, 10, 190, 20);
1748
1749 tester::apply("b03",
1750 from_wkt<G>("BOX(-170 10,170 20)"),
1751 -170, 10, 170, 20);
1752
1753 tester::apply("b04",
1754 from_wkt<G>("BOX(10 10,350 20)"),
1755 10, 10, 350, 20);
1756
1757 tester::apply("b04a",
1758 from_wkt<G>("BOX(10 10,-10 20)"),
1759 10, 10, 350, 20);
1760
1761 // box is a band
1762 tester::apply("b05",
1763 from_wkt<G>("BOX(0 10,360 20)"),
1764 -180, 10, 180, 20);
1765
1766 tester::apply("b05a",
1767 from_wkt<G>("BOX(0 10,0 20)"),
1768 0, 10, 0, 20);
1769
1770 // box is almost a band
1771 tester::apply("b06",
1772 from_wkt<G>("BOX(10 10,5 20)"),
1773 10, 10, 365, 20);
1774
1775 // initial box is a band that crosses itself
1776 tester::apply("b07",
1777 from_wkt<G>("BOX(0 10,540 20)"),
1778 -180, 10, 180, 20);
1779
1780 // initial box is a band that crosses itself
1781 tester::apply("b08",
1782 from_wkt<G>("BOX(0 10,720 20)"),
1783 -180, 10, 180, 20);
1784
1785 tester::apply("b09",
1786 from_wkt<G>("BOX(10 10,10 10)"),
1787 10, 10, 10, 10);
1788
1789 tester::apply("b09a",
1790 from_wkt<G>("BOX(370 10,370 10)"),
1791 10, 10, 10, 10);
1792
1793 // box contains north and south pole
1794 tester::apply("b10",
1795 from_wkt<G>("BOX(0 -90,0 90)"),
1796 0, -90, 0, 90);
1797
1798 // box contains north and south pole
1799 tester::apply("b10a",
1800 from_wkt<G>("BOX(10 -90,10 90)"),
1801 10, -90, 10, 90);
1802
1803 // box contains north and south pole
1804 tester::apply("b10b",
1805 from_wkt<G>("BOX(0 -90,10 90)"),
1806 0, -90, 10, 90);
1807
1808 // box contains north and south pole
1809 tester::apply("b11",
1810 from_wkt<G>("BOX(0 -90,180 90)"),
1811 0, -90, 180, 90);
1812
1813 // box contains north and south pole
1814 tester::apply("b11a",
1815 from_wkt<G>("BOX(10 -90,190 90)"),
1816 10, -90, 190, 90);
1817
1818 // box contains north and south pole
1819 tester::apply("b11b",
1820 from_wkt<G>("BOX(10 -90,110 90)"),
1821 10, -90, 110, 90);
1822
1823 // box contains north and south pole and is a band
1824 // (box covers the entire spheroid)
1825 tester::apply("b12",
1826 from_wkt<G>("BOX(0 -90,360 90)"),
1827 -180, -90, 180, 90);
1828
1829 // box contains north and south pole and is a band
1830 // (box covers the entire spheroid)
1831 tester::apply("b12a",
1832 from_wkt<G>("BOX(10 -90,370 90)"),
1833 -180, -90, 180, 90);
1834
1835 // box contains north and south pole and is a band
1836 // (box covers the entire spheroid)
1837 tester::apply("b12b",
1838 from_wkt<G>("BOX(-175 -90,185 90)"),
1839 -180, -90, 180, 90);
1840
1841 // box contains north and south pole and is a band
1842 // (box covers the entire spheroid)
1843 tester::apply("b12c",
1844 from_wkt<G>("BOX(-175 -90,185 90)"),
1845 -180, -90, 180, 90);
1846
1847 // box contains north and south pole and is a band and is self-intersecting
1848 // (box covers the entire spheroid)
1849 tester::apply("b12d",
1850 from_wkt<G>("BOX(-175 -90,186 90)"),
1851 -180, -90, 180, 90);
1852
1853 // box contains north and south pole and is a band and is self-intersecting
1854 // (box covers the entire spheroid)
1855 tester::apply("b12e",
1856 from_wkt<G>("BOX(0 -90,540 90)"),
1857 -180, -90, 180, 90);
1858
1859 // box contains north and south pole and is a band and is self-intersecting
1860 // (box covers the entire spheroid)
1861 tester::apply("b12f",
1862 from_wkt<G>("BOX(10 -90,540 90)"),
1863 -180, -90, 180, 90);
1864
1865 // box is a band
1866 tester::apply("b13",
1867 from_wkt<G>("BOX(180 -10,-180 10)"),
1868 -180, -10, 180, 10);
1869
1870 // box contains north and south pole and is a band
1871 // (box covers the entire spheroid)
1872 tester::apply("b13a",
1873 from_wkt<G>("BOX(180 -90,-180 90)"),
1874 -180, -90, 180, 90);
1875
1876 tester::apply("b14",
1877 from_wkt<G>("BOX(0 10,30 90)"),
1878 0, 10, 30, 90);
1879
1880 tester::apply("b15",
1881 from_wkt<G>("BOX(179 10,178 70)"),
1882 179, 10, 538, 70);
1883
1884 // box contains north pole
1885 tester::apply("b16",
1886 from_wkt<G>("BOX(10 40,20 90)"),
1887 10, 40, 20, 90);
1888
1889 tester::apply("b16a",
1890 from_wkt<G>("BOX(170 40,-170 90)"),
1891 170, 40, 190, 90);
1892
1893 // box contains south pole
1894 tester::apply("b17",
1895 from_wkt<G>("BOX(10 -90,20 40)"),
1896 10, -90, 20, 40);
1897
1898 tester::apply("b17a",
1899 from_wkt<G>("BOX(150 -90,-150 40)"),
1900 150, -90, 210, 40);
1901
1902 // box degenerates to the north pole
1903 tester::apply("b98",
1904 from_wkt<G>("BOX(10 90,20 90)"),
1905 0, 90, 0, 90);
1906
1907 // box degenerates to the south pole
1908 tester::apply("b99",
1909 from_wkt<G>("BOX(10 -90,20 -90)"),
1910 0, -90, 0, -90);
1911
1912 double eps = std::numeric_limits<double>::epsilon();
1913 double heps = eps / 2;
1914
1915 tester::apply("b100", G(P(1-heps, 1-heps), P(1, 1)), 1-heps, 1-heps, 1, 1);
1916}
1917
b32b8144
FG
1918template <typename CoordinateSystem>
1919void test_envelope_box_polar()
1920{
1921 typedef bg::model::point<double, 2, CoordinateSystem> P;
1922 typedef bg::model::box<P> G;
1923 typedef bg::model::box<P> B;
1924 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
1925
1926 tester::apply("b01",
1927 from_wkt<G>("BOX(10 10,20 20)"),
1928 10, 10, 20, 20);
1929
1930 tester::apply("b02a",
1931 from_wkt<G>("BOX(170 10,-170 20)"),
1932 170, 10, 190, 20);
1933
1934 tester::apply("b10b",
1935 from_wkt<G>("BOX(0 0,10 180)"),
1936 0, 0, 10, 180);
1937
1938 tester::apply("b16a",
1939 from_wkt<G>("BOX(170 40,-170 180)"),
1940 170, 40, 190, 180);
1941}
1942
7c673cae
FG
1943BOOST_AUTO_TEST_CASE( envelope_box )
1944{
1945 test_envelope_box<bg::cs::spherical_equatorial<bg::degree> >();
1946 test_envelope_box<bg::cs::geographic<bg::degree> >();
b32b8144 1947 test_envelope_box_polar<bg::cs::spherical<bg::degree> >();
7c673cae
FG
1948}
1949
1950
1951template <typename CoordinateSystem>
1952void test_envelope_box_with_height()
1953{
1954 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
1955 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
1956 typedef bg::model::box<point_type> G;
1957 typedef bg::model::box<point_type> B;
b32b8144 1958 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1959
1960 tester::apply("bh01",
1961 from_wkt<G>("BOX(10 10 567,20 20 2834)"),
1962 10, 10, 567, 20, 20, 2834);
1963
1964 tester::apply("bh02",
1965 from_wkt<G>("BOX(10 10 567,20 20 567)"),
1966 10, 10, 567, 20, 20, 567);
1967
1968 tester::apply("bh03",
1969 from_wkt<G>("BOX(0 10 567,170 90 1567)"),
1970 0, 10, 567, 170, 90, 1567);
1971}
1972
1973BOOST_AUTO_TEST_CASE( envelope_box_with_height )
1974{
1975 test_envelope_box_with_height<bg::cs::spherical_equatorial<bg::degree> >();
1976 test_envelope_box_with_height<bg::cs::geographic<bg::degree> >();
1977}
1978
1979
b32b8144 1980BOOST_AUTO_TEST_CASE( envelope_sphere_linestring )
7c673cae
FG
1981{
1982 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
1983 typedef bg::model::point<double, 2, coordinate_system_type> P;
1984 typedef bg::model::linestring<P> G;
1985 typedef bg::model::box<P> B;
b32b8144 1986 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
1987
1988 // empty linestring
1989 test_empty_geometry<coordinate_system_type, G>("l00", "LINESTRING()");
1990
1991 tester::apply("l01",
1992 from_wkt<G>("LINESTRING(10 15)"),
1993 10, 15, 10, 15);
1994
1995 tester::apply("l01a",
1996 from_wkt<G>("LINESTRING(370 15)"),
1997 10, 15, 10, 15);
1998
1999 tester::apply("l01b",
2000 from_wkt<G>("LINESTRING(370 90)"),
2001 0, 90, 0, 90);
2002
2003 tester::apply("l02",
2004 from_wkt<G>("LINESTRING(10 10,20 20,10 30)"),
2005 10, 10, 20, 30);
2006
2007 // linestring that circles the entire globe
2008 tester::apply("l03",
2009 from_wkt<G>("LINESTRING(-185 0,-170 25,-50 10,10 10,20 20,100 5,180 15)"),
b32b8144 2010 -180, 0, 180, 33.587539971516854,
7c673cae
FG
2011 4.0 * std::numeric_limits<double>::epsilon());
2012
2013 // linestring that crosses the antimeridian but staying close to it
2014 tester::apply("l04",
2015 from_wkt<G>("LINESTRING(-170 10,170 45,160 5,-160 25)"),
2016 160, 5, 200, 45);
2017
2018 // linestring that goes through the north pole (twice)
2019 tester::apply("l05",
2020 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30)"),
2021 -170, 30, 20, 90);
2022
2023 // linestring that goes through the north pole (three times)
2024 tester::apply("l05a",
2025 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70)"),
2026 -170, 30, 30, 90);
2027
2028 // linestring that goes through the north pole (four times)
2029 tester::apply("l05b",
2030 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25)"),
2031 -170, 25, 40, 90);
2032
2033 // linestring that goes through the north pole (five times)
2034 tester::apply("l05c",
2035 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25,-130 25,50 45)"),
2036 -170, 25, 50, 90);
2037
2038 // linestring that goes through the north pole (five times)
2039 tester::apply("l05d",
2040 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25,-130 25,50 45,185 45)"),
2041 -170, 25, 185, 90);
2042
2043 // linestring that crosses the antimeridian
2044 tester::apply("l06",
2045 from_wkt<G>("LINESTRING(-160 85,-170 80,170 40,160 80)"),
2046 160, 40, 200, 85);
2047
2048 // linestring that crosses the antimeridian
2049 tester::apply("l06a",
2050 from_wkt<G>("LINESTRING(-130 85,-170 84,170 40,160 80)"),
2051 160, 40, 230, 85.02629680862029);
2052
2053 // linestring that goes through the north pole
2054 tester::apply("l07",
2055 from_wkt<G>("LINESTRING(-160 40,-170 90,-140 40,-50 30)"),
2056 -160, 30, -50, 90);
2057
2058 // linestring that degenerates to the north pole
2059 tester::apply("l08",
2060 from_wkt<G>("LINESTRING(-40 90,-30 90,-140 90,10 90)"),
2061 0, 90, 0, 90);
2062
2063 // linestring with duplicate points
2064 tester::apply("l09",
2065 from_wkt<G>("LINESTRING(-40 20,-40 20,-140 85,-10 5,-10 5)"),
b32b8144
FG
2066 -140, 5, -10, 86.184540574427757);
2067
2068 // linestring with duplicate points
2069 tester::apply("l09a",
2070 from_wkt<G>("LINESTRING(-40 20,320 20,-140 85,-10 5,350 5)"),
2071 -140, 5, -10, 86.184540574427757);
2072
2073 // linestring that lies on the equator
2074 tester::apply("l10",
2075 from_wkt<G>("LINESTRING(0 0,50 0)"),
2076 0, 0, 50, 0);
2077
2078 // linestring that lies on the equator
2079 tester::apply("l10a",
2080 from_wkt<G>("LINESTRING(-50 0,50 0)"),
2081 -50, 0, 50, 0);
2082
2083 // linestring that lies on the equator and touches antimeridian
2084 tester::apply("l10b",
2085 from_wkt<G>("LINESTRING(50 0,180 0)"),
2086 50, 0, 180, 0);
2087
2088 // linestring that lies on the equator and crosses antimeridian
2089 tester::apply("l10c",
2090 from_wkt<G>("LINESTRING(-170 0,160 0)"),
2091 160, 0, 190, 0);
2092
2093 double eps = std::numeric_limits<double>::epsilon();
2094 double heps = eps / 2;
2095
2096 {
2097 G l;
2098 l.push_back(P(1, 1));
2099 l.push_back(P(1-heps, 1-heps));
2100 tester::apply("l11", l, 1-heps, 1-heps, 1, 1);
2101 }
2102
2103 {
2104 G l;
2105 l.push_back(P(0, 0));
2106 l.push_back(P(1-heps, 1-heps));
2107 l.push_back(P(0, 0));
2108 l.push_back(P(1, 1));
2109 tester::apply("l12", l, 0, 0, 1, 1);
2110 }
2111}
2112
2113BOOST_AUTO_TEST_CASE( envelope_spheroid_linestring )
2114{
2115 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
2116 typedef bg::model::point<double, 2, coordinate_system_type> P;
2117 typedef bg::model::linestring<P> G;
2118 typedef bg::model::box<P> B;
2119 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
2120
2121 // empty linestring
2122 test_empty_geometry<coordinate_system_type, G>("l00", "LINESTRING()");
2123
2124 tester::apply("l01",
2125 from_wkt<G>("LINESTRING(10 15)"),
2126 10, 15, 10, 15);
2127
2128 tester::apply("l01a",
2129 from_wkt<G>("LINESTRING(370 15)"),
2130 10, 15, 10, 15);
2131
2132 tester::apply("l01b",
2133 from_wkt<G>("LINESTRING(370 90)"),
2134 0, 90, 0, 90);
2135
2136 tester::apply("l02",
2137 from_wkt<G>("LINESTRING(10 10,20 20,10 30)"),
2138 10, 10, 20, 30);
2139
2140 // linestring that circles the entire globe
2141 tester::apply("l03",
2142 from_wkt<G>("LINESTRING(-185 0,-170 25,-50 10,10 10,20 20,100 5,180 15)"),
2143 -180, 0, 180, rng(33.702476580412359, 33.702476580413318));
2144
2145 // linestring that crosses the antimeridian but staying close to it
2146 tester::apply("l04",
2147 from_wkt<G>("LINESTRING(-170 10,170 45,160 5,-160 25)"),
2148 160, 5, 200, 45);
2149
2150 // linestring that goes through the north pole (twice)
2151 tester::apply("l05",
2152 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30)"),
2153 -170, 30, 20, 90);
2154
2155 // linestring that goes through the north pole (three times)
2156 tester::apply("l05a",
2157 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70)"),
2158 -170, 30, 30, 90);
2159
2160 // linestring that goes through the north pole (four times)
2161 tester::apply("l05b",
2162 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25)"),
2163 -170, 25, 40, 90);
2164
2165 // linestring that goes through the north pole (five times)
2166 tester::apply("l05c",
2167 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25,-130 25,50 45)"),
2168 -170, 25, 50, 90);
2169
2170 // linestring that goes through the north pole (five times)
2171 tester::apply("l05d",
2172 from_wkt<G>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25,-130 25,50 45,185 45)"),
2173 -170, 25, 185, 90);
2174
2175 // linestring that crosses the antimeridian
2176 tester::apply("l06",
2177 from_wkt<G>("LINESTRING(-160 85,-170 80,170 40,160 80)"),
2178 160, 40, 200, 85);
2179
2180 // linestring that crosses the antimeridian
2181 tester::apply("l06a",
2182 from_wkt<G>("LINESTRING(-130 85,-170 84,170 40,160 80)"),
2183 160, 40, 230, 85.02630556315151);
2184
2185 // linestring that goes through the north pole
2186 tester::apply("l07",
2187 from_wkt<G>("LINESTRING(-160 40,-170 90,-140 40,-50 30)"),
2188 -160, 30, -50, 90);
2189
2190 // linestring that degenerates to the north pole
2191 tester::apply("l08",
2192 from_wkt<G>("LINESTRING(-40 90,-30 90,-140 90,10 90)"),
2193 0, 90, 0, 90);
2194
2195 // linestring with duplicate points
2196 tester::apply("l09",
2197 from_wkt<G>("LINESTRING(-40 20,-40 20,-140 85,-10 5,-10 5)"),
2198 -140, 5, -10, 86.18564770636192);
7c673cae
FG
2199
2200 // linestring with duplicate points
2201 tester::apply("l09a",
2202 from_wkt<G>("LINESTRING(-40 20,320 20,-140 85,-10 5,350 5)"),
b32b8144 2203 -140, 5, -10, 86.18564770636192);
7c673cae
FG
2204
2205 // linestring that lies on the equator
2206 tester::apply("l10",
2207 from_wkt<G>("LINESTRING(0 0,50 0)"),
2208 0, 0, 50, 0);
2209
2210 // linestring that lies on the equator
2211 tester::apply("l10a",
2212 from_wkt<G>("LINESTRING(-50 0,50 0)"),
2213 -50, 0, 50, 0);
2214
2215 // linestring that lies on the equator and touches antimeridian
2216 tester::apply("l10b",
2217 from_wkt<G>("LINESTRING(50 0,180 0)"),
2218 50, 0, 180, 0);
2219
2220 // linestring that lies on the equator and crosses antimeridian
2221 tester::apply("l10c",
2222 from_wkt<G>("LINESTRING(-170 0,160 0)"),
2223 160, 0, 190, 0);
2224
2225 double eps = std::numeric_limits<double>::epsilon();
2226 double heps = eps / 2;
2227
2228 {
2229 G l;
2230 l.push_back(P(1, 1));
2231 l.push_back(P(1-heps, 1-heps));
2232 tester::apply("l11", l, 1-heps, 1-heps, 1, 1);
2233 }
2234
2235 {
2236 G l;
2237 l.push_back(P(0, 0));
2238 l.push_back(P(1-heps, 1-heps));
2239 l.push_back(P(0, 0));
2240 l.push_back(P(1, 1));
2241 tester::apply("l12", l, 0, 0, 1, 1);
2242 }
2243}
2244
2245
b32b8144 2246BOOST_AUTO_TEST_CASE( envelope_linestring_sphere_with_height )
7c673cae
FG
2247{
2248 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
2249 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
2250 typedef bg::model::linestring<point_type> G;
2251 typedef bg::model::box<point_type> B;
b32b8144 2252 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
2253
2254 // empty linestring
2255 test_empty_geometry<coordinate_system_type, G>("lh00", "LINESTRING()");
2256
2257 tester::apply("lh01",
2258 from_wkt<G>("LINESTRING(10 15 30,20 25 434,30 35 186)"),
2259 10, 15, 30, 30, 35, 434);
2260}
2261
b32b8144
FG
2262BOOST_AUTO_TEST_CASE( envelope_linestring_spheroid_with_height )
2263{
2264 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
2265 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
2266 typedef bg::model::linestring<point_type> G;
2267 typedef bg::model::box<point_type> B;
2268 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
2269
2270 // empty linestring
2271 test_empty_geometry<coordinate_system_type, G>("lh00", "LINESTRING()");
2272
2273 tester::apply("lh01",
2274 from_wkt<G>("LINESTRING(10 15 30,20 25 434,30 35 186)"),
2275 10, 15, 30, 30, 35, 434);
2276}
7c673cae 2277
b32b8144 2278BOOST_AUTO_TEST_CASE( envelope_sphere_multilinestring )
7c673cae
FG
2279{
2280 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
2281 typedef bg::model::point<double, 2, coordinate_system_type> point_type;
2282 typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
2283 typedef bg::model::box<point_type> B;
b32b8144 2284 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
2285
2286 // empty multilinestring
2287 test_empty_geometry<coordinate_system_type, G>("ml00", "MULTILINESTRING()");
2288
2289 // invalid multilinestring
2290 test_empty_geometry<coordinate_system_type, G>("ml00a",
2291 "MULTILINESTRING(())");
2292
2293 // invalid multilinestring
2294 test_empty_geometry<coordinate_system_type, G>("ml00b",
2295 "MULTILINESTRING((),())");
2296
2297 // invalid multilinestring
2298 tester::apply("ml00c",
2299 from_wkt<G>("MULTILINESTRING((10 15),(),())"),
2300 10, 15, 10, 15);
2301
2302 // invalid multilinestring
2303 tester::apply("ml00d",
2304 from_wkt<G>("MULTILINESTRING((),(10 15),())"),
2305 10, 15, 10, 15);
2306
2307 tester::apply("ml01",
2308 from_wkt<G>("MULTILINESTRING((10 15))"),
2309 10, 15, 10, 15);
2310
92f5a8d4 2311#ifdef BOOST_GEOMETRY_TEST_FAILURES
7c673cae
FG
2312 tester::apply("ml01a",
2313 from_wkt<G>("MULTILINESTRING((),(),(10 15),())"),
2314 10, 15, 10, 15);
92f5a8d4 2315#endif
7c673cae
FG
2316
2317 tester::apply("ml02",
2318 from_wkt<G>("MULTILINESTRING((-170 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
b32b8144 2319 -180, 25, 180, 81.113793608034072);
7c673cae
FG
2320
2321 tester::apply("ml03",
2322 from_wkt<G>("MULTILINESTRING((-150 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
b32b8144 2323 -150, 25, 200, 81.113793608034072);
7c673cae
FG
2324
2325 tester::apply("ml04",
2326 from_wkt<G>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80))"),
2327 -150, 35, 100, 80.07385383411011);
2328
2329 tester::apply("ml04a",
2330 from_wkt<G>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
2331 10, 25, 260, 80.07385383411011);
2332
2333 tester::apply("ml05",
2334 from_wkt<G>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80))"),
2335 -140, 35, 100, 80.07385383411011);
2336
2337 tester::apply("ml05a",
2338 from_wkt<G>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
2339 10, 25, 260, 80.07385383411011);
2340}
2341
b32b8144
FG
2342BOOST_AUTO_TEST_CASE( envelope_spheroid_multilinestring )
2343{
2344 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
2345 typedef bg::model::point<double, 2, coordinate_system_type> point_type;
2346 typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
2347 typedef bg::model::box<point_type> B;
2348 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
2349
2350 // empty multilinestring
2351 test_empty_geometry<coordinate_system_type, G>("ml00", "MULTILINESTRING()");
2352
2353 // invalid multilinestring
2354 test_empty_geometry<coordinate_system_type, G>("ml00a",
2355 "MULTILINESTRING(())");
2356
2357 // invalid multilinestring
2358 test_empty_geometry<coordinate_system_type, G>("ml00b",
2359 "MULTILINESTRING((),())");
2360
2361 // invalid multilinestring
2362 tester::apply("ml00c",
2363 from_wkt<G>("MULTILINESTRING((10 15),(),())"),
2364 10, 15, 10, 15);
2365
2366 // invalid multilinestring
2367 tester::apply("ml00d",
2368 from_wkt<G>("MULTILINESTRING((),(10 15),())"),
2369 10, 15, 10, 15);
2370
2371 tester::apply("ml01",
2372 from_wkt<G>("MULTILINESTRING((10 15))"),
2373 10, 15, 10, 15);
2374
92f5a8d4 2375#ifdef BOOST_GEOMETRY_TEST_FAILURES
b32b8144
FG
2376 tester::apply("ml01a",
2377 from_wkt<G>("MULTILINESTRING((),(),(10 15),())"),
2378 10, 15, 10, 15);
92f5a8d4 2379#endif
b32b8144
FG
2380
2381 tester::apply("ml02",
2382 from_wkt<G>("MULTILINESTRING((-170 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
2383 -180, 25, 180, 81.115885076701147);
2384
2385 tester::apply("ml03",
2386 from_wkt<G>("MULTILINESTRING((-150 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
2387 -150, 25, 200, 81.115885076701147);
2388
2389 tester::apply("ml04",
2390 from_wkt<G>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80))"),
2391 -150, 35, 100, rng(80.07385383411011, 80.082544902477267));
2392
2393 tester::apply("ml04a",
2394 from_wkt<G>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
2395 10, 25, 260, rng(80.07385383411011, 80.082544902477267));
2396
2397 tester::apply("ml05",
2398 from_wkt<G>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80))"),
2399 -140, 35, 100, rng(80.07385383411011, 80.082544902477267));
2400
2401 tester::apply("ml05a",
2402 from_wkt<G>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
2403 10, 25, 260, rng(80.07385383411011, 80.082544902477267));
2404}
2405
7c673cae 2406
b32b8144 2407BOOST_AUTO_TEST_CASE( envelope_multilinestring_sphere_with_height )
7c673cae
FG
2408{
2409 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
2410 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
2411 typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
2412 typedef bg::model::box<point_type> B;
b32b8144
FG
2413 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
2414
2415 tester::apply("mlh01",
2416 from_wkt<G>("MULTILINESTRING((10 15 1000))"),
2417 10, 15, 1000, 10, 15, 1000);
2418
92f5a8d4 2419#ifdef BOOST_GEOMETRY_TEST_FAILURES
b32b8144
FG
2420 tester::apply("mlh01a",
2421 from_wkt<G>("MULTILINESTRING((),(),(10 15 1000),())"),
2422 10, 15, 1000, 10, 15, 1000);
92f5a8d4 2423#endif
b32b8144
FG
2424
2425 tester::apply("mlh02",
2426 from_wkt<G>("MULTILINESTRING((-170 40 400,-100 80 300),(-10 25 600,10 35 700,120 45 450))"),
2427 -10, 25, 300, 260, 80, 700);
2428}
2429
2430BOOST_AUTO_TEST_CASE( envelope_multilinestring_spheroid_with_height )
2431{
2432 typedef bg::cs::geographic<bg::degree> coordinate_system_type;
2433 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
2434 typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
2435 typedef bg::model::box<point_type> B;
2436 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae
FG
2437
2438 tester::apply("mlh01",
2439 from_wkt<G>("MULTILINESTRING((10 15 1000))"),
2440 10, 15, 1000, 10, 15, 1000);
2441
92f5a8d4 2442#ifdef BOOST_GEOMETRY_TEST_FAILURES
7c673cae
FG
2443 tester::apply("mlh01a",
2444 from_wkt<G>("MULTILINESTRING((),(),(10 15 1000),())"),
2445 10, 15, 1000, 10, 15, 1000);
92f5a8d4 2446#endif
7c673cae
FG
2447
2448 tester::apply("mlh02",
2449 from_wkt<G>("MULTILINESTRING((-170 40 400,-100 80 300),(-10 25 600,10 35 700,120 45 450))"),
2450 -10, 25, 300, 260, 80, 700);
2451}
2452
92f5a8d4
TL
2453//Test spherical polygons and rings (geographic should be similar)
2454BOOST_AUTO_TEST_CASE( envelope_polygon )
2455{
2456 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
2457 typedef bg::model::point<double, 2, coordinate_system_type> point_type;
2458 typedef bg::model::polygon<point_type> G;
2459 typedef bg::model::box<point_type> B;
2460 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
2461
2462 typedef bg::model::ring<point_type> R;
2463 typedef test_envelope_on_sphere_or_spheroid<R, B> testerR;
2464 R ring1;
2465 bg::append(ring1, point_type(0.0, 0.0));
2466 bg::append(ring1, point_type(0.0, 5.0));
2467 bg::append(ring1, point_type(5.0, 5.0));
2468 bg::append(ring1, point_type(5.0, 0.0));
2469 bg::append(ring1, point_type(0.0, 0.0));
2470
2471 testerR::apply("r01",
2472 ring1,
2473 0, 0, 5, 5.0047392446083938);
2474 tester::apply("p01",
2475 from_wkt<G>("POLYGON((0 0,1 0,1 1,0 1,0 0))"),
2476 0, 0, 1, 1.0000380706527705);
2477 tester::apply("p02",
2478 from_wkt<G>("POLYGON((0 0,1 0,1 1,0 1,0 0),(0.5 0.5,0.7 0.5,0.7 0.7,0.5 0.5))"),
2479 0, 0, 1, 1.0000380706527705);
2480 tester::apply("p03",
2481 from_wkt<G>("POLYGON((),(0.5 0.5,0.5 0.7,0.7 0.7,0.5 0.5))"),
2482 0.5, 0.5, 0.7, 0.70000106605644807);
2483 tester::apply("p04",
2484 from_wkt<G>("POLYGON((),(0.5 0.5,0.5 0.7,0.7 0.7,0.5 0.5),\
2485 (0.7 0.5,0.9 0.5,0.9 0.7,0.7 0.5))"),
2486 0.5, 0.5, 0.9, 0.70000106605644807);
2487
2488 // https://github.com/boostorg/geometry/issues/466
2489 tester::apply("p5-issue466",
2490 from_wkt<G>("POLYGON((2.4 48.9021,2.4 48.89,2.3 48.89,2.3 48.9021,2.4 48.9021))"),
2491 2.3, 48.89, 2.4, 48.902110807274966);
2492 tester::apply("p6-issue466",
2493 from_wkt<G>("POLYGON((2.4 48.90215,2.4 48.89,2.3 48.89,2.3 48.90215,2.4 48.90215))"),
2494 2.3, 48.89, 2.4, 48.902160807272381);
2495 tester::apply("p7-issue466",
2496 from_wkt<G>("POLYGON((2.4 48.9022,2.4 48.89,2.3 48.89,2.3 48.9022,2.4 48.9022))"),
2497 2.3, 48.89, 2.4, 48.902210807269796);
2498}
7c673cae 2499
7c673cae
FG
2500// unit test for rings de-activated for now (current implementation
2501// for area on the spherical equatorial coordinate system is not complete)
2502// TODO: re-activate once implementation is done
92f5a8d4 2503// right now implementation does not distinguish between ccw and cw rings
7c673cae
FG
2504BOOST_AUTO_TEST_CASE( envelope_cw_ring )
2505{
b32b8144
FG
2506 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
2507 typedef bg::model::point<double, 2, coordinate_system_type> point_type;
2508 typedef bg::model::polygon<point_type> G;
2509 typedef bg::model::box<point_type> B;
2510 typedef test_envelope_on_sphere_or_spheroid<G, B> tester;
7c673cae 2511
b32b8144 2512 //double const eps = std::numeric_limits<double>::epsilon();
7c673cae
FG
2513
2514 tester::apply("r01cw",
2515 from_wkt<G>("POLYGON((0 10,0 45,50 10,0 10))"),
2516 0, 10, 50, 45);
b32b8144 2517#if 0
7c673cae
FG
2518 // ring that contains both the north and south poles in its interior
2519 tester::apply("r01cw-r",
2520 from_wkt<G>("POLYGON((0 10,50 10,0 45,0 10))"),
2521 -180, -90, 180, 90);
2522
2523 // ring that contains the north pole in its interior
2524 tester::apply("r02cw",
2525 from_wkt<G>("POLYGON((0 0,-50 0,-170 0,180 0,100 0,0 0))"),
2526 -180, 0, 180, 90);
2527 // -180, -90, 180, 0);
2528
2529 // ring that contains the south pole in its interior
2530 tester::apply("r02cw-r",
2531 from_wkt<G>("POLYGON((0 0,100 0,180 0,-170 0,-50 0,0 0))"),
2532 -180, -90, 180, 0);
2533 // -180, 0, 180, 90);
2534
2535 // ring that contains the north pole in its interior
2536 tester::apply("r03cw",
2537 from_wkt<G>("POLYGON((0 -10,-50 -10,-170 -10,180 -10,100 -10,0 -10))"),
2538 -180, -19.42540014068282, 180, 90);
2539 // -180, -90, 180, -10);
2540
2541 // ring that contains both the south and north poles in its interior
2542 tester::apply("r03cw-r",
2543 from_wkt<G>("POLYGON((0 -10,100 -10,180 -10,-170 -10,-50 -10,0 -10))"),
2544 -180, -90, 180, -10);
2545 // -180, -19.42540014068282, 180, 90);
2546
2547 // ring that has the north pole as vertex and contains the south pole
2548 tester::apply("r04cw",
2549 from_wkt<G>("POLYGON((0 0,-50 90,-50 0,0 0))"),
2550 -180, -90, 180, 90);
2551
2552 // ring that has the north pole as vertex
2553 tester::apply("r04cw-r",
2554 from_wkt<G>("POLYGON((0 0,-50 0,-50 90,0 0))"),
2555 -50, 0, 0, 90);
2556
2557 // ring that crosses antimeridian but does not contain any pole
2558 tester::apply("r05cw",
2559 from_wkt<G>("POLYGON((-140 0,140 10,-140 80,-140 0))"),
2560 140, 0, 220, 80);
2561
2562 // ring that crosses antimeridian multiple times but does not
2563 // contain any pole
2564 tester::apply("r06cw",
2565 from_wkt<G>("POLYGON((-140 10,140 10,140 80,-140 80,-140 10))"),
2566 140, 10, 220, 82.30737118075496,
2567 2 * eps);
2568
2569 // ring that crosses antimeridian multiple times but does not
2570 // contain any pole
2571 tester::apply("r07cw",
2572 from_wkt<G>("POLYGON((-140 10,140 10,180 80,-140 10))"),
2573 140, 10, 220, 80);
2574
2575 // ring that goes through the north pole
2576 tester::apply("r08cw",
2577 from_wkt<G>("POLYGON((0 0,-50 0,-50 90,0 0))"),
2578 -50, 0, 0, 90);
2579
2580 // ring that goes through the south pole and contains the north pole
2581 tester::apply("r09cw",
2582 from_wkt<G>("POLYGON((0 0,0 -90,50 0,0 0))"),
2583 -180, -90, 180, 90);
2584
2585 // ring that goes through the south pole
2586 tester::apply("r09cw-r",
2587 from_wkt<G>("POLYGON((0 0,50 0,50 -90,0 0))"),
2588 0, -90, 50, 0);
2589
2590 // ring that goes through both south and north pole
2591 tester::apply("r10cw",
2592 from_wkt<G>("POLYGON((50 0,50 -90,40 0,40 90,50 0))"),
2593 40, -90, 50, 90);
2594
2595 // ring that goes through both south and north pole and crosses antimeridian
2596 tester::apply("r11cw",
2597 from_wkt<G>("POLYGON((-170 0,-170 -90,160 0,160 90,-170 0))"),
2598 160, -90, 190, 90);
2599
2600 // ring with edge that goes through the north pole and contains
2601 // south pole (the bounding box is the entire globe)
2602 tester::apply("r12cw",
2603 from_wkt<G>("POLYGON((-50 40,130 10,170 80,-50 40))"),
2604 -180, -90, 180, 90);
2605 // -180, 10, 180, 90);
2606
2607 // ring with edge that goes through the north pole
2608 tester::apply("r12cw-r",
2609 from_wkt<G>("POLYGON((-50 40,170 80,130 10,-50 40))"),
2610 -180, 10, 180, 90);
2611 // -180, -90, 180, 90);
2612
2613 // ring that represents a spherical cap near the north pole
2614 tester::apply("r13cw",
2615 from_wkt<G>("POLYGON((100 45,0 45,-100 45,-100 90,100 45))"),
2616 -100, 45, 100, 90);
2617
2618 // ring that represents the complement of a spherical cap
2619 // near the north pole
2620 tester::apply("r13cw-r",
2621 from_wkt<G>("POLYGON((-100 45,0 45,100 45,100 90,-100 45))"),
2622 -180, -90, 180, 90);
2623
2624 // ring that represents the complement of a spherical cap
2625 // that touches the south pole
2626 tester::apply("r14cw",
2627 from_wkt<G>("POLYGON((-100 45,0 45,100 45,100 -90,-100 45))"),
2628 -100, -90, 100, 57.26759279038765);
2629
2630 // ring that represents a spherical cap that touches the south pole
2631 tester::apply("r14cw-r",
2632 from_wkt<G>("POLYGON((100 45,0 45,-100 45,-100 -90,100 45))"),
2633 -180, -90, 180, 90);
2634
2635 // ring with edge that goes through the south pole
2636 tester::apply("r15cw",
2637 from_wkt<G>("POLYGON((-50 -40,130 -10,170 -80,-50 -40))"),
2638 -180, -90, 180, -10);
2639
2640 // ring with edge that goes through the south pole and contains
2641 // north pole (the bounding box is the entire globe)
2642 tester::apply("r15cw-r",
2643 from_wkt<G>("POLYGON((-50 -40,170 -80,130 -10,-50 -40))"),
2644 -180, -90, 180, 90);
2645
2646 // ring that does not contain any pole and lies in the lower hemisphere
2647 tester::apply("r16",
2648 from_wkt<G>("POLYGON((-50 -80,-50 -40,-30 -40,-30 -80,-50 -80))"),
2649 -50, -80.14892388341609, -30, -40);
2650
2651 // ring that lies in the lower hemisphere and contains both poles
2652 tester::apply("r16-r",
2653 from_wkt<G>("POLYGON((-50 -80,-30 -80,-30 -40,-50 -40,-50 -80))"),
2654 -180, -90, 180, 90);
2655
2656 // ring that goes through the south pole and contains the north pole
2657 tester::apply("r17cw",
2658 from_wkt<G>("POLYGON((50 0,50 -90,100 0,50 0))"),
2659 -180, -90, 180, 90);
2660
2661 // ring that goes through the south pole
2662 tester::apply("r17cw-r",
2663 from_wkt<G>("POLYGON((50 0,100 0,100 -90,50 0))"),
2664 50, -90, 100, 0);
2665
2666 // ring that goes through the south pole and contains the north pole
2667 tester::apply("r18cw",
2668 from_wkt<G>("POLYGON((50 0,50 -90,460 0,50 0))"),
2669 -180, -90, 180, 90);
2670
2671 // ring that goes through the south pole
2672 tester::apply("r18cw-r",
2673 from_wkt<G>("POLYGON((50 0,460 0,100 -90,50 0))"),
2674 50, -90, 100, 0);
2675
2676 // ring that goes through the south pole and contains the north pole
2677 tester::apply("r19cw",
2678 from_wkt<G>("POLYGON((50 0,50 -90,-260 0,50 0))"),
2679 -180, -90, 180, 90);
2680
2681 // ring that goes through the south pole
2682 tester::apply("r19cw-r",
2683 from_wkt<G>("POLYGON((50 0,-260 0,100 -90,50 0))"),
2684 50, -90, 100, 0);
2685
2686 // ring that goes through both poles
2687 tester::apply("r20cw",
2688 from_wkt<G>("POLYGON((10 0,10 90,20 0,20 -90,10 0))"),
2689 10, -90, 20, 90); // SUCCEEDS FOR WRONG REASON
2690
2691 // ring that goes through both poles
2692 tester::apply("r20cw-r",
2693 from_wkt<G>("POLYGON((10 0,10 -90,20 0,20 90,10 0))"),
2694 -180, -90, 180, 90); // FAILS NOW
2695
2696 // ring that goes through both poles and its boundary forms
2697 // a great circle
2698 tester::apply("r21cw",
2699 from_wkt<G>("POLYGON((-10 0,-10 90,170 0,170 -90,-10 0))"),
2700 -10, -90, 170, 90); // SUCCEEDS FOR WRONG REASON
2701
2702 // ring that goes through both poles and its boundary forms
2703 // a great circle
2704 tester::apply("r21cw-r",
2705 from_wkt<G>("POLYGON((-10 0,-10 -90,170 0,170 90,-10 0))"),
2706 170, -90, 350, 90); // FAILS NOW
7c673cae 2707#endif
b32b8144
FG
2708}
2709