1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2015-2016, Oracle and/or its affiliates.
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
13 #ifndef BOOST_TEST_MODULE
14 #define BOOST_TEST_MODULE test_envelope_on_spheroid
17 #include <boost/test/included/unit_test.hpp>
24 #include <geometry_test_common.hpp>
25 #include <from_wkt.hpp>
27 #include <boost/numeric/conversion/bounds.hpp>
28 #include <boost/type_traits/is_same.hpp>
30 #include <boost/geometry/core/coordinate_dimension.hpp>
31 #include <boost/geometry/core/tag.hpp>
32 #include <boost/geometry/core/tags.hpp>
34 #include <boost/geometry/geometries/geometries.hpp>
36 #include <boost/geometry/util/condition.hpp>
38 #include <boost/geometry/io/dsv/write.hpp>
39 #include <boost/geometry/io/wkt/wkt.hpp>
41 #include <boost/geometry/algorithms/convert.hpp>
42 #include <boost/geometry/algorithms/envelope.hpp>
43 #include <boost/geometry/algorithms/reverse.hpp>
45 #include <boost/geometry/index/detail/algorithms/is_valid.hpp>
47 #include "test_envelope_expand_on_spheroid.hpp"
50 template <typename MBR
>
51 class envelope_on_spheroid_basic_tester
57 typename Tag
= typename
bg::tag
<Geometry
>::type
61 template <typename OutputStream
>
62 static inline OutputStream
& apply(OutputStream
& os
,
63 Geometry
const& geometry
)
65 os
<< bg::wkt(geometry
);
70 template <typename Segment
>
71 struct write_geometry
<Segment
, bg::segment_tag
>
73 template <typename OutputStream
>
74 static inline OutputStream
& apply(OutputStream
& os
,
75 Segment
const& segment
)
77 os
<< "SEGMENT" << bg::dsv(segment
);
82 template <typename Box
>
83 struct write_geometry
<Box
, bg::box_tag
>
85 template <typename OutputStream
>
86 static inline OutputStream
& apply(OutputStream
& os
,
89 os
<< "BOX" << bg::dsv(box
);
94 template <typename Geometry
, typename Box
>
95 static inline void check_message(bool same_boxes
,
96 std::string
const& case_id
,
97 std::string
const& units_str
,
98 Geometry
const& geometry
,
102 std::ostringstream stream
;
103 stream
<< "case ID: " << case_id
<< ", "
104 << "MBR units: " << units_str
<< "; "
107 write_geometry
<Geometry
>::apply(stream
, geometry
);
109 stream
<< std::setprecision(17);
111 stream
<< "; " << "expected: " << bg::dsv(expected
)
112 << ", " << "detected: " << bg::dsv(detected
);
114 BOOST_CHECK_MESSAGE(same_boxes
, stream
.str());
117 template <typename Box
, typename Geometry
>
118 static inline void base_test(std::string
const& case_id
,
119 Geometry
const& geometry
,
120 double lon_min
, double lat_min
, double height_min
,
121 double lon_max
, double lat_max
, double height_max
,
124 typedef typename
bg::coordinate_system
<Box
>::type::units box_units_type
;
126 std::string
const units_str
= units2string
<box_units_type
>();
129 bg::envelope(geometry
, detected
);
132 initialize_box
<Box
>::apply(expected
,
133 lon_min
, lat_min
, height_min
,
134 lon_max
, lat_max
, height_max
);
136 #ifdef BOOST_GEOMETRY_TEST_DEBUG
137 std::cout
<< "geometry: ";
138 write_geometry
<Geometry
>::apply(std::cout
, geometry
);
140 std::cout
<< std::endl
141 << "MBR units: " << units_str
143 << "expected: " << bg::dsv(expected
)
145 << "detected: " << bg::dsv(detected
)
146 << std::endl
<< std::endl
;
149 check_message(box_equals
<Box
>::apply(detected
, expected
, tolerance
),
151 geometry
, expected
, detected
);
153 // if valid box is expected, check the validity
154 if (lon_min
<= lon_max
&& lat_min
<= lat_max
&& height_min
<= height_max
)
156 BOOST_CHECK_MESSAGE(bg::index::detail::is_valid(detected
),
157 "Case ID: " << case_id
<< ", "
158 << "MBR units: " << units_str
<< "; "
159 << "Invalid Box: " << bg::dsv(detected
));
164 template <typename Geometry
>
165 static inline void apply(std::string
const& case_id
,
166 Geometry
const& geometry
,
167 double lon_min
, double lat_min
, double height_min
,
168 double lon_max
, double lat_max
, double height_max
,
171 typedef other_system_info
173 typename
bg::coordinate_system
<MBR
>::type
176 typedef bg::model::box
180 typename
bg::coordinate_type
<MBR
>::type
,
181 bg::dimension
<MBR
>::value
,
186 #ifdef BOOST_GEOMETRY_TEST_DEBUG
187 std::cout
<< std::endl
<< std::endl
;
188 std::cout
<< "case ID: " << case_id
<< std::endl
<< std::endl
;
191 base_test
<MBR
>(case_id
, geometry
,
192 lon_min
, lat_min
, height_min
,
193 lon_max
, lat_max
, height_max
,
196 if (lon_max
< lon_min
)
198 // we are in the case were a special MBR is returned;
199 // makes no sense to change units
200 base_test
<other_mbr_type
>(case_id
, geometry
,
201 lon_min
, lat_min
, height_min
,
202 lon_max
, lat_max
, height_max
,
207 base_test
<other_mbr_type
>(case_id
, geometry
,
208 other::convert(lon_min
),
209 other::convert(lat_min
),
211 other::convert(lon_max
),
212 other::convert(lat_max
),
220 // test the reverse of a geometry if it is either linear or ring
221 template <typename Geometry
, typename Tag
= typename
bg::tag
<Geometry
>::type
>
222 struct test_reverse_geometry
224 static bool const is_linear
=
225 boost::is_same
<Tag
, bg::segment_tag
>::value
226 || boost::is_same
<Tag
, bg::linestring_tag
>::value
227 || boost::is_same
<Tag
, bg::multi_linestring_tag
>::value
;
229 // currently disable rings
230 static bool const is_ring
= false;
231 // static bool const is_ring = boost::is_same<Tag, bg::ring_tag>::value;
233 typedef typename
boost::mpl::if_c
235 is_linear
|| is_ring
,
240 static bool const value
= type::value
;
247 typename Tag
= typename
bg::tag
<Geometry
>::type
,
248 bool TestReverse
= test_reverse_geometry
<Geometry
>::value
250 struct test_envelope_on_spheroid
252 static inline void apply(std::string
const& case_id
,
253 Geometry
const& geometry
,
254 double lon_min1
, double lat_min1
, double height_min1
,
255 double lon_max1
, double lat_max1
, double height_max1
,
256 double lon_min2
, double lat_min2
, double height_min2
,
257 double lon_max2
, double lat_max2
, double height_max2
,
258 double tolerance
= std::numeric_limits
<double>::epsilon())
260 envelope_on_spheroid_basic_tester
263 >::apply(case_id
, geometry
,
264 lon_min1
, lat_min1
, height_min1
,
265 lon_max1
, lat_max1
, height_max1
,
268 if (BOOST_GEOMETRY_CONDITION(TestReverse
))
270 std::string reversed_case_id
= case_id
+ "-reverse";
272 Geometry reversed_geometry
= geometry
;
273 bg::reverse(reversed_geometry
);
274 envelope_on_spheroid_basic_tester
277 >::apply(reversed_case_id
, reversed_geometry
,
278 lon_min2
, lat_min2
, height_min2
,
279 lon_max2
, lat_max2
, height_max2
,
283 #ifdef BOOST_GEOMETRY_TEST_DEBUG
284 std::cout
<< "=================="
285 << std::endl
<< std::endl
;
289 static inline void apply(std::string
const& case_id
,
290 Geometry
const& geometry
,
291 double lon_min1
, double lat_min1
,
292 double lon_max1
, double lat_max1
,
293 double lon_min2
, double lat_min2
,
294 double lon_max2
, double lat_max2
,
295 double tolerance
= std::numeric_limits
<double>::epsilon())
297 apply(case_id
, geometry
,
298 lon_min1
, lat_min1
, 0, lon_max1
, lat_max1
, 0,
299 lon_min2
, lat_min2
, 0, lon_max2
, lat_max2
, 0,
303 static inline void apply(std::string
const& case_id
,
304 Geometry
const& geometry
,
305 double lon_min
, double lat_min
, double height_min
,
306 double lon_max
, double lat_max
, double height_max
,
307 double tolerance
= std::numeric_limits
<double>::epsilon())
309 apply(case_id
, geometry
,
310 lon_min
, lat_min
, height_min
,
311 lon_max
, lat_max
, height_max
,
312 lon_min
, lat_min
, height_min
,
313 lon_max
, lat_max
, height_max
,
317 static inline void apply(std::string
const& case_id
,
318 Geometry
const& geometry
,
319 double lon_min
, double lat_min
,
320 double lon_max
, double lat_max
,
321 double tolerance
= std::numeric_limits
<double>::epsilon())
323 apply(case_id
, geometry
,
324 lon_min
, lat_min
, 0, lon_max
, lat_max
, 0,
330 // special tester for rings
331 template <typename Geometry
, typename MBR
, bool TestReverse
>
332 struct test_envelope_on_spheroid
<Geometry
, MBR
, bg::ring_tag
, TestReverse
>
334 static inline void apply(std::string
const& case_id
,
335 Geometry
const& geometry
,
336 double lon_min1
, double lat_min1
,
337 double lon_max1
, double lat_max1
,
338 double lon_min2
, double lat_min2
,
339 double lon_max2
, double lat_max2
,
340 double tolerance
= std::numeric_limits
<double>::epsilon())
342 envelope_on_spheroid_basic_tester
345 >::apply(case_id
, geometry
,
346 lon_min1
, lat_min1
, lon_max1
, lat_max1
,
349 std::string ccw_case_id
= case_id
+ "-2ccw";
353 typename
bg::point_type
<Geometry
>::type
, false
355 bg::convert(geometry
, ccw_ring
);
357 envelope_on_spheroid_basic_tester
360 >::apply(ccw_case_id
, ccw_ring
,
361 lon_min2
, lat_min2
, lon_max2
, lat_max2
,
364 #ifdef BOOST_GEOMETRY_TEST_DEBUG
365 std::cout
<< "=================="
366 << std::endl
<< std::endl
;
370 static inline void apply(std::string
const& case_id
,
371 Geometry
const& geometry
,
372 double lon_min
, double lat_min
,
373 double lon_max
, double lat_max
,
374 double tolerance
= std::numeric_limits
<double>::epsilon())
376 apply(case_id
, geometry
,
377 lon_min
, lat_min
, lon_max
, lat_max
,
378 lon_min
, lat_min
, lon_max
, lat_max
,
384 template <typename CoordinateSystem
, typename Geometry
>
385 void test_empty_geometry(std::string
const& case_id
, std::string
const& wkt
)
387 std::size_t const dim
= bg::dimension
<Geometry
>::value
;
389 typedef bg::model::point
<double, dim
, CoordinateSystem
> point_type
;
390 typedef bg::model::box
<point_type
> B
;
391 typedef test_envelope_on_spheroid
<Geometry
, B
> tester
;
393 typedef typename
bg::coordinate_type
<Geometry
>::type ct
;
394 ct high_val
= boost::numeric::bounds
<ct
>::highest();
395 ct low_val
= boost::numeric::bounds
<ct
>::lowest();
397 if (BOOST_GEOMETRY_CONDITION(dim
== 2))
399 tester::apply(case_id
,
400 from_wkt
<Geometry
>(wkt
),
401 high_val
, high_val
, low_val
, low_val
);
405 tester::apply(case_id
,
406 from_wkt
<Geometry
>(wkt
),
407 high_val
, high_val
, high_val
, low_val
, low_val
, low_val
);
412 template <typename CoordinateSystem
>
413 void test_envelope_point()
415 typedef bg::model::point
<double, 2, CoordinateSystem
> point_type
;
416 typedef point_type G
;
417 typedef bg::model::box
<point_type
> B
;
418 typedef test_envelope_on_spheroid
<G
, B
> tester
;
421 from_wkt
<G
>("POINT(10 10)"),
425 from_wkt
<G
>("POINT(370 10)"),
428 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
430 from_wkt
<G
>("POINT(370 -350)"),
434 // north and south poles
436 from_wkt
<G
>("POINT(0 90)"),
439 tester::apply("p04a",
440 from_wkt
<G
>("POINT(10 90)"),
443 tester::apply("p04b",
444 from_wkt
<G
>("POINT(270 90)"),
447 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
448 tester::apply("p04c",
449 from_wkt
<G
>("POINT(270 450)"),
453 tester::apply("p04d",
454 from_wkt
<G
>("POINT(190 90)"),
457 tester::apply("p04e",
458 from_wkt
<G
>("POINT(-100 90)"),
462 from_wkt
<G
>("POINT(0 -90)"),
465 tester::apply("p05a",
466 from_wkt
<G
>("POINT(10 -90)"),
469 tester::apply("p05b",
470 from_wkt
<G
>("POINT(270 -90)"),
473 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
474 tester::apply("p05c",
475 from_wkt
<G
>("POINT(270 -450)"),
479 tester::apply("p05d",
480 from_wkt
<G
>("POINT(190 -90)"),
483 tester::apply("p05e",
484 from_wkt
<G
>("POINT(-100 -90)"),
487 tester::apply("p05f",
488 from_wkt
<G
>("POINT(-100 -90)"),
492 BOOST_AUTO_TEST_CASE( envelope_point
)
494 test_envelope_point
<bg::cs::spherical_equatorial
<bg::degree
> >();
495 test_envelope_point
<bg::cs::geographic
<bg::degree
> >();
499 template <typename CoordinateSystem
>
500 void test_envelope_point_with_height()
502 typedef bg::model::point
<double, 3, CoordinateSystem
> point_type
;
503 typedef point_type G
;
504 typedef bg::model::box
<point_type
> B
;
505 typedef test_envelope_on_spheroid
<G
, B
> tester
;
507 tester::apply("ph01",
508 from_wkt
<G
>("POINT(10 10 1256)"),
509 10, 10, 1256, 10, 10, 1256);
512 BOOST_AUTO_TEST_CASE( envelope_point_with_height
)
514 test_envelope_point_with_height
516 bg::cs::spherical_equatorial
<bg::degree
>
518 test_envelope_point_with_height
<bg::cs::geographic
<bg::degree
> >();
522 BOOST_AUTO_TEST_CASE( envelope_segment
)
524 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
525 typedef bg::model::point
<double, 2, coordinate_system_type
> P
;
526 typedef bg::model::segment
<P
> G
;
527 typedef bg::model::box
<P
> B
;
528 typedef test_envelope_on_spheroid
<G
, B
> tester
;
530 double const eps
= std::numeric_limits
<double>::epsilon();
533 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
537 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
538 10, 10, 40, 10.34527004614999);
540 tester::apply("s02a",
541 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
542 10, 10, 40, 10.34527004614999);
545 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
546 160, 10, 190, 10.34527004614999);
548 tester::apply("s03a",
549 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
550 160, 10, 190, 10.34527004614999);
552 tester::apply("s03b",
553 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
554 160, -10.34527004614999, 190, -10);
557 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
560 tester::apply("s04a",
561 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
564 // segment ending at the north pole
566 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
569 // segment starting at the north pole
570 tester::apply("s05a",
571 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
574 // segment ending at the north pole
576 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
579 // segment starting at the north pole
580 tester::apply("s06a",
581 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
584 // segment ending at the north pole
586 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
589 // segment passing through the south pole
591 from_wkt
<G
>("SEGMENT(-170 -45,10 -30)"),
595 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
596 1, -85.28884376852969, 179, 30,
599 tester::apply("s09a",
600 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
601 2, -87.63659983704832, 181, 30);
605 from_wkt
<G
>("SEGMENT(0 -45,181 30)"),
606 -179, -88.07047433509489, 0, 30,
610 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
611 -100, 30, 20, 57.93195594009233);
613 tester::apply("s11a",
614 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
615 -100, 30, 20, 49.43962741846035);
617 // segment degenerating to the north pole
619 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
622 // segment degenerating to the south pole
624 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
628 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
629 10, 20, 20, 30);//48.87458730907602);
632 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
633 50, 45, 185, 69.05897952775615);
635 // segment that lies on the equator
637 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
640 // segment that lies on the equator
641 tester::apply("s16a",
642 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
645 // segment that lies on the equator and touches antimeridian
646 tester::apply("s16b",
647 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
650 // segment that lies on the equator and crosses antimeridian
651 tester::apply("s16c",
652 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
656 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
659 tester::apply("s17-r",
660 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
664 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
667 tester::apply("s18-r",
668 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
671 // segment connecting the north and south pole
673 // this should be forbidden actually, as it is not well-defined
674 // with this test we demonstrate that the algorithm still returns
675 // something meaningful
677 from_wkt
<G
>("SEGMENT(10 90,20 -90)"),
680 // https://svn.boost.org/trac/boost/ticket/12106
681 tester::apply("s100_ticket_12106",
682 G(P(11.488323611111111, 53.687086666666673), P(11.488324166666667, 53.687086666666673)),
683 11.488323611111111, 53.687086666666673, 11.488324166666667, 53.687086666666673);
685 double const heps
= eps
/ 2;
687 tester::apply("s101",
688 G(P(1, 1), P(1-heps
, 1-heps
)),
689 1-heps
, 1-heps
, 1, 1);
690 tester::apply("s102",
691 G(P(1, 1), P(1, 1-heps
)),
693 tester::apply("s103",
694 G(P(1, 1), P(1-heps
, 1)),
696 tester::apply("s104",
697 G(P(2, 1), P(1, 1-heps
)),
698 1, 1-heps
, 2, 1.000038070652770505);
699 tester::apply("s105",
700 G(P(1, 2), P(1-heps
, 1)),
705 BOOST_AUTO_TEST_CASE( envelope_segment_with_height
)
707 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
708 typedef bg::model::point
<double, 3, coordinate_system_type
> point_type
;
709 typedef bg::model::segment
<point_type
> G
;
710 typedef bg::model::box
<point_type
> B
;
711 typedef test_envelope_on_spheroid
<G
, B
> tester
;
713 tester::apply("sh01",
714 from_wkt
<G
>("SEGMENT(10 10 567,40 40 1356)"),
715 10, 10, 567, 40, 40, 1356);
717 tester::apply("sh02",
718 from_wkt
<G
>("SEGMENT(10 10 1356,40 40 567)"),
719 10, 10, 567, 40, 40, 1356);
723 template <typename CoordinateSystem
>
724 void test_envelope_multipoint()
726 typedef bg::model::point
<double, 2, CoordinateSystem
> P
;
727 typedef bg::model::multi_point
<P
> G
;
728 typedef bg::model::box
<P
> B
;
729 typedef test_envelope_on_spheroid
<G
, B
> tester
;
732 test_empty_geometry
<CoordinateSystem
, G
>("mp00", "MULTIPOINT()");
734 tester::apply("mp01",
735 from_wkt
<G
>("MULTIPOINT(0 0,10 10)"),
738 tester::apply("mp02",
739 from_wkt
<G
>("MULTIPOINT(0 10,10 0)"),
742 tester::apply("mp03",
743 from_wkt
<G
>("MULTIPOINT(-10 20,0 10,10 0)"),
746 tester::apply("mp04",
747 from_wkt
<G
>("MULTIPOINT(-10 20,0 10,10 -15)"),
750 tester::apply("mp05",
751 from_wkt
<G
>("MULTIPOINT(-85 10,85 -20)"),
754 tester::apply("mp06",
755 from_wkt
<G
>("MULTIPOINT(-95 10,85 -20)"),
758 tester::apply("mp07",
759 from_wkt
<G
>("MULTIPOINT(-96 10,85 -20)"),
760 85, -20, -96+360, 10);
762 tester::apply("mp08",
763 from_wkt
<G
>("MULTIPOINT(175 15,-175 -20)"),
764 175, -20, -175+360, 15);
766 tester::apply("mp09",
767 from_wkt
<G
>("MULTIPOINT(170 15,170 20,-175 10,-90 10,10 10)"),
768 170, 10, 10+360, 20);
771 tester::apply("mp09a",
772 from_wkt
<G
>("MULTIPOINT(10 10,170 15,170 20,-175 10,-90 10)"),
773 170, 10, 10+360, 20);
776 tester::apply("mp10",
777 from_wkt
<G
>("MULTIPOINT(10 10,20 90,30 -90)"),
781 tester::apply("mp11",
782 from_wkt
<G
>("MULTIPOINT(179 90,-179 -90,10 10)"),
785 tester::apply("mp11a",
786 from_wkt
<G
>("MULTIPOINT(10 10,179 90,-179 -90)"),
790 tester::apply("mp11b",
791 from_wkt
<G
>("MULTIPOINT(179 90,-179 -90,-90 0)"),
794 tester::apply("mp11c",
795 from_wkt
<G
>("MULTIPOINT(-90 0,179 90,-179 -90,-90 0)"),
798 tester::apply("mp12",
799 from_wkt
<G
>("MULTIPOINT(170 -30,175 60,-178 10)"),
800 170, -30, -178+360, 60);
802 tester::apply("mp13",
803 from_wkt
<G
>("MULTIPOINT(-170 -30,-175 40,178 50)"),
804 178, -30, -170+360, 50);
806 tester::apply("mp13a",
807 from_wkt
<G
>("MULTIPOINT(-170 -30,178 50)"),
808 178, -30, -170+360, 50);
810 tester::apply("mp13b",
811 from_wkt
<G
>("MULTIPOINT(-170 -30,178 50,-175 40)"),
812 178, -30, -170+360, 50);
814 tester::apply("mp15",
815 from_wkt
<G
>("MULTIPOINT(10 -20)"),
818 tester::apply("mp16",
819 from_wkt
<G
>("MULTIPOINT(0 90,10 90)"),
822 tester::apply("mp17",
823 from_wkt
<G
>("MULTIPOINT(179 80,-179 -80,10 10)"),
824 10, -80, -179+360, 80);
826 tester::apply("mp17a",
827 from_wkt
<G
>("MULTIPOINT(10 10,179 80,-179 -80)"),
828 10, -80, -179+360, 80);
830 tester::apply("mp17b",
831 from_wkt
<G
>("MULTIPOINT(179 80,-179 -80,-90 0)"),
832 179, -80, -90+360, 80);
834 tester::apply("mp17c",
835 from_wkt
<G
>("MULTIPOINT(-90 0,179 80,-179 -80,-90 0)"),
836 179, -80, -90+360, 80);
838 tester::apply("mp18",
839 from_wkt
<G
>("MULTIPOINT(-170 45,20 25,40 40)"),
842 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
843 tester::apply("mp18a",
844 from_wkt
<G
>("MULTIPOINT(10 135,20 25,40 40)"),
848 tester::apply("mp19",
849 from_wkt
<G
>("MULTIPOINT(350 45,20 25,40 40)"),
852 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
853 tester::apply("mp19a",
854 from_wkt
<G
>("MULTIPOINT(170 135,20 25,40 40)"),
858 double eps
= std::numeric_limits
<double>::epsilon();
859 double heps
= eps
/ 2;
862 mp
.push_back(P(1, 1));
863 mp
.push_back(P(1-heps
, 1-heps
));
864 tester::apply("mp20", mp
, 1-heps
, 1-heps
, 1, 1);
868 BOOST_AUTO_TEST_CASE( envelope_multipoint
)
870 test_envelope_multipoint
<bg::cs::spherical_equatorial
<bg::degree
> >();
871 test_envelope_multipoint
<bg::cs::geographic
<bg::degree
> >();
875 template <typename CoordinateSystem
>
876 void test_envelope_multipoint_with_height()
878 typedef bg::model::point
<double, 3, CoordinateSystem
> point_type
;
879 typedef bg::model::multi_point
<point_type
> G
;
880 typedef bg::model::box
<point_type
> B
;
881 typedef test_envelope_on_spheroid
<G
, B
> tester
;
884 test_empty_geometry
<CoordinateSystem
, G
>("mph00", "MULTIPOINT()");
886 tester::apply("mph01",
887 from_wkt
<G
>("MULTIPOINT(0 0 567,10 10 1456)"),
888 0, 0, 567, 10, 10, 1456);
890 tester::apply("mph02",
891 from_wkt
<G
>("MULTIPOINT(0 0 567,10 10 1456,20 90 967)"),
892 0, 0, 567, 10, 90, 1456);
895 BOOST_AUTO_TEST_CASE( envelope_multipoint_with_height
)
897 test_envelope_multipoint_with_height
899 bg::cs::spherical_equatorial
<bg::degree
>
901 test_envelope_multipoint_with_height
<bg::cs::geographic
<bg::degree
> >();
905 template <typename CoordinateSystem
>
906 void test_envelope_box()
908 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
909 typedef bg::model::point
<double, 2, coordinate_system_type
> P
;
910 typedef bg::model::box
<P
> G
;
911 typedef bg::model::box
<P
> B
;
912 typedef test_envelope_on_spheroid
<G
, B
> tester
;
915 from_wkt
<G
>("BOX(10 10,20 20)"),
918 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
920 from_wkt
<G
>("BOX(10 370,20 20)"),
924 // box crosses anti-meridian
925 tester::apply("b02a",
926 from_wkt
<G
>("BOX(170 10,-170 20)"),
930 from_wkt
<G
>("BOX(-170 10,170 20)"),
934 from_wkt
<G
>("BOX(10 10,350 20)"),
937 tester::apply("b04a",
938 from_wkt
<G
>("BOX(10 10,-10 20)"),
943 from_wkt
<G
>("BOX(0 10,360 20)"),
946 tester::apply("b05a",
947 from_wkt
<G
>("BOX(0 10,0 20)"),
950 // box is almost a band
952 from_wkt
<G
>("BOX(10 10,5 20)"),
955 // initial box is a band that crosses itself
957 from_wkt
<G
>("BOX(0 10,540 20)"),
960 // initial box is a band that crosses itself
962 from_wkt
<G
>("BOX(0 10,720 20)"),
966 from_wkt
<G
>("BOX(10 10,10 10)"),
969 tester::apply("b09a",
970 from_wkt
<G
>("BOX(370 10,370 10)"),
973 // box contains north and south pole
975 from_wkt
<G
>("BOX(0 -90,0 90)"),
978 // box contains north and south pole
979 tester::apply("b10a",
980 from_wkt
<G
>("BOX(10 -90,10 90)"),
983 // box contains north and south pole
984 tester::apply("b10b",
985 from_wkt
<G
>("BOX(0 -90,10 90)"),
988 // box contains north and south pole
990 from_wkt
<G
>("BOX(0 -90,180 90)"),
993 // box contains north and south pole
994 tester::apply("b11a",
995 from_wkt
<G
>("BOX(10 -90,190 90)"),
998 // box contains north and south pole
999 tester::apply("b11b",
1000 from_wkt
<G
>("BOX(10 -90,110 90)"),
1003 // box contains north and south pole and is a band
1004 // (box covers the entire spheroid)
1005 tester::apply("b12",
1006 from_wkt
<G
>("BOX(0 -90,360 90)"),
1007 -180, -90, 180, 90);
1009 // box contains north and south pole and is a band
1010 // (box covers the entire spheroid)
1011 tester::apply("b12a",
1012 from_wkt
<G
>("BOX(10 -90,370 90)"),
1013 -180, -90, 180, 90);
1015 // box contains north and south pole and is a band
1016 // (box covers the entire spheroid)
1017 tester::apply("b12b",
1018 from_wkt
<G
>("BOX(-175 -90,185 90)"),
1019 -180, -90, 180, 90);
1021 // box contains north and south pole and is a band
1022 // (box covers the entire spheroid)
1023 tester::apply("b12c",
1024 from_wkt
<G
>("BOX(-175 -90,185 90)"),
1025 -180, -90, 180, 90);
1027 // box contains north and south pole and is a band and is self-intersecting
1028 // (box covers the entire spheroid)
1029 tester::apply("b12d",
1030 from_wkt
<G
>("BOX(-175 -90,186 90)"),
1031 -180, -90, 180, 90);
1033 // box contains north and south pole and is a band and is self-intersecting
1034 // (box covers the entire spheroid)
1035 tester::apply("b12e",
1036 from_wkt
<G
>("BOX(0 -90,540 90)"),
1037 -180, -90, 180, 90);
1039 // box contains north and south pole and is a band and is self-intersecting
1040 // (box covers the entire spheroid)
1041 tester::apply("b12f",
1042 from_wkt
<G
>("BOX(10 -90,540 90)"),
1043 -180, -90, 180, 90);
1046 tester::apply("b13",
1047 from_wkt
<G
>("BOX(180 -10,-180 10)"),
1048 -180, -10, 180, 10);
1050 // box contains north and south pole and is a band
1051 // (box covers the entire spheroid)
1052 tester::apply("b13a",
1053 from_wkt
<G
>("BOX(180 -90,-180 90)"),
1054 -180, -90, 180, 90);
1056 tester::apply("b14",
1057 from_wkt
<G
>("BOX(0 10,30 90)"),
1060 tester::apply("b15",
1061 from_wkt
<G
>("BOX(179 10,178 70)"),
1064 // box contains north pole
1065 tester::apply("b16",
1066 from_wkt
<G
>("BOX(10 40,20 90)"),
1069 tester::apply("b16a",
1070 from_wkt
<G
>("BOX(170 40,-170 90)"),
1073 // box contains south pole
1074 tester::apply("b17",
1075 from_wkt
<G
>("BOX(10 -90,20 40)"),
1078 tester::apply("b17a",
1079 from_wkt
<G
>("BOX(150 -90,-150 40)"),
1082 // box degenerates to the north pole
1083 tester::apply("b98",
1084 from_wkt
<G
>("BOX(10 90,20 90)"),
1087 // box degenerates to the south pole
1088 tester::apply("b99",
1089 from_wkt
<G
>("BOX(10 -90,20 -90)"),
1092 double eps
= std::numeric_limits
<double>::epsilon();
1093 double heps
= eps
/ 2;
1095 tester::apply("b100", G(P(1-heps
, 1-heps
), P(1, 1)), 1-heps
, 1-heps
, 1, 1);
1098 BOOST_AUTO_TEST_CASE( envelope_box
)
1100 test_envelope_box
<bg::cs::spherical_equatorial
<bg::degree
> >();
1101 test_envelope_box
<bg::cs::geographic
<bg::degree
> >();
1105 template <typename CoordinateSystem
>
1106 void test_envelope_box_with_height()
1108 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
1109 typedef bg::model::point
<double, 3, coordinate_system_type
> point_type
;
1110 typedef bg::model::box
<point_type
> G
;
1111 typedef bg::model::box
<point_type
> B
;
1112 typedef test_envelope_on_spheroid
<G
, B
> tester
;
1114 tester::apply("bh01",
1115 from_wkt
<G
>("BOX(10 10 567,20 20 2834)"),
1116 10, 10, 567, 20, 20, 2834);
1118 tester::apply("bh02",
1119 from_wkt
<G
>("BOX(10 10 567,20 20 567)"),
1120 10, 10, 567, 20, 20, 567);
1122 tester::apply("bh03",
1123 from_wkt
<G
>("BOX(0 10 567,170 90 1567)"),
1124 0, 10, 567, 170, 90, 1567);
1127 BOOST_AUTO_TEST_CASE( envelope_box_with_height
)
1129 test_envelope_box_with_height
<bg::cs::spherical_equatorial
<bg::degree
> >();
1130 test_envelope_box_with_height
<bg::cs::geographic
<bg::degree
> >();
1134 BOOST_AUTO_TEST_CASE( envelope_linestring
)
1136 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
1137 typedef bg::model::point
<double, 2, coordinate_system_type
> P
;
1138 typedef bg::model::linestring
<P
> G
;
1139 typedef bg::model::box
<P
> B
;
1140 typedef test_envelope_on_spheroid
<G
, B
> tester
;
1143 test_empty_geometry
<coordinate_system_type
, G
>("l00", "LINESTRING()");
1145 tester::apply("l01",
1146 from_wkt
<G
>("LINESTRING(10 15)"),
1149 tester::apply("l01a",
1150 from_wkt
<G
>("LINESTRING(370 15)"),
1153 tester::apply("l01b",
1154 from_wkt
<G
>("LINESTRING(370 90)"),
1157 tester::apply("l02",
1158 from_wkt
<G
>("LINESTRING(10 10,20 20,10 30)"),
1161 // linestring that circles the entire globe
1162 tester::apply("l03",
1163 from_wkt
<G
>("LINESTRING(-185 0,-170 25,-50 10,10 10,20 20,100 5,180 15)"),
1164 -180, 0, 180, 25.15036418555258,
1165 4.0 * std::numeric_limits
<double>::epsilon());
1167 // linestring that crosses the antimeridian but staying close to it
1168 tester::apply("l04",
1169 from_wkt
<G
>("LINESTRING(-170 10,170 45,160 5,-160 25)"),
1172 // linestring that goes through the north pole (twice)
1173 tester::apply("l05",
1174 from_wkt
<G
>("LINESTRING(-170 80,10 60,20 80,-160 30)"),
1177 // linestring that goes through the north pole (three times)
1178 tester::apply("l05a",
1179 from_wkt
<G
>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70)"),
1182 // linestring that goes through the north pole (four times)
1183 tester::apply("l05b",
1184 from_wkt
<G
>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25)"),
1187 // linestring that goes through the north pole (five times)
1188 tester::apply("l05c",
1189 from_wkt
<G
>("LINESTRING(-170 80,10 60,20 80,-160 30,-150 30,30 70,40 85,-140 25,-130 25,50 45)"),
1192 // linestring that goes through the north pole (five times)
1193 tester::apply("l05d",
1194 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)"),
1197 // linestring that crosses the antimeridian
1198 tester::apply("l06",
1199 from_wkt
<G
>("LINESTRING(-160 85,-170 80,170 40,160 80)"),
1202 // linestring that crosses the antimeridian
1203 tester::apply("l06a",
1204 from_wkt
<G
>("LINESTRING(-130 85,-170 84,170 40,160 80)"),
1205 160, 40, 230, 85.02629680862029);
1207 // linestring that goes through the north pole
1208 tester::apply("l07",
1209 from_wkt
<G
>("LINESTRING(-160 40,-170 90,-140 40,-50 30)"),
1212 // linestring that degenerates to the north pole
1213 tester::apply("l08",
1214 from_wkt
<G
>("LINESTRING(-40 90,-30 90,-140 90,10 90)"),
1217 // linestring with duplicate points
1218 tester::apply("l09",
1219 from_wkt
<G
>("LINESTRING(-40 20,-40 20,-140 85,-10 5,-10 5)"),
1222 // linestring with duplicate points
1223 tester::apply("l09a",
1224 from_wkt
<G
>("LINESTRING(-40 20,320 20,-140 85,-10 5,350 5)"),
1227 // linestring that lies on the equator
1228 tester::apply("l10",
1229 from_wkt
<G
>("LINESTRING(0 0,50 0)"),
1232 // linestring that lies on the equator
1233 tester::apply("l10a",
1234 from_wkt
<G
>("LINESTRING(-50 0,50 0)"),
1237 // linestring that lies on the equator and touches antimeridian
1238 tester::apply("l10b",
1239 from_wkt
<G
>("LINESTRING(50 0,180 0)"),
1242 // linestring that lies on the equator and crosses antimeridian
1243 tester::apply("l10c",
1244 from_wkt
<G
>("LINESTRING(-170 0,160 0)"),
1247 double eps
= std::numeric_limits
<double>::epsilon();
1248 double heps
= eps
/ 2;
1252 l
.push_back(P(1, 1));
1253 l
.push_back(P(1-heps
, 1-heps
));
1254 tester::apply("l11", l
, 1-heps
, 1-heps
, 1, 1);
1259 l
.push_back(P(0, 0));
1260 l
.push_back(P(1-heps
, 1-heps
));
1261 l
.push_back(P(0, 0));
1262 l
.push_back(P(1, 1));
1263 tester::apply("l12", l
, 0, 0, 1, 1);
1268 BOOST_AUTO_TEST_CASE( envelope_linestring_with_height
)
1270 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
1271 typedef bg::model::point
<double, 3, coordinate_system_type
> point_type
;
1272 typedef bg::model::linestring
<point_type
> G
;
1273 typedef bg::model::box
<point_type
> B
;
1274 typedef test_envelope_on_spheroid
<G
, B
> tester
;
1277 test_empty_geometry
<coordinate_system_type
, G
>("lh00", "LINESTRING()");
1279 tester::apply("lh01",
1280 from_wkt
<G
>("LINESTRING(10 15 30,20 25 434,30 35 186)"),
1281 10, 15, 30, 30, 35, 434);
1285 BOOST_AUTO_TEST_CASE( envelope_multilinestring
)
1287 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
1288 typedef bg::model::point
<double, 2, coordinate_system_type
> point_type
;
1289 typedef bg::model::multi_linestring
<bg::model::linestring
<point_type
> > G
;
1290 typedef bg::model::box
<point_type
> B
;
1291 typedef test_envelope_on_spheroid
<G
, B
> tester
;
1293 // empty multilinestring
1294 test_empty_geometry
<coordinate_system_type
, G
>("ml00", "MULTILINESTRING()");
1296 // invalid multilinestring
1297 test_empty_geometry
<coordinate_system_type
, G
>("ml00a",
1298 "MULTILINESTRING(())");
1300 // invalid multilinestring
1301 test_empty_geometry
<coordinate_system_type
, G
>("ml00b",
1302 "MULTILINESTRING((),())");
1304 // invalid multilinestring
1305 tester::apply("ml00c",
1306 from_wkt
<G
>("MULTILINESTRING((10 15),(),())"),
1309 // invalid multilinestring
1310 tester::apply("ml00d",
1311 from_wkt
<G
>("MULTILINESTRING((),(10 15),())"),
1314 tester::apply("ml01",
1315 from_wkt
<G
>("MULTILINESTRING((10 15))"),
1318 #ifdef BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
1319 tester::apply("ml01a",
1320 from_wkt
<G
>("MULTILINESTRING((),(),(10 15),())"),
1322 #endif // BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
1324 tester::apply("ml02",
1325 from_wkt
<G
>("MULTILINESTRING((-170 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
1328 tester::apply("ml03",
1329 from_wkt
<G
>("MULTILINESTRING((-150 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
1332 tester::apply("ml04",
1333 from_wkt
<G
>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80))"),
1334 -150, 35, 100, 80.07385383411011);
1336 tester::apply("ml04a",
1337 from_wkt
<G
>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
1338 10, 25, 260, 80.07385383411011);
1340 tester::apply("ml05",
1341 from_wkt
<G
>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80))"),
1342 -140, 35, 100, 80.07385383411011);
1344 tester::apply("ml05a",
1345 from_wkt
<G
>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80),(170 25,-160 80))"),
1346 10, 25, 260, 80.07385383411011);
1350 BOOST_AUTO_TEST_CASE( envelope_multilinestring_with_height
)
1352 typedef bg::cs::spherical_equatorial
<bg::degree
> coordinate_system_type
;
1353 typedef bg::model::point
<double, 3, coordinate_system_type
> point_type
;
1354 typedef bg::model::multi_linestring
<bg::model::linestring
<point_type
> > G
;
1355 typedef bg::model::box
<point_type
> B
;
1356 typedef test_envelope_on_spheroid
<G
, B
> tester
;
1358 tester::apply("mlh01",
1359 from_wkt
<G
>("MULTILINESTRING((10 15 1000))"),
1360 10, 15, 1000, 10, 15, 1000);
1362 #ifdef BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
1363 tester::apply("mlh01a",
1364 from_wkt
<G
>("MULTILINESTRING((),(),(10 15 1000),())"),
1365 10, 15, 1000, 10, 15, 1000);
1366 #endif // BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
1368 tester::apply("mlh02",
1369 from_wkt
<G
>("MULTILINESTRING((-170 40 400,-100 80 300),(-10 25 600,10 35 700,120 45 450))"),
1370 -10, 25, 300, 260, 80, 700);
1375 // unit test for rings de-activated for now (current implementation
1376 // for area on the spherical equatorial coordinate system is not complete)
1377 // TODO: re-activate once implementation is done
1378 BOOST_AUTO_TEST_CASE( envelope_cw_ring
)
1380 typedef deg_cw_ring_type G
;
1381 typedef test_envelope_on_spheroid
<G
, deg_box_type
> tester
;
1383 double const eps
= std::numeric_limits
<double>::epsilon();
1385 tester::apply("r01cw",
1386 from_wkt
<G
>("POLYGON((0 10,0 45,50 10,0 10))"),
1389 // ring that contains both the north and south poles in its interior
1390 tester::apply("r01cw-r",
1391 from_wkt
<G
>("POLYGON((0 10,50 10,0 45,0 10))"),
1392 -180, -90, 180, 90);
1394 // ring that contains the north pole in its interior
1395 tester::apply("r02cw",
1396 from_wkt
<G
>("POLYGON((0 0,-50 0,-170 0,180 0,100 0,0 0))"),
1398 // -180, -90, 180, 0);
1400 // ring that contains the south pole in its interior
1401 tester::apply("r02cw-r",
1402 from_wkt
<G
>("POLYGON((0 0,100 0,180 0,-170 0,-50 0,0 0))"),
1404 // -180, 0, 180, 90);
1406 // ring that contains the north pole in its interior
1407 tester::apply("r03cw",
1408 from_wkt
<G
>("POLYGON((0 -10,-50 -10,-170 -10,180 -10,100 -10,0 -10))"),
1409 -180, -19.42540014068282, 180, 90);
1410 // -180, -90, 180, -10);
1412 // ring that contains both the south and north poles in its interior
1413 tester::apply("r03cw-r",
1414 from_wkt
<G
>("POLYGON((0 -10,100 -10,180 -10,-170 -10,-50 -10,0 -10))"),
1415 -180, -90, 180, -10);
1416 // -180, -19.42540014068282, 180, 90);
1418 // ring that has the north pole as vertex and contains the south pole
1419 tester::apply("r04cw",
1420 from_wkt
<G
>("POLYGON((0 0,-50 90,-50 0,0 0))"),
1421 -180, -90, 180, 90);
1423 // ring that has the north pole as vertex
1424 tester::apply("r04cw-r",
1425 from_wkt
<G
>("POLYGON((0 0,-50 0,-50 90,0 0))"),
1428 // ring that crosses antimeridian but does not contain any pole
1429 tester::apply("r05cw",
1430 from_wkt
<G
>("POLYGON((-140 0,140 10,-140 80,-140 0))"),
1433 // ring that crosses antimeridian multiple times but does not
1435 tester::apply("r06cw",
1436 from_wkt
<G
>("POLYGON((-140 10,140 10,140 80,-140 80,-140 10))"),
1437 140, 10, 220, 82.30737118075496,
1440 // ring that crosses antimeridian multiple times but does not
1442 tester::apply("r07cw",
1443 from_wkt
<G
>("POLYGON((-140 10,140 10,180 80,-140 10))"),
1446 // ring that goes through the north pole
1447 tester::apply("r08cw",
1448 from_wkt
<G
>("POLYGON((0 0,-50 0,-50 90,0 0))"),
1451 // ring that goes through the south pole and contains the north pole
1452 tester::apply("r09cw",
1453 from_wkt
<G
>("POLYGON((0 0,0 -90,50 0,0 0))"),
1454 -180, -90, 180, 90);
1456 // ring that goes through the south pole
1457 tester::apply("r09cw-r",
1458 from_wkt
<G
>("POLYGON((0 0,50 0,50 -90,0 0))"),
1461 // ring that goes through both south and north pole
1462 tester::apply("r10cw",
1463 from_wkt
<G
>("POLYGON((50 0,50 -90,40 0,40 90,50 0))"),
1466 // ring that goes through both south and north pole and crosses antimeridian
1467 tester::apply("r11cw",
1468 from_wkt
<G
>("POLYGON((-170 0,-170 -90,160 0,160 90,-170 0))"),
1471 // ring with edge that goes through the north pole and contains
1472 // south pole (the bounding box is the entire globe)
1473 tester::apply("r12cw",
1474 from_wkt
<G
>("POLYGON((-50 40,130 10,170 80,-50 40))"),
1475 -180, -90, 180, 90);
1476 // -180, 10, 180, 90);
1478 // ring with edge that goes through the north pole
1479 tester::apply("r12cw-r",
1480 from_wkt
<G
>("POLYGON((-50 40,170 80,130 10,-50 40))"),
1482 // -180, -90, 180, 90);
1484 // ring that represents a spherical cap near the north pole
1485 tester::apply("r13cw",
1486 from_wkt
<G
>("POLYGON((100 45,0 45,-100 45,-100 90,100 45))"),
1489 // ring that represents the complement of a spherical cap
1490 // near the north pole
1491 tester::apply("r13cw-r",
1492 from_wkt
<G
>("POLYGON((-100 45,0 45,100 45,100 90,-100 45))"),
1493 -180, -90, 180, 90);
1495 // ring that represents the complement of a spherical cap
1496 // that touches the south pole
1497 tester::apply("r14cw",
1498 from_wkt
<G
>("POLYGON((-100 45,0 45,100 45,100 -90,-100 45))"),
1499 -100, -90, 100, 57.26759279038765);
1501 // ring that represents a spherical cap that touches the south pole
1502 tester::apply("r14cw-r",
1503 from_wkt
<G
>("POLYGON((100 45,0 45,-100 45,-100 -90,100 45))"),
1504 -180, -90, 180, 90);
1506 // ring with edge that goes through the south pole
1507 tester::apply("r15cw",
1508 from_wkt
<G
>("POLYGON((-50 -40,130 -10,170 -80,-50 -40))"),
1509 -180, -90, 180, -10);
1511 // ring with edge that goes through the south pole and contains
1512 // north pole (the bounding box is the entire globe)
1513 tester::apply("r15cw-r",
1514 from_wkt
<G
>("POLYGON((-50 -40,170 -80,130 -10,-50 -40))"),
1515 -180, -90, 180, 90);
1517 // ring that does not contain any pole and lies in the lower hemisphere
1518 tester::apply("r16",
1519 from_wkt
<G
>("POLYGON((-50 -80,-50 -40,-30 -40,-30 -80,-50 -80))"),
1520 -50, -80.14892388341609, -30, -40);
1522 // ring that lies in the lower hemisphere and contains both poles
1523 tester::apply("r16-r",
1524 from_wkt
<G
>("POLYGON((-50 -80,-30 -80,-30 -40,-50 -40,-50 -80))"),
1525 -180, -90, 180, 90);
1527 // ring that goes through the south pole and contains the north pole
1528 tester::apply("r17cw",
1529 from_wkt
<G
>("POLYGON((50 0,50 -90,100 0,50 0))"),
1530 -180, -90, 180, 90);
1532 // ring that goes through the south pole
1533 tester::apply("r17cw-r",
1534 from_wkt
<G
>("POLYGON((50 0,100 0,100 -90,50 0))"),
1537 // ring that goes through the south pole and contains the north pole
1538 tester::apply("r18cw",
1539 from_wkt
<G
>("POLYGON((50 0,50 -90,460 0,50 0))"),
1540 -180, -90, 180, 90);
1542 // ring that goes through the south pole
1543 tester::apply("r18cw-r",
1544 from_wkt
<G
>("POLYGON((50 0,460 0,100 -90,50 0))"),
1547 // ring that goes through the south pole and contains the north pole
1548 tester::apply("r19cw",
1549 from_wkt
<G
>("POLYGON((50 0,50 -90,-260 0,50 0))"),
1550 -180, -90, 180, 90);
1552 // ring that goes through the south pole
1553 tester::apply("r19cw-r",
1554 from_wkt
<G
>("POLYGON((50 0,-260 0,100 -90,50 0))"),
1557 // ring that goes through both poles
1558 tester::apply("r20cw",
1559 from_wkt
<G
>("POLYGON((10 0,10 90,20 0,20 -90,10 0))"),
1560 10, -90, 20, 90); // SUCCEEDS FOR WRONG REASON
1562 // ring that goes through both poles
1563 tester::apply("r20cw-r",
1564 from_wkt
<G
>("POLYGON((10 0,10 -90,20 0,20 90,10 0))"),
1565 -180, -90, 180, 90); // FAILS NOW
1567 // ring that goes through both poles and its boundary forms
1569 tester::apply("r21cw",
1570 from_wkt
<G
>("POLYGON((-10 0,-10 90,170 0,170 -90,-10 0))"),
1571 -10, -90, 170, 90); // SUCCEEDS FOR WRONG REASON
1573 // ring that goes through both poles and its boundary forms
1575 tester::apply("r21cw-r",
1576 from_wkt
<G
>("POLYGON((-10 0,-10 -90,170 0,170 90,-10 0))"),
1577 170, -90, 350, 90); // FAILS NOW