1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2015-2018, Oracle and/or its affiliates.
6 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
7 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
8 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
10 // Licensed under the Boost Software License version 1.0.
11 // http://www.boost.org/users/license.html
14 #ifndef BOOST_TEST_MODULE
15 #define BOOST_TEST_MODULE test_envelope_on_sphere_or_spheroid
18 #include <boost/test/included/unit_test.hpp>
25 #include <geometry_test_common.hpp>
26 #include <from_wkt.hpp>
28 #include <boost/numeric/conversion/bounds.hpp>
29 #include <boost/type_traits/is_same.hpp>
31 #include <boost/geometry/core/coordinate_dimension.hpp>
32 #include <boost/geometry/core/tag.hpp>
33 #include <boost/geometry/core/tags.hpp>
35 #include <boost/geometry/geometries/geometries.hpp>
37 #include <boost/geometry/util/condition.hpp>
39 #include <boost/geometry/io/dsv/write.hpp>
40 #include <boost/geometry/io/wkt/wkt.hpp>
42 #include <boost/geometry/algorithms/convert.hpp>
43 #include <boost/geometry/algorithms/envelope.hpp>
44 #include <boost/geometry/algorithms/reverse.hpp>
46 #include <boost/geometry/index/detail/algorithms/is_valid.hpp>
48 #include "test_envelope_expand_on_spheroid.hpp"
51 template <typename FormulaPolicy
, typename CS_Tag
>
54 template <typename Geometry
, typename Box
>
55 static inline void apply(Geometry
& geometry
, Box
& detected
)
57 bg::envelope(geometry
, detected
);
61 template <typename FormulaPolicy
>
62 struct test_envelope
<FormulaPolicy
, bg::geographic_tag
>
64 template <typename Geometry
, typename Box
>
65 static inline void apply(Geometry
& geometry
,
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
;
73 typename
boost::mpl::if_c
75 boost::is_same
<typename
bg::tag
<Geometry
>::type
, bg::point_tag
>::value
,
77 typename
boost::mpl::if_c
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
83 boost::is_same
<typename
bg::tag
<Geometry
>::type
, bg::box_tag
>::value
,
90 bg::envelope(geometry
, detected
, strategy
);
94 template <typename MBR
, typename FormulaPolicy
= bg::strategy::thomas
>
95 class envelope_on_spheroid_basic_tester
101 typename Tag
= typename
bg::tag
<Geometry
>::type
103 struct write_geometry
105 template <typename OutputStream
>
106 static inline OutputStream
& apply(OutputStream
& os
,
107 Geometry
const& geometry
)
109 os
<< bg::wkt(geometry
);
114 template <typename Segment
>
115 struct write_geometry
<Segment
, bg::segment_tag
>
117 template <typename OutputStream
>
118 static inline OutputStream
& apply(OutputStream
& os
,
119 Segment
const& segment
)
121 os
<< "SEGMENT" << bg::dsv(segment
);
126 template <typename Box
>
127 struct write_geometry
<Box
, bg::box_tag
>
129 template <typename OutputStream
>
130 static inline OutputStream
& apply(OutputStream
& os
,
133 os
<< "BOX" << bg::dsv(box
);
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
,
146 std::ostringstream stream
;
147 stream
<< "case ID: " << case_id
<< ", "
148 << "MBR units: " << units_str
<< "; "
151 write_geometry
<Geometry
>::apply(stream
, geometry
);
153 stream
<< std::setprecision(17);
155 stream
<< "; " << "expected: " << bg::dsv(expected
)
156 << ", " << "detected: " << bg::dsv(detected
);
158 BOOST_CHECK_MESSAGE(same_boxes
, stream
.str());
163 typename Geometry
, typename Box
,
164 typename T1
, typename T2
, typename T3
, typename T4
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
,
174 std::ostringstream stream
;
175 stream
<< "case ID: " << case_id
<< ", "
176 << "MBR units: " << units_str
<< "; "
179 write_geometry
<Geometry
>::apply(stream
, geometry
);
181 stream
<< std::setprecision(17);
183 stream
<< "; " << "expected: ";
185 if (BOOST_GEOMETRY_CONDITION(bg::dimension
<Box
>::value
== 2))
187 stream
<< "(" << lon_min
<< " " << lat_min
188 << ", " << lon_max
<< " " << lat_max
<< ")";
192 stream
<< "(" << lon_min
<< " " << lat_min
<< " " << height_min
193 << ", " << lon_max
<< " " << lat_max
<< " " << height_max
<< ")";
195 stream
<< ", " << "detected: " << bg::dsv(detected
);
197 BOOST_CHECK_MESSAGE(same_boxes
, stream
.str());
202 typename Box
, typename Geometry
,
203 typename T1
, typename T2
, typename T3
, typename T4
205 static inline void base_test(std::string
const& case_id
,
206 Geometry
const& geometry
,
207 T1
const& lon_min
, T2
const& lat_min
, double height_min
,
208 T3
const& lon_max
, T4
const& lat_max
, double height_max
,
211 typedef typename
bg::coordinate_system
<Box
>::type::units box_units_type
;
213 std::string
const units_str
= units2string
<box_units_type
>();
216 test_envelope
<FormulaPolicy
, typename
bg::cs_tag
<Geometry
>::type
>
217 ::apply(geometry
, detected
);
219 #ifdef BOOST_GEOMETRY_TEST_DEBUG
220 std::cout
<< "geometry: ";
221 write_geometry
<Geometry
>::apply(std::cout
, geometry
);
223 std::cout
<< std::endl
224 << "MBR units: " << units_str
226 std::cout
<< "expected: ";
227 if (BOOST_GEOMETRY_CONDITION(bg::dimension
<Box
>::value
== 2))
229 std::cout
<< "(" << lon_min
<< " " << lat_min
230 << ", " << lon_max
<< " " << lat_max
<< ")";
234 std::cout
<< "(" << lon_min
<< " " << lat_min
<< " " << height_min
235 << ", " << lon_max
<< " " << lat_max
<< " " << height_max
<< ")";
237 std::cout
<< std::endl
238 << "detected: " << bg::dsv(detected
)
239 << std::endl
<< std::endl
;
242 bool check
= box_check_equals
<Box
>::apply(detected
,
243 lon_min
, lat_min
, height_min
,
244 lon_max
, lat_max
, height_max
,
250 lon_min
, lat_min
, height_min
,
251 lon_max
, lat_max
, height_max
,
254 // if valid box is expected, check the validity
255 if (lon_min
<= lon_max
&& lat_min
<= lat_max
&& height_min
<= height_max
)
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
));
268 typename T1
, typename T2
, typename T3
, typename T4
270 static inline void apply(std::string
const& case_id
,
271 Geometry
const& geometry
,
272 T1
const& lon_min
, T2
const& lat_min
, double height_min
,
273 T3
const& lon_max
, T4
const& lat_max
, double height_max
,
276 typedef other_system_info
278 typename
bg::coordinate_system
<MBR
>::type
281 typedef bg::model::box
285 typename
bg::coordinate_type
<MBR
>::type
,
286 bg::dimension
<MBR
>::value
,
291 #ifdef BOOST_GEOMETRY_TEST_DEBUG
292 std::cout
<< std::endl
<< std::endl
;
293 std::cout
<< "case ID: " << case_id
<< std::endl
<< std::endl
;
296 base_test
<MBR
>(case_id
, geometry
,
297 lon_min
, lat_min
, height_min
,
298 lon_max
, lat_max
, height_max
,
301 if (lon_max
< lon_min
)
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
,
312 base_test
<other_mbr_type
>(case_id
, geometry
,
313 other::convert(lon_min
),
314 other::convert(lat_min
),
316 other::convert(lon_max
),
317 other::convert(lat_max
),
325 // test the reverse of a geometry if it is either linear or ring
326 template <typename Geometry
, typename Tag
= typename
bg::tag
<Geometry
>::type
>
327 struct test_reverse_geometry
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
;
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;
338 typedef typename
boost::mpl::if_c
340 is_linear
|| is_ring
,
345 static bool const value
= type::value
;
352 typename Tag
= typename
bg::tag
<Geometry
>::type
,
353 bool TestReverse
= test_reverse_geometry
<Geometry
>::value
,
354 typename FormulaPolicy
= bg::strategy::thomas
356 struct test_envelope_on_sphere_or_spheroid
358 template <typename T1
, typename T2
, typename T3
, typename T4
,
359 typename T5
, typename T6
, typename T7
, typename T8
>
360 static inline void apply(std::string
const& case_id
,
361 Geometry
const& geometry
,
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
,
366 double tolerance
= std::numeric_limits
<double>::epsilon())
368 envelope_on_spheroid_basic_tester
371 >::apply(case_id
, geometry
,
372 lon_min1
, lat_min1
, height_min1
,
373 lon_max1
, lat_max1
, height_max1
,
376 if (BOOST_GEOMETRY_CONDITION(TestReverse
))
378 std::string reversed_case_id
= case_id
+ "-reverse";
380 Geometry reversed_geometry
= geometry
;
381 bg::reverse(reversed_geometry
);
382 envelope_on_spheroid_basic_tester
385 >::apply(reversed_case_id
, reversed_geometry
,
386 lon_min2
, lat_min2
, height_min2
,
387 lon_max2
, lat_max2
, height_max2
,
391 #ifdef BOOST_GEOMETRY_TEST_DEBUG
392 std::cout
<< "=================="
393 << std::endl
<< std::endl
;
397 template <typename T1
, typename T2
, typename T3
, typename T4
,
398 typename T5
, typename T6
, typename T7
, typename T8
>
399 static inline void apply(std::string
const& case_id
,
400 Geometry
const& geometry
,
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
,
405 double tolerance
= std::numeric_limits
<double>::epsilon())
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,
413 template <typename T1
, typename T2
, typename T3
, typename T4
>
414 static inline void apply(std::string
const& case_id
,
415 Geometry
const& geometry
,
416 T1
const& lon_min
, T2
const& lat_min
, double height_min
,
417 T3
const& lon_max
, T4
const& lat_max
, double height_max
,
418 double tolerance
= std::numeric_limits
<double>::epsilon())
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
,
428 template <typename T1
, typename T2
, typename T3
, typename T4
>
429 static inline void apply(std::string
const& case_id
,
430 Geometry
const& geometry
,
431 T1
const& lon_min
, T2
const& lat_min
,
432 T3
const& lon_max
, T4
const& lat_max
,
433 double tolerance
= std::numeric_limits
<double>::epsilon())
435 apply(case_id
, geometry
,
436 lon_min
, lat_min
, 0, lon_max
, lat_max
, 0,
442 // special tester for rings
443 template <typename Geometry
, typename MBR
, bool TestReverse
>
444 struct test_envelope_on_sphere_or_spheroid
<Geometry
, MBR
, bg::ring_tag
, TestReverse
>
446 template <typename T1
, typename T2
, typename T3
, typename T4
,
447 typename T5
, typename T6
, typename T7
, typename T8
>
448 static inline void apply(std::string
const& case_id
,
449 Geometry
const& geometry
,
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())
456 envelope_on_spheroid_basic_tester
459 >::apply(case_id
, geometry
,
460 lon_min1
, lat_min1
, 0,
461 lon_max1
, lat_max1
, 0,
464 std::string ccw_case_id
= case_id
+ "-2ccw";
468 typename
bg::point_type
<Geometry
>::type
, false
470 bg::convert(geometry
, ccw_ring
);
472 envelope_on_spheroid_basic_tester
475 >::apply(ccw_case_id
, ccw_ring
,
476 lon_min2
, lat_min2
, 0,
477 lon_max2
, lat_max2
, 0,
480 #ifdef BOOST_GEOMETRY_TEST_DEBUG
481 std::cout
<< "=================="
482 << std::endl
<< std::endl
;
486 template <typename T1
, typename T2
, typename T3
, typename T4
>
487 static inline void apply(std::string
const& case_id
,
488 Geometry
const& geometry
,
489 T1
const& lon_min
, T2
const& lat_min
,
490 T3
const& lon_max
, T4
const& lat_max
,
491 double tolerance
= std::numeric_limits
<double>::epsilon())
493 apply(case_id
, geometry
,
494 lon_min
, lat_min
, lon_max
, lat_max
,
495 lon_min
, lat_min
, lon_max
, lat_max
,
501 template <typename CoordinateSystem
, typename Geometry
>
502 void test_empty_geometry(std::string
const& case_id
, std::string
const& wkt
)
504 std::size_t const dim
= bg::dimension
<Geometry
>::value
;
506 typedef bg::model::point
<double, dim
, CoordinateSystem
> point_type
;
507 typedef bg::model::box
<point_type
> B
;
508 typedef test_envelope_on_sphere_or_spheroid
<Geometry
, B
> tester
;
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();
514 if (BOOST_GEOMETRY_CONDITION(dim
== 2))
516 tester::apply(case_id
,
517 from_wkt
<Geometry
>(wkt
),
518 high_val
, high_val
, low_val
, low_val
);
522 tester::apply(case_id
,
523 from_wkt
<Geometry
>(wkt
),
524 high_val
, high_val
, high_val
, low_val
, low_val
, low_val
);
529 template <typename CoordinateSystem
>
530 void test_envelope_point()
532 typedef bg::model::point
<double, 2, CoordinateSystem
> point_type
;
533 typedef point_type G
;
534 typedef bg::model::box
<point_type
> B
;
535 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
538 from_wkt
<G
>("POINT(10 10)"),
542 from_wkt
<G
>("POINT(370 10)"),
545 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
547 from_wkt
<G
>("POINT(370 -350)"),
551 // north and south poles
553 from_wkt
<G
>("POINT(0 90)"),
556 tester::apply("p04a",
557 from_wkt
<G
>("POINT(10 90)"),
560 tester::apply("p04b",
561 from_wkt
<G
>("POINT(270 90)"),
564 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
565 tester::apply("p04c",
566 from_wkt
<G
>("POINT(270 450)"),
570 tester::apply("p04d",
571 from_wkt
<G
>("POINT(190 90)"),
574 tester::apply("p04e",
575 from_wkt
<G
>("POINT(-100 90)"),
579 from_wkt
<G
>("POINT(0 -90)"),
582 tester::apply("p05a",
583 from_wkt
<G
>("POINT(10 -90)"),
586 tester::apply("p05b",
587 from_wkt
<G
>("POINT(270 -90)"),
590 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
591 tester::apply("p05c",
592 from_wkt
<G
>("POINT(270 -450)"),
596 tester::apply("p05d",
597 from_wkt
<G
>("POINT(190 -90)"),
600 tester::apply("p05e",
601 from_wkt
<G
>("POINT(-100 -90)"),
604 tester::apply("p05f",
605 from_wkt
<G
>("POINT(-100 -90)"),
609 BOOST_AUTO_TEST_CASE( envelope_point
)
611 test_envelope_point
<bg::cs::spherical_equatorial
<bg::degree
> >();
612 test_envelope_point
<bg::cs::geographic
<bg::degree
> >();
616 template <typename CoordinateSystem
>
617 void test_envelope_point_with_height()
619 typedef bg::model::point
<double, 3, CoordinateSystem
> point_type
;
620 typedef point_type G
;
621 typedef bg::model::box
<point_type
> B
;
622 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
624 tester::apply("ph01",
625 from_wkt
<G
>("POINT(10 10 1256)"),
626 10, 10, 1256, 10, 10, 1256);
629 BOOST_AUTO_TEST_CASE( envelope_point_with_height
)
631 test_envelope_point_with_height
633 bg::cs::spherical_equatorial
<bg::degree
>
635 test_envelope_point_with_height
<bg::cs::geographic
<bg::degree
> >();
639 BOOST_AUTO_TEST_CASE( envelope_segment_sphere
)
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
;
645 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
647 double const eps
= std::numeric_limits
<double>::epsilon();
650 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
654 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
655 10, 10, 40, 10.345270046149988);
658 from_wkt<G>("SEGMENT(1 2,70 1)"),
661 tester::apply("s02a",
662 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
663 10, 10, 40, 10.34527004614999);
666 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
667 160, 10, 190, 10.34527004614999);
669 tester::apply("s03a",
670 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
671 160, 10, 190, 10.34527004614999);
673 tester::apply("s03b",
674 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
675 160, -10.34527004614999, 190, -10);
678 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
681 tester::apply("s04a",
682 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
685 // segment ending at the north pole
687 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
690 // segment starting at the north pole
691 tester::apply("s05a",
692 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
695 // segment ending at the north pole
697 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
700 // segment starting at the north pole
701 tester::apply("s06a",
702 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
705 // segment ending at the north pole
707 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
710 // segment passing through the south pole
712 from_wkt
<G
>("SEGMENT(-170 -45,10 -30)"),
716 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
717 1, -85.28884376852969, 179, 30,
720 tester::apply("s09a",
721 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
722 2, -87.63659983704832, 181, 30);
726 from_wkt
<G
>("SEGMENT(0 -45,181 30)"),
727 -179, -87.636599837048323, 0, 30,
731 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
732 -100, 30, 20, 57.93195594009233);
734 tester::apply("s11a",
735 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
736 -100, 30, 20, 57.931955940092337);
738 // segment degenerating to the north pole
740 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
743 // segment degenerating to the south pole
745 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
749 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
750 10, 20, 20, 30);//48.87458730907602);
753 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
754 50, 45, 185, 69.05897952775615);
756 // segment that lies on the equator
758 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
761 // segment that lies on the equator
762 tester::apply("s16a",
763 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
766 // segment that lies on the equator and touches antimeridian
767 tester::apply("s16b",
768 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
771 // segment that lies on the equator and crosses antimeridian
772 tester::apply("s16c",
773 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
777 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
780 tester::apply("s17-r",
781 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
785 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
788 tester::apply("s18-r",
789 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
792 // segment connecting the north and south pole
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
798 from_wkt
<G
>("SEGMENT(10 90,20 -90)"),
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);
806 double const heps
= eps
/ 2;
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
)),
814 tester::apply("s103",
815 G(P(1, 1), P(1-heps
, 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)),
825 BOOST_AUTO_TEST_CASE( envelope_segment_spherical_polar
)
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
;
834 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
838 from_wkt
<G
>("SEGMENT(10 80,40 80)"),
839 10, 90 - 10.345270046149988, 40, 80);
842 from_wkt
<G
>("SEGMENT(160 80,-170 80)"),
843 160, 90 - 10.34527004614999, 190, 80);
845 // segment ending at the north pole
847 from_wkt
<G
>("SEGMENT(40 45,80 0)"),
852 BOOST_AUTO_TEST_CASE( envelope_segment_spheroid
)
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
;
860 double const eps
= std::numeric_limits
<double>::epsilon();
863 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
867 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
868 10, 10, 40, 10.347587605817942);
870 tester::apply("s02a",
871 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
872 10, 10, 40, 10.347587605817942);
875 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
876 160, 10, 190, 10.347587605817942);
878 tester::apply("s03a",
879 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
880 160, 10, 190, 10.347587605817942);
882 tester::apply("s03b",
883 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
884 160, -10.347587605817942, 190, -10);
887 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
890 tester::apply("s04a",
891 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
894 // segment ending at the north pole
896 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
899 // segment starting at the north pole
900 tester::apply("s05a",
901 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
904 // segment ending at the north pole
906 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
909 // segment starting at the north pole
910 tester::apply("s06a",
911 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
914 // segment ending at the north pole
916 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
919 // segment passing through the south pole
921 from_wkt
<G
>("SEGMENT(-170 -45,10 -30)"),
925 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
926 1, rng(-85.392785243526134, -85.392785243525253), 179, 30);
928 tester::apply("s09a",
929 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
930 2, rng(-87.689300911353811, -87.689300911353371), 181, 30);
934 from_wkt
<G
>("SEGMENT(0 -45,181 30)"),
935 -179, rng(-87.689300911353797, -87.689300911353385), 0, 30);
938 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
939 -100, 30, 20, rng(57.990810958016482, 57.990810958016965));
941 tester::apply("s11a",
942 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
943 -100, 30, 20, rng(57.990810958016453, 57.990810958016965));
945 // segment degenerating to the north pole
947 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
950 // segment degenerating to the south pole
952 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
956 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
957 10, 20, 20, 30);//48.87458730907602);
960 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
961 50, 45, 185, rng(69.098479073902851, 69.098479073903178));
963 // segment that lies on the equator
965 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
968 // segment that lies on the equator
969 tester::apply("s16a",
970 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
973 // segment that lies on the equator and touches antimeridian
974 tester::apply("s16b",
975 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
978 // segment that lies on the equator and crosses antimeridian
979 tester::apply("s16c",
980 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
984 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
987 tester::apply("s17-r",
988 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
992 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
995 tester::apply("s18-r",
996 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
999 // segment connecting the north and south pole
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)"),
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);
1013 double const heps
= eps
/ 2;
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
)),
1021 tester::apply("s103",
1022 G(P(1, 1), P(1-heps
, 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)),
1032 BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_thomas
)
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
1043 test_reverse_geometry
<G
>::value
,
1044 bg::strategy::thomas
1047 tester::apply("s01",
1048 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
1051 tester::apply("s02",
1052 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
1053 10, 10, 40, 10.347587605817942);
1055 tester::apply("s02a",
1056 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
1057 10, 10, 40, 10.347587605817942);
1059 tester::apply("s03",
1060 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
1061 160, 10, 190, 10.347587605817942);
1063 tester::apply("s03a",
1064 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
1065 160, 10, 190, 10.347587605817942);
1067 tester::apply("s03b",
1068 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
1069 160, -10.347587605817942, 190, -10);
1071 tester::apply("s04",
1072 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
1075 tester::apply("s04a",
1076 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
1079 // segment ending at the north pole
1080 tester::apply("s05",
1081 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
1084 // segment starting at the north pole
1085 tester::apply("s05a",
1086 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
1089 // segment ending at the north pole
1090 tester::apply("s06",
1091 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
1094 // segment starting at the north pole
1095 tester::apply("s06a",
1096 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
1099 // segment ending at the north pole
1100 tester::apply("s07",
1101 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
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);
1109 tester::apply("s09",
1110 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
1111 1, rng(-85.392785243526134, -85.392785243525253), 179, 30);
1113 tester::apply("s09a",
1114 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
1115 2, rng(-87.689300911353811, -87.689300911353371), 181, 30);
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);
1122 tester::apply("s11",
1123 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
1124 -100, 30, 20, rng(57.990810958016482, 57.990810958016965));
1126 tester::apply("s11a",
1127 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
1128 -100, 30, 20, rng(57.990810958016453, 57.990810958016965));
1130 // segment degenerating to the north pole
1131 tester::apply("s12",
1132 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
1135 // segment degenerating to the south pole
1136 tester::apply("s13",
1137 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
1140 tester::apply("s14",
1141 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
1142 10, 20, 20, 30);//48.87458730907602);
1144 tester::apply("s15",
1145 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
1146 50, 45, 185, rng(69.098479073902851, 69.098479073903178));
1148 // segment that lies on the equator
1149 tester::apply("s16",
1150 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
1153 // segment that lies on the equator
1154 tester::apply("s16a",
1155 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
1158 // segment that lies on the equator and touches antimeridian
1159 tester::apply("s16b",
1160 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
1163 // segment that lies on the equator and crosses antimeridian
1164 tester::apply("s16c",
1165 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
1168 tester::apply("s17",
1169 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
1172 tester::apply("s17-r",
1173 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
1176 tester::apply("s18",
1177 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
1180 tester::apply("s18-r",
1181 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
1186 BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_andoyer
)
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
1197 test_reverse_geometry
<G
>::value
,
1198 bg::strategy::andoyer
1201 tester::apply("s01",
1202 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
1205 tester::apply("s02",
1206 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
1207 10, 10, 40, 10.34758709960203);
1209 tester::apply("s02a",
1210 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
1211 10, 10, 40, 10.34758709960203);
1213 tester::apply("s03",
1214 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
1215 160, 10, 190, 10.34758709960203);
1217 tester::apply("s03a",
1218 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
1219 160, 10, 190, 10.34758709960203);
1221 tester::apply("s03b",
1222 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
1223 160, -10.34758709960203, 190, -10);
1225 tester::apply("s04",
1226 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
1229 tester::apply("s04a",
1230 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
1233 // segment ending at the north pole
1234 tester::apply("s05",
1235 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
1238 // segment starting at the north pole
1239 tester::apply("s05a",
1240 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
1243 // segment ending at the north pole
1244 tester::apply("s06",
1245 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
1248 // segment starting at the north pole
1249 tester::apply("s06a",
1250 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
1253 // segment ending at the north pole
1254 tester::apply("s07",
1255 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
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);
1263 tester::apply("s09",
1264 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
1265 1, rng(-85.394745211091248, -85.394745211090353), 179, 30);
1267 tester::apply("s09a",
1268 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
1269 2, rng(-87.690317839849726, -87.690317839849271), 181, 30);
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);
1276 tester::apply("s11",
1277 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
1278 -100, 30, 20, rng(57.990742552279649, 57.990742552280153));
1280 tester::apply("s11a",
1281 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
1282 -100, 30, 20, rng(57.99074255227962, 57.990742552280118));
1284 // segment degenerating to the north pole
1285 tester::apply("s12",
1286 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
1289 // segment degenerating to the south pole
1290 tester::apply("s13",
1291 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
1294 tester::apply("s14",
1295 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
1296 10, 20, 20, 30);//48.87458730907602);
1298 tester::apply("s15",
1299 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
1300 50, 45, 185, rng(69.098446893408124, 69.09844689340845));
1302 // segment that lies on the equator
1303 tester::apply("s16",
1304 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
1307 // segment that lies on the equator
1308 tester::apply("s16a",
1309 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
1312 // segment that lies on the equator and touches antimeridian
1313 tester::apply("s16b",
1314 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
1317 // segment that lies on the equator and crosses antimeridian
1318 tester::apply("s16c",
1319 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
1322 tester::apply("s17",
1323 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
1326 tester::apply("s17-r",
1327 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
1330 tester::apply("s18",
1331 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
1334 tester::apply("s18-r",
1335 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
1338 // segments intersecting pole
1339 tester::apply("s19",
1340 from_wkt
<G
>("SEGMENT(0 0, 180 0)"),
1342 tester::apply("s20",
1343 from_wkt
<G
>("SEGMENT(0 0, -180 0)"),
1345 tester::apply("s21",
1346 from_wkt
<G
>("SEGMENT(0 1, 180 1)"),
1348 std::numeric_limits
<double>::epsilon() * 10);
1349 tester::apply("s22",
1350 from_wkt
<G
>("SEGMENT(0 -1, 180 -1)"),
1352 std::numeric_limits
<double>::epsilon() * 10);
1356 BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_strategy_vincenty
)
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
1367 test_reverse_geometry
<G
>::value
,
1368 bg::strategy::vincenty
1371 tester::apply("s01",
1372 from_wkt
<G
>("SEGMENT(10 10,40 40)"),
1375 tester::apply("s02",
1376 from_wkt
<G
>("SEGMENT(10 10,40 10)"),
1377 10, 10, 40, rng(10.347587628821937, 10.347587628821941));
1379 tester::apply("s02a",
1380 from_wkt
<G
>("SEGMENT(40 10,10 10)"),
1381 10, 10, 40, rng(10.347587628821937, 10.347587628821941));
1383 tester::apply("s03",
1384 from_wkt
<G
>("SEGMENT(160 10,-170 10)"),
1385 160, 10, 190, rng(10.347587628821937, 10.347587628821941));
1387 tester::apply("s03a",
1388 from_wkt
<G
>("SEGMENT(-170 10,160 10)"),
1389 160, 10, 190, rng(10.347587628821937, 10.347587628821941));
1391 tester::apply("s03b",
1392 from_wkt
<G
>("SEGMENT(-170 -10,160 -10)"),
1393 160, rng(-10.347587628821941, -10.347587628821937), 190, -10);
1395 tester::apply("s04",
1396 from_wkt
<G
>("SEGMENT(-40 45,140 60)"),
1399 tester::apply("s04a",
1400 from_wkt
<G
>("SEGMENT(-40 45,140 25)"),
1403 // segment ending at the north pole
1404 tester::apply("s05",
1405 from_wkt
<G
>("SEGMENT(40 45,80 90)"),
1408 // segment starting at the north pole
1409 tester::apply("s05a",
1410 from_wkt
<G
>("SEGMENT(80 90,40 45)"),
1413 // segment ending at the north pole
1414 tester::apply("s06",
1415 from_wkt
<G
>("SEGMENT(-40 45,80 90)"),
1418 // segment starting at the north pole
1419 tester::apply("s06a",
1420 from_wkt
<G
>("SEGMENT(70 90,-40 45)"),
1423 // segment ending at the north pole
1424 tester::apply("s07",
1425 from_wkt
<G
>("SEGMENT(40 -45,80 90)"),
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);
1433 tester::apply("s09",
1434 from_wkt
<G
>("SEGMENT(1 -45,179 30)"),
1435 1, rng(-85.392840929577218, -85.392840929576352), 179, 30);
1437 tester::apply("s09a",
1438 from_wkt
<G
>("SEGMENT(2 -45,181 30)"),
1439 2, rng(-87.689330275867817, -87.689330275867405), 181, 30);
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);
1446 tester::apply("s11",
1447 from_wkt
<G
>("SEGMENT(260 30,20 45)"),
1448 -100, 30, 20, rng(57.990810647056549, 57.990810647057032));
1450 tester::apply("s11a",
1451 from_wkt
<G
>("SEGMENT(260 45,20 30)"),
1452 -100, 30, 20, rng(57.990810647056541, 57.990810647057032));
1454 // segment degenerating to the north pole
1455 tester::apply("s12",
1456 from_wkt
<G
>("SEGMENT(10 90,20 90)"),
1459 // segment degenerating to the south pole
1460 tester::apply("s13",
1461 from_wkt
<G
>("SEGMENT(10 -90,20 -90)"),
1464 tester::apply("s14",
1465 from_wkt
<G
>("SEGMENT(20 20,10 30)"),
1466 10, 20, 20, 30);//48.87458730907602);
1468 tester::apply("s15",
1469 from_wkt
<G
>("SEGMENT(50 45,185 45)"),
1470 50, 45, 185, rng(69.098479136978156, 69.098479136978497));
1472 // segment that lies on the equator
1473 tester::apply("s16",
1474 from_wkt
<G
>("SEGMENT(0 0,50 0)"),
1477 // segment that lies on the equator
1478 tester::apply("s16a",
1479 from_wkt
<G
>("SEGMENT(-50 0,50 0)"),
1482 // segment that lies on the equator and touches antimeridian
1483 tester::apply("s16b",
1484 from_wkt
<G
>("SEGMENT(50 0,180 0)"),
1487 // segment that lies on the equator and crosses antimeridian
1488 tester::apply("s16c",
1489 from_wkt
<G
>("SEGMENT(-170 0,160 0)"),
1492 tester::apply("s17",
1493 from_wkt
<G
>("SEGMENT(140 10, -140 80)"),
1496 tester::apply("s17-r",
1497 from_wkt
<G
>("SEGMENT(-140 80, 140 10)"),
1500 tester::apply("s18",
1501 from_wkt
<G
>("SEGMENT(20 10, 100 80)"),
1504 tester::apply("s18-r",
1505 from_wkt
<G
>("SEGMENT(100 80, 20 10)"),
1510 BOOST_AUTO_TEST_CASE( envelope_segment_sphere_with_height
)
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
;
1518 tester::apply("sh01",
1519 from_wkt
<G
>("SEGMENT(10 10 567,40 40 1356)"),
1520 10, 10, 567, 40, 40, 1356);
1522 tester::apply("sh02",
1523 from_wkt
<G
>("SEGMENT(10 10 1356,40 40 567)"),
1524 10, 10, 567, 40, 40, 1356);
1527 BOOST_AUTO_TEST_CASE( envelope_segment_spheroid_with_height
)
1529 typedef bg::cs::geographic
<bg::degree
> coordinate_system_type
;
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
;
1533 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1535 tester::apply("sh01",
1536 from_wkt
<G
>("SEGMENT(10 10 567,40 40 1356)"),
1537 10, 10, 567, 40, 40, 1356);
1539 tester::apply("sh02",
1540 from_wkt
<G
>("SEGMENT(10 10 1356,40 40 567)"),
1541 10, 10, 567, 40, 40, 1356);
1544 template <typename CoordinateSystem
>
1545 void test_envelope_multipoint()
1547 typedef bg::model::point
<double, 2, CoordinateSystem
> P
;
1548 typedef bg::model::multi_point
<P
> G
;
1549 typedef bg::model::box
<P
> B
;
1550 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1553 test_empty_geometry
<CoordinateSystem
, G
>("mp00", "MULTIPOINT()");
1555 tester::apply("mp01",
1556 from_wkt
<G
>("MULTIPOINT(0 0,10 10)"),
1559 tester::apply("mp02",
1560 from_wkt
<G
>("MULTIPOINT(0 10,10 0)"),
1563 tester::apply("mp03",
1564 from_wkt
<G
>("MULTIPOINT(-10 20,0 10,10 0)"),
1567 tester::apply("mp04",
1568 from_wkt
<G
>("MULTIPOINT(-10 20,0 10,10 -15)"),
1571 tester::apply("mp05",
1572 from_wkt
<G
>("MULTIPOINT(-85 10,85 -20)"),
1575 tester::apply("mp06",
1576 from_wkt
<G
>("MULTIPOINT(-95 10,85 -20)"),
1579 tester::apply("mp07",
1580 from_wkt
<G
>("MULTIPOINT(-96 10,85 -20)"),
1581 85, -20, -96+360, 10);
1583 tester::apply("mp08",
1584 from_wkt
<G
>("MULTIPOINT(175 15,-175 -20)"),
1585 175, -20, -175+360, 15);
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);
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);
1597 tester::apply("mp10",
1598 from_wkt
<G
>("MULTIPOINT(10 10,20 90,30 -90)"),
1602 tester::apply("mp11",
1603 from_wkt
<G
>("MULTIPOINT(179 90,-179 -90,10 10)"),
1606 tester::apply("mp11a",
1607 from_wkt
<G
>("MULTIPOINT(10 10,179 90,-179 -90)"),
1611 tester::apply("mp11b",
1612 from_wkt
<G
>("MULTIPOINT(179 90,-179 -90,-90 0)"),
1615 tester::apply("mp11c",
1616 from_wkt
<G
>("MULTIPOINT(-90 0,179 90,-179 -90,-90 0)"),
1619 tester::apply("mp12",
1620 from_wkt
<G
>("MULTIPOINT(170 -30,175 60,-178 10)"),
1621 170, -30, -178+360, 60);
1623 tester::apply("mp13",
1624 from_wkt
<G
>("MULTIPOINT(-170 -30,-175 40,178 50)"),
1625 178, -30, -170+360, 50);
1627 tester::apply("mp13a",
1628 from_wkt
<G
>("MULTIPOINT(-170 -30,178 50)"),
1629 178, -30, -170+360, 50);
1631 tester::apply("mp13b",
1632 from_wkt
<G
>("MULTIPOINT(-170 -30,178 50,-175 40)"),
1633 178, -30, -170+360, 50);
1635 tester::apply("mp15",
1636 from_wkt
<G
>("MULTIPOINT(10 -20)"),
1639 tester::apply("mp16",
1640 from_wkt
<G
>("MULTIPOINT(0 90,10 90)"),
1643 tester::apply("mp17",
1644 from_wkt
<G
>("MULTIPOINT(179 80,-179 -80,10 10)"),
1645 10, -80, -179+360, 80);
1647 tester::apply("mp17a",
1648 from_wkt
<G
>("MULTIPOINT(10 10,179 80,-179 -80)"),
1649 10, -80, -179+360, 80);
1651 tester::apply("mp17b",
1652 from_wkt
<G
>("MULTIPOINT(179 80,-179 -80,-90 0)"),
1653 179, -80, -90+360, 80);
1655 tester::apply("mp17c",
1656 from_wkt
<G
>("MULTIPOINT(-90 0,179 80,-179 -80,-90 0)"),
1657 179, -80, -90+360, 80);
1659 tester::apply("mp18",
1660 from_wkt
<G
>("MULTIPOINT(-170 45,20 25,40 40)"),
1663 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1664 tester::apply("mp18a",
1665 from_wkt
<G
>("MULTIPOINT(10 135,20 25,40 40)"),
1669 tester::apply("mp19",
1670 from_wkt
<G
>("MULTIPOINT(350 45,20 25,40 40)"),
1673 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1674 tester::apply("mp19a",
1675 from_wkt
<G
>("MULTIPOINT(170 135,20 25,40 40)"),
1679 double eps
= std::numeric_limits
<double>::epsilon();
1680 double heps
= eps
/ 2;
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);
1689 BOOST_AUTO_TEST_CASE( envelope_multipoint
)
1691 test_envelope_multipoint
<bg::cs::spherical_equatorial
<bg::degree
> >();
1692 test_envelope_multipoint
<bg::cs::geographic
<bg::degree
> >();
1696 template <typename CoordinateSystem
>
1697 void test_envelope_multipoint_with_height()
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
;
1702 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1705 test_empty_geometry
<CoordinateSystem
, G
>("mph00", "MULTIPOINT()");
1707 tester::apply("mph01",
1708 from_wkt
<G
>("MULTIPOINT(0 0 567,10 10 1456)"),
1709 0, 0, 567, 10, 10, 1456);
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);
1716 BOOST_AUTO_TEST_CASE( envelope_multipoint_with_height
)
1718 test_envelope_multipoint_with_height
1720 bg::cs::spherical_equatorial
<bg::degree
>
1722 test_envelope_multipoint_with_height
<bg::cs::geographic
<bg::degree
> >();
1726 template <typename CoordinateSystem
>
1727 void test_envelope_box()
1729 typedef bg::model::point
<double, 2, CoordinateSystem
> P
;
1730 typedef bg::model::box
<P
> G
;
1731 typedef bg::model::box
<P
> B
;
1732 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1734 tester::apply("b01",
1735 from_wkt
<G
>("BOX(10 10,20 20)"),
1738 #ifdef BOOST_GEOMETRY_NORMALIZE_LATITUDE
1739 tester::apply("b02",
1740 from_wkt
<G
>("BOX(10 370,20 20)"),
1744 // box crosses anti-meridian
1745 tester::apply("b02a",
1746 from_wkt
<G
>("BOX(170 10,-170 20)"),
1749 tester::apply("b03",
1750 from_wkt
<G
>("BOX(-170 10,170 20)"),
1753 tester::apply("b04",
1754 from_wkt
<G
>("BOX(10 10,350 20)"),
1757 tester::apply("b04a",
1758 from_wkt
<G
>("BOX(10 10,-10 20)"),
1762 tester::apply("b05",
1763 from_wkt
<G
>("BOX(0 10,360 20)"),
1766 tester::apply("b05a",
1767 from_wkt
<G
>("BOX(0 10,0 20)"),
1770 // box is almost a band
1771 tester::apply("b06",
1772 from_wkt
<G
>("BOX(10 10,5 20)"),
1775 // initial box is a band that crosses itself
1776 tester::apply("b07",
1777 from_wkt
<G
>("BOX(0 10,540 20)"),
1780 // initial box is a band that crosses itself
1781 tester::apply("b08",
1782 from_wkt
<G
>("BOX(0 10,720 20)"),
1785 tester::apply("b09",
1786 from_wkt
<G
>("BOX(10 10,10 10)"),
1789 tester::apply("b09a",
1790 from_wkt
<G
>("BOX(370 10,370 10)"),
1793 // box contains north and south pole
1794 tester::apply("b10",
1795 from_wkt
<G
>("BOX(0 -90,0 90)"),
1798 // box contains north and south pole
1799 tester::apply("b10a",
1800 from_wkt
<G
>("BOX(10 -90,10 90)"),
1803 // box contains north and south pole
1804 tester::apply("b10b",
1805 from_wkt
<G
>("BOX(0 -90,10 90)"),
1808 // box contains north and south pole
1809 tester::apply("b11",
1810 from_wkt
<G
>("BOX(0 -90,180 90)"),
1813 // box contains north and south pole
1814 tester::apply("b11a",
1815 from_wkt
<G
>("BOX(10 -90,190 90)"),
1818 // box contains north and south pole
1819 tester::apply("b11b",
1820 from_wkt
<G
>("BOX(10 -90,110 90)"),
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);
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);
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);
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);
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);
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);
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);
1866 tester::apply("b13",
1867 from_wkt
<G
>("BOX(180 -10,-180 10)"),
1868 -180, -10, 180, 10);
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);
1876 tester::apply("b14",
1877 from_wkt
<G
>("BOX(0 10,30 90)"),
1880 tester::apply("b15",
1881 from_wkt
<G
>("BOX(179 10,178 70)"),
1884 // box contains north pole
1885 tester::apply("b16",
1886 from_wkt
<G
>("BOX(10 40,20 90)"),
1889 tester::apply("b16a",
1890 from_wkt
<G
>("BOX(170 40,-170 90)"),
1893 // box contains south pole
1894 tester::apply("b17",
1895 from_wkt
<G
>("BOX(10 -90,20 40)"),
1898 tester::apply("b17a",
1899 from_wkt
<G
>("BOX(150 -90,-150 40)"),
1902 // box degenerates to the north pole
1903 tester::apply("b98",
1904 from_wkt
<G
>("BOX(10 90,20 90)"),
1907 // box degenerates to the south pole
1908 tester::apply("b99",
1909 from_wkt
<G
>("BOX(10 -90,20 -90)"),
1912 double eps
= std::numeric_limits
<double>::epsilon();
1913 double heps
= eps
/ 2;
1915 tester::apply("b100", G(P(1-heps
, 1-heps
), P(1, 1)), 1-heps
, 1-heps
, 1, 1);
1918 template <typename CoordinateSystem
>
1919 void test_envelope_box_polar()
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
;
1926 tester::apply("b01",
1927 from_wkt
<G
>("BOX(10 10,20 20)"),
1930 tester::apply("b02a",
1931 from_wkt
<G
>("BOX(170 10,-170 20)"),
1934 tester::apply("b10b",
1935 from_wkt
<G
>("BOX(0 0,10 180)"),
1938 tester::apply("b16a",
1939 from_wkt
<G
>("BOX(170 40,-170 180)"),
1943 BOOST_AUTO_TEST_CASE( envelope_box
)
1945 test_envelope_box
<bg::cs::spherical_equatorial
<bg::degree
> >();
1946 test_envelope_box
<bg::cs::geographic
<bg::degree
> >();
1947 test_envelope_box_polar
<bg::cs::spherical
<bg::degree
> >();
1951 template <typename CoordinateSystem
>
1952 void test_envelope_box_with_height()
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
;
1958 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1960 tester::apply("bh01",
1961 from_wkt
<G
>("BOX(10 10 567,20 20 2834)"),
1962 10, 10, 567, 20, 20, 2834);
1964 tester::apply("bh02",
1965 from_wkt
<G
>("BOX(10 10 567,20 20 567)"),
1966 10, 10, 567, 20, 20, 567);
1968 tester::apply("bh03",
1969 from_wkt
<G
>("BOX(0 10 567,170 90 1567)"),
1970 0, 10, 567, 170, 90, 1567);
1973 BOOST_AUTO_TEST_CASE( envelope_box_with_height
)
1975 test_envelope_box_with_height
<bg::cs::spherical_equatorial
<bg::degree
> >();
1976 test_envelope_box_with_height
<bg::cs::geographic
<bg::degree
> >();
1980 BOOST_AUTO_TEST_CASE( envelope_sphere_linestring
)
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
;
1986 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
1989 test_empty_geometry
<coordinate_system_type
, G
>("l00", "LINESTRING()");
1991 tester::apply("l01",
1992 from_wkt
<G
>("LINESTRING(10 15)"),
1995 tester::apply("l01a",
1996 from_wkt
<G
>("LINESTRING(370 15)"),
1999 tester::apply("l01b",
2000 from_wkt
<G
>("LINESTRING(370 90)"),
2003 tester::apply("l02",
2004 from_wkt
<G
>("LINESTRING(10 10,20 20,10 30)"),
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)"),
2010 -180, 0, 180, 33.587539971516854,
2011 4.0 * std::numeric_limits
<double>::epsilon());
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)"),
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)"),
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)"),
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)"),
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)"),
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)"),
2043 // linestring that crosses the antimeridian
2044 tester::apply("l06",
2045 from_wkt
<G
>("LINESTRING(-160 85,-170 80,170 40,160 80)"),
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);
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)"),
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)"),
2063 // linestring with duplicate points
2064 tester::apply("l09",
2065 from_wkt
<G
>("LINESTRING(-40 20,-40 20,-140 85,-10 5,-10 5)"),
2066 -140, 5, -10, 86.184540574427757);
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);
2073 // linestring that lies on the equator
2074 tester::apply("l10",
2075 from_wkt
<G
>("LINESTRING(0 0,50 0)"),
2078 // linestring that lies on the equator
2079 tester::apply("l10a",
2080 from_wkt
<G
>("LINESTRING(-50 0,50 0)"),
2083 // linestring that lies on the equator and touches antimeridian
2084 tester::apply("l10b",
2085 from_wkt
<G
>("LINESTRING(50 0,180 0)"),
2088 // linestring that lies on the equator and crosses antimeridian
2089 tester::apply("l10c",
2090 from_wkt
<G
>("LINESTRING(-170 0,160 0)"),
2093 double eps
= std::numeric_limits
<double>::epsilon();
2094 double heps
= eps
/ 2;
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);
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);
2113 BOOST_AUTO_TEST_CASE( envelope_spheroid_linestring
)
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
;
2122 test_empty_geometry
<coordinate_system_type
, G
>("l00", "LINESTRING()");
2124 tester::apply("l01",
2125 from_wkt
<G
>("LINESTRING(10 15)"),
2128 tester::apply("l01a",
2129 from_wkt
<G
>("LINESTRING(370 15)"),
2132 tester::apply("l01b",
2133 from_wkt
<G
>("LINESTRING(370 90)"),
2136 tester::apply("l02",
2137 from_wkt
<G
>("LINESTRING(10 10,20 20,10 30)"),
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));
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)"),
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)"),
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)"),
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)"),
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)"),
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)"),
2175 // linestring that crosses the antimeridian
2176 tester::apply("l06",
2177 from_wkt
<G
>("LINESTRING(-160 85,-170 80,170 40,160 80)"),
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);
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)"),
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)"),
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);
2200 // linestring with duplicate points
2201 tester::apply("l09a",
2202 from_wkt
<G
>("LINESTRING(-40 20,320 20,-140 85,-10 5,350 5)"),
2203 -140, 5, -10, 86.18564770636192);
2205 // linestring that lies on the equator
2206 tester::apply("l10",
2207 from_wkt
<G
>("LINESTRING(0 0,50 0)"),
2210 // linestring that lies on the equator
2211 tester::apply("l10a",
2212 from_wkt
<G
>("LINESTRING(-50 0,50 0)"),
2215 // linestring that lies on the equator and touches antimeridian
2216 tester::apply("l10b",
2217 from_wkt
<G
>("LINESTRING(50 0,180 0)"),
2220 // linestring that lies on the equator and crosses antimeridian
2221 tester::apply("l10c",
2222 from_wkt
<G
>("LINESTRING(-170 0,160 0)"),
2225 double eps
= std::numeric_limits
<double>::epsilon();
2226 double heps
= eps
/ 2;
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);
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);
2246 BOOST_AUTO_TEST_CASE( envelope_linestring_sphere_with_height
)
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
;
2252 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
2255 test_empty_geometry
<coordinate_system_type
, G
>("lh00", "LINESTRING()");
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);
2262 BOOST_AUTO_TEST_CASE( envelope_linestring_spheroid_with_height
)
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
;
2271 test_empty_geometry
<coordinate_system_type
, G
>("lh00", "LINESTRING()");
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);
2278 BOOST_AUTO_TEST_CASE( envelope_sphere_multilinestring
)
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
;
2284 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
2286 // empty multilinestring
2287 test_empty_geometry
<coordinate_system_type
, G
>("ml00", "MULTILINESTRING()");
2289 // invalid multilinestring
2290 test_empty_geometry
<coordinate_system_type
, G
>("ml00a",
2291 "MULTILINESTRING(())");
2293 // invalid multilinestring
2294 test_empty_geometry
<coordinate_system_type
, G
>("ml00b",
2295 "MULTILINESTRING((),())");
2297 // invalid multilinestring
2298 tester::apply("ml00c",
2299 from_wkt
<G
>("MULTILINESTRING((10 15),(),())"),
2302 // invalid multilinestring
2303 tester::apply("ml00d",
2304 from_wkt
<G
>("MULTILINESTRING((),(10 15),())"),
2307 tester::apply("ml01",
2308 from_wkt
<G
>("MULTILINESTRING((10 15))"),
2311 #ifdef BOOST_GEOMETRY_TEST_FAILURES
2312 tester::apply("ml01a",
2313 from_wkt
<G
>("MULTILINESTRING((),(),(10 15),())"),
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))"),
2319 -180, 25, 180, 81.113793608034072);
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))"),
2323 -150, 25, 200, 81.113793608034072);
2325 tester::apply("ml04",
2326 from_wkt
<G
>("MULTILINESTRING((-150 40,-100 80),(10 35,100 80))"),
2327 -150, 35, 100, 80.07385383411011);
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);
2333 tester::apply("ml05",
2334 from_wkt
<G
>("MULTILINESTRING((-140 40,-100 80),(10 35,100 80))"),
2335 -140, 35, 100, 80.07385383411011);
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);
2342 BOOST_AUTO_TEST_CASE( envelope_spheroid_multilinestring
)
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
;
2350 // empty multilinestring
2351 test_empty_geometry
<coordinate_system_type
, G
>("ml00", "MULTILINESTRING()");
2353 // invalid multilinestring
2354 test_empty_geometry
<coordinate_system_type
, G
>("ml00a",
2355 "MULTILINESTRING(())");
2357 // invalid multilinestring
2358 test_empty_geometry
<coordinate_system_type
, G
>("ml00b",
2359 "MULTILINESTRING((),())");
2361 // invalid multilinestring
2362 tester::apply("ml00c",
2363 from_wkt
<G
>("MULTILINESTRING((10 15),(),())"),
2366 // invalid multilinestring
2367 tester::apply("ml00d",
2368 from_wkt
<G
>("MULTILINESTRING((),(10 15),())"),
2371 tester::apply("ml01",
2372 from_wkt
<G
>("MULTILINESTRING((10 15))"),
2375 #ifdef BOOST_GEOMETRY_TEST_FAILURES
2376 tester::apply("ml01a",
2377 from_wkt
<G
>("MULTILINESTRING((),(),(10 15),())"),
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);
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);
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));
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));
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));
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));
2407 BOOST_AUTO_TEST_CASE( envelope_multilinestring_sphere_with_height
)
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
;
2413 typedef test_envelope_on_sphere_or_spheroid
<G
, B
> tester
;
2415 tester::apply("mlh01",
2416 from_wkt
<G
>("MULTILINESTRING((10 15 1000))"),
2417 10, 15, 1000, 10, 15, 1000);
2419 #ifdef BOOST_GEOMETRY_TEST_FAILURES
2420 tester::apply("mlh01a",
2421 from_wkt
<G
>("MULTILINESTRING((),(),(10 15 1000),())"),
2422 10, 15, 1000, 10, 15, 1000);
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);
2430 BOOST_AUTO_TEST_CASE( envelope_multilinestring_spheroid_with_height
)
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
;
2438 tester::apply("mlh01",
2439 from_wkt
<G
>("MULTILINESTRING((10 15 1000))"),
2440 10, 15, 1000, 10, 15, 1000);
2442 #ifdef BOOST_GEOMETRY_TEST_FAILURES
2443 tester::apply("mlh01a",
2444 from_wkt
<G
>("MULTILINESTRING((),(),(10 15 1000),())"),
2445 10, 15, 1000, 10, 15, 1000);
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);
2453 //Test spherical polygons and rings (geographic should be similar)
2454 BOOST_AUTO_TEST_CASE( envelope_polygon
)
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
;
2462 typedef bg::model::ring
<point_type
> R
;
2463 typedef test_envelope_on_sphere_or_spheroid
<R
, B
> testerR
;
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));
2471 testerR::apply("r01",
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);
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);
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
2503 // right now implementation does not distinguish between ccw and cw rings
2504 BOOST_AUTO_TEST_CASE( envelope_cw_ring
)
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
;
2512 //double const eps = std::numeric_limits<double>::epsilon();
2514 tester::apply("r01cw",
2515 from_wkt
<G
>("POLYGON((0 10,0 45,50 10,0 10))"),
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);
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))"),
2527 // -180, -90, 180, 0);
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))"),
2533 // -180, 0, 180, 90);
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);
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);
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);
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))"),
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))"),
2562 // ring that crosses antimeridian multiple times but does not
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,
2569 // ring that crosses antimeridian multiple times but does not
2571 tester::apply("r07cw",
2572 from_wkt
<G
>("POLYGON((-140 10,140 10,180 80,-140 10))"),
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))"),
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);
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))"),
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))"),
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))"),
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);
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))"),
2611 // -180, -90, 180, 90);
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))"),
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);
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);
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);
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);
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);
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);
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);
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);
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))"),
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);
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))"),
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);
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))"),
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
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
2696 // ring that goes through both poles and its boundary forms
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
2702 // ring that goes through both poles and its boundary forms
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