]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/geometry/test/algorithms/envelope_expand/expand_on_spheroid.cpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / geometry / test / algorithms / envelope_expand / expand_on_spheroid.cpp
1 // Boost.Geometry (aka GGL, Generic Geometry Library)
2 // Unit Test
3
4 // Copyright (c) 2015, Oracle and/or its affiliates.
5
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7
8 // Licensed under the Boost Software License version 1.0.
9 // http://www.boost.org/users/license.html
10
11 #ifndef BOOST_TEST_MODULE
12 #define BOOST_TEST_MODULE test_expand_on_spheroid
13 #endif
14
15 #include <boost/test/included/unit_test.hpp>
16
17 #include <cstddef>
18
19 #include <iostream>
20 #include <string>
21
22 #include <geometry_test_common.hpp>
23 #include <from_wkt.hpp>
24
25 #include <boost/type_traits/is_same.hpp>
26
27 #include <boost/geometry/core/coordinate_dimension.hpp>
28 #include <boost/geometry/core/tag.hpp>
29 #include <boost/geometry/core/tags.hpp>
30
31 #include <boost/geometry/geometries/geometries.hpp>
32
33 #include <boost/geometry/views/detail/indexed_point_view.hpp>
34
35 #include <boost/geometry/util/condition.hpp>
36
37 #include <boost/geometry/io/dsv/write.hpp>
38 #include <boost/geometry/io/wkt/wkt.hpp>
39
40 #include <boost/geometry/algorithms/assign.hpp>
41 #include <boost/geometry/algorithms/envelope.hpp>
42 #include <boost/geometry/algorithms/expand.hpp>
43 #include <boost/geometry/algorithms/transform.hpp>
44
45 #include "test_envelope_expand_on_spheroid.hpp"
46
47
48 class test_expand_on_spheroid
49 {
50 private:
51 template
52 <
53 typename Geometry,
54 typename Tag = typename bg::tag<Geometry>::type
55 >
56 struct write_geometry
57 {
58 template <typename OutputStream>
59 static inline OutputStream& apply(OutputStream& os,
60 Geometry const& geometry)
61 {
62 os << bg::wkt(geometry);
63 return os;
64 }
65 };
66
67 template <typename Segment>
68 struct write_geometry<Segment, bg::segment_tag>
69 {
70 template <typename OutputStream>
71 static inline OutputStream& apply(OutputStream& os,
72 Segment const& segment)
73 {
74 os << "SEGMENT" << bg::dsv(segment);
75 return os;
76 }
77 };
78
79 template <typename Box>
80 struct write_geometry<Box, bg::box_tag>
81 {
82 template <typename OutputStream>
83 static inline OutputStream& apply(OutputStream& os,
84 Box const& box)
85 {
86 os << "BOX" << bg::dsv(box);
87 return os;
88 }
89 };
90
91 template <typename Box, typename Geometry>
92 static inline void check_message(bool same_boxes,
93 std::string const& case_id,
94 std::string const& units_str,
95 Box const& box,
96 Geometry const& geometry,
97 bool expected_are_different,
98 Box const& expected1,
99 Box const& expected2,
100 Box const& detected)
101 {
102 std::ostringstream stream;
103 stream << "case ID: " << case_id << ", "
104 << "MBR units: " << units_str << "; "
105 << "input box: BOX" << bg::dsv(box) << ", "
106 << "geometry: ";
107
108 write_geometry<Geometry>::apply(stream, geometry);
109
110 stream << std::setprecision(17);
111
112 stream << "; " << "expected: " << bg::dsv(expected1);
113
114 if (expected_are_different)
115 {
116 stream << " or: " << bg::dsv(expected2);
117 }
118 stream << ", " << "detected: " << bg::dsv(detected);
119
120 BOOST_CHECK_MESSAGE(same_boxes, stream.str());
121 }
122
123
124 template <bool Reverse = false, typename = void>
125 struct basic_tester
126 {
127 template <typename Box, typename Geometry>
128 static inline void base_test(std::string const& case_id,
129 Box const& box,
130 Geometry const& geometry,
131 double lon_min1, double lat_min1,
132 double height_min1,
133 double lon_max1, double lat_max1,
134 double height_max1,
135 double lon_min2, double lat_min2,
136 double height_min2,
137 double lon_max2, double lat_max2,
138 double height_max2,
139 double tolerance)
140 {
141 typedef typename bg::coordinate_system
142 <
143 Box
144 >::type::units box_units_type;
145
146 std::string const units_str = units2string<box_units_type>();
147
148 Box detected;
149 bg::convert(box, detected);
150 bg::expand(detected, geometry);
151
152 bool expected_are_different =
153 (lon_min1 != lon_min2) || (lat_min1 != lat_min2)
154 || (lon_max1 != lon_max2) || (lat_max1 != lat_max2);
155
156 Box expected1;
157 initialize_box<Box>::apply(expected1,
158 lon_min1, lat_min1, height_min1,
159 lon_max1, lat_max1, height_max1);
160
161 Box expected2;
162 initialize_box<Box>::apply(expected2,
163 lon_min2, lat_min2, height_min2,
164 lon_max2, lat_max2, height_max2);
165
166 #ifdef BOOST_GEOMETRY_TEST_DEBUG
167 std::cout << "input box: BOX" << bg::dsv(box) << std::endl;
168
169 std::cout << "geometry: ";
170 write_geometry<Geometry>::apply(std::cout, geometry);
171
172 std::cout << std::endl
173 << "MBR units: " << units_str
174 << std::endl
175 << "expected: " << bg::dsv(expected1);
176
177 if (expected_are_different)
178 {
179 std::cout << " or: " << bg::dsv(expected2);
180 }
181
182 std::cout << std::endl
183 << "detected: " << bg::dsv(detected)
184 << std::endl << std::endl;
185 #endif
186 bool same_boxes
187 = box_equals<Box>::apply(detected, expected1, tolerance);
188
189 if (expected_are_different)
190 {
191 same_boxes = same_boxes
192 || box_equals<Box>::apply(detected, expected2, tolerance);
193 }
194
195 check_message(same_boxes, case_id, units_str,
196 box, geometry, expected_are_different,
197 expected1, expected2, detected);
198 }
199
200 template <typename Box, typename Geometry>
201 static inline void apply(std::string const& case_id,
202 Box const& box,
203 Geometry const& geometry,
204 double lon_min1, double lat_min1,
205 double height_min1,
206 double lon_max1, double lat_max1,
207 double height_max1,
208 double lon_min2, double lat_min2,
209 double height_min2,
210 double lon_max2, double lat_max2,
211 double height_max2,
212 double tolerance)
213 {
214 typedef other_system_info
215 <
216 typename bg::coordinate_system<Box>::type
217 > other;
218
219 typedef bg::model::box
220 <
221 bg::model::point
222 <
223 typename bg::coordinate_type<Box>::type,
224 bg::dimension<Box>::value,
225 typename other::type
226 >
227 > other_mbr_type;
228
229 #ifdef BOOST_GEOMETRY_TEST_DEBUG
230 std::cout << "case ID: " << case_id
231 << std::endl << std::endl;
232 #endif
233
234 base_test(case_id, box, geometry,
235 lon_min1, lat_min1, height_min1,
236 lon_max1, lat_max1, height_max1,
237 lon_min2, lat_min2, height_min2,
238 lon_max2, lat_max2, height_max2,
239 tolerance);
240
241 other_mbr_type other_box;
242 bg::detail::indexed_point_view<Box const, 0> p_min(box);
243 bg::detail::indexed_point_view<Box const, 1> p_max(box);
244 bg::detail::indexed_point_view
245 <
246 other_mbr_type, 0
247 > other_min(other_box);
248
249 bg::detail::indexed_point_view
250 <
251 other_mbr_type, 1
252 > other_max(other_box);
253
254 bg::transform(p_min, other_min);
255 bg::transform(p_max, other_max);
256
257 base_test(case_id, other_box, geometry,
258 other::convert(lon_min1),
259 other::convert(lat_min1),
260 height_min1,
261 other::convert(lon_max1),
262 other::convert(lat_max1),
263 height_max1,
264 other::convert(lon_min2),
265 other::convert(lat_min2),
266 height_min2,
267 other::convert(lon_max2),
268 other::convert(lat_max2),
269 height_max2,
270 tolerance);
271
272 #ifdef BOOST_GEOMETRY_TEST_DEBUG
273 std::cout << "=================="
274 << std::endl << std::endl;
275 #endif
276 }
277 };
278
279 template <typename Dummy>
280 struct basic_tester<true, Dummy>
281 {
282 template <typename Box, typename Geometry>
283 static inline void apply(std::string const& case_id,
284 Box const& box,
285 Geometry const& geometry,
286 double lon_min1, double lat_min1,
287 double height_min1,
288 double lon_max1, double lat_max1,
289 double height_max1,
290 double lon_min2, double lat_min2,
291 double height_min2,
292 double lon_max2, double lat_max2,
293 double height_max2,
294 double tolerance)
295 {
296 basic_tester
297 <
298 false
299 >::apply(case_id, box, geometry,
300 lon_min1, lat_min1, height_min1,
301 lon_max1, lat_max1, height_max1,
302 lon_min2, lat_min2, height_min1,
303 lon_max2, lat_max2, height_max2,
304 tolerance);
305
306 std::string case_id_r = case_id + "[R]";
307
308 basic_tester
309 <
310 false
311 >::apply(case_id_r, geometry, box,
312 lon_min1, lat_min1, height_min1,
313 lon_max1, lat_max1, height_max1,
314 lon_min2, lat_min2, height_min2,
315 lon_max2, lat_max2, height_max2,
316 tolerance);
317 }
318 };
319
320
321 public:
322 template <typename Box, typename Geometry>
323 static inline void apply(std::string const& case_id,
324 Box const& box,
325 Geometry const& geometry,
326 double lon_min1, double lat_min1, double height_min1,
327 double lon_max1, double lat_max1, double height_max1,
328 double lon_min2, double lat_min2, double height_min2,
329 double lon_max2, double lat_max2, double height_max2,
330 double tolerance = std::numeric_limits<double>::epsilon())
331 {
332
333 basic_tester
334 <
335 boost::is_same
336 <
337 typename bg::tag<Geometry>::type,
338 bg::box_tag
339 >::value
340 >::apply(case_id, box, geometry,
341 lon_min1, lat_min1, height_min1,
342 lon_max1, lat_max1, height_max1,
343 lon_min2, lat_min2, height_min2,
344 lon_max2, lat_max2, height_max2,
345 tolerance);
346 }
347
348 template <typename Box, typename Geometry>
349 static inline void apply(std::string const& case_id,
350 Box const& box,
351 Geometry const& geometry,
352 double lon_min1, double lat_min1,
353 double lon_max1, double lat_max1,
354 double lon_min2, double lat_min2,
355 double lon_max2, double lat_max2,
356 double tolerance = std::numeric_limits<double>::epsilon())
357 {
358 apply(case_id, box, geometry,
359 lon_min1, lat_min1, 0, lon_max1, lat_max1, 0,
360 lon_min2, lat_min2, 0, lon_max2, lat_max2, 0,
361 tolerance);
362 }
363
364 template <typename Box, typename Geometry>
365 static inline void apply(std::string const& case_id,
366 Box const& box,
367 Geometry const& geometry,
368 double lon_min, double lat_min,
369 double lon_max, double lat_max,
370 double tolerance = std::numeric_limits<double>::epsilon())
371 {
372 apply(case_id, box, geometry,
373 lon_min, lat_min, 0, lon_max, lat_max, 0,
374 lon_min, lat_min, 0, lon_max, lat_max, 0,
375 tolerance);
376 }
377
378 template <typename Box, typename Geometry>
379 static inline void apply(std::string const& case_id,
380 Box const& box,
381 Geometry const& geometry,
382 double lon_min, double lat_min, double height_min,
383 double lon_max, double lat_max, double height_max,
384 double tolerance = std::numeric_limits<double>::epsilon())
385 {
386 apply(case_id, box, geometry,
387 lon_min, lat_min, height_min, lon_max, lat_max, height_max,
388 lon_min, lat_min, height_min, lon_max, lat_max, height_max,
389 tolerance);
390 }
391 };
392
393
394 template <typename CoordinateSystem>
395 void test_expand_point()
396 {
397 typedef bg::model::point<double, 2, CoordinateSystem> point_type;
398 typedef bg::model::box<point_type> B;
399 typedef point_type G;
400 typedef test_expand_on_spheroid tester;
401
402 tester::apply("p01",
403 from_wkt<B>("BOX(0 0,5 5)"),
404 from_wkt<G>("POINT(10 10)"),
405 0, 0, 10, 10);
406
407 tester::apply("p02",
408 from_wkt<B>("BOX(0 0,5 5)"),
409 from_wkt<G>("POINT(370 10)"),
410 0, 0, 10, 10);
411
412 tester::apply("p03",
413 from_wkt<B>("BOX(10 10,10 10)"),
414 from_wkt<G>("POINT(20 20)"),
415 10, 10, 20, 20);
416
417 tester::apply("p04",
418 from_wkt<B>("BOX(10 10,10 10)"),
419 from_wkt<G>("POINT(10 20)"),
420 10, 10, 10, 20);
421
422 // there are two possible valid longitude ranges:
423 // [10, 190] and [-170, 10]
424 tester::apply("p05",
425 from_wkt<B>("BOX(10 10,10 10)"),
426 from_wkt<G>("POINT(190 20)"),
427 10, 10, 190, 20);
428
429 // there are two possible valid longitude ranges:
430 // [10, 190] and [-170, 10]
431 tester::apply("p05a",
432 from_wkt<B>("BOX(10 10,10 10)"),
433 from_wkt<G>("POINT(-170 20)"),
434 10, 10, 190, 20,
435 -170, 10, 10, 20);
436
437 tester::apply("p06",
438 from_wkt<B>("BOX(170 10,175 20)"),
439 from_wkt<G>("POINT(-170 15)"),
440 170, 10, 190, 20);
441
442 tester::apply("p06a",
443 from_wkt<B>("BOX(170 10,175 20)"),
444 from_wkt<G>("POINT(-170 -6)"),
445 170, -6, 190, 20);
446
447 tester::apply("p06b",
448 from_wkt<B>("BOX(170 10,175 20)"),
449 from_wkt<G>("POINT(-170 36)"),
450 170, 10, 190, 36);
451
452 // point is inside box
453 tester::apply("p07",
454 from_wkt<B>("BOX(-30 -45,60 55)"),
455 from_wkt<G>("POINT(0 0)"),
456 -30, -45, 60, 55);
457
458 // point is inside box
459 tester::apply("p07a",
460 from_wkt<B>("BOX(-30 -45,60 55)"),
461 from_wkt<G>("POINT(360 0)"),
462 -30, -45, 60, 55);
463
464 tester::apply("p08",
465 from_wkt<B>("BOX(-100 -45,-90 55)"),
466 from_wkt<G>("POINT(80 60)"),
467 -100, -45, 80, 60);
468
469 tester::apply("p09",
470 from_wkt<B>("BOX(-100 -45,-90 55)"),
471 from_wkt<G>("POINT(170 60)"),
472 170, -45, 270, 60);
473
474 // point is north pole
475 tester::apply("p10",
476 from_wkt<B>("BOX(-100 -45,-90 55)"),
477 from_wkt<G>("POINT(-80 90)"),
478 -100, -45, -90, 90);
479
480 // point is north pole
481 tester::apply("p10a",
482 from_wkt<B>("BOX(-100 -45,-90 55)"),
483 from_wkt<G>("POINT(170 90)"),
484 -100, -45, -90, 90);
485
486 tester::apply("p10b",
487 from_wkt<B>("BOX(-100 -45,-90 55)"),
488 from_wkt<G>("POINT(170 80)"),
489 170, -45, 270, 80);
490
491 // box is north pole
492 tester::apply("p11",
493 from_wkt<B>("BOX(10 90,20 90)"),
494 from_wkt<G>("POINT(15 89)"),
495 15, 89, 15, 90);
496
497 // box is south pole
498 tester::apply("p11a",
499 from_wkt<B>("BOX(10 -90,20 -90)"),
500 from_wkt<G>("POINT(15 89)"),
501 15, -90, 15, 89);
502
503 // point is south pole
504 tester::apply("p12",
505 from_wkt<B>("BOX(10 80,20 85)"),
506 from_wkt<G>("POINT(15 -90)"),
507 10, -90, 20, 85);
508
509 // point is south pole
510 tester::apply("p12a",
511 from_wkt<B>("BOX(10 80,20 85)"),
512 from_wkt<G>("POINT(25 -90)"),
513 10, -90, 20, 85);
514
515 // box is north pole and point is south pole
516 tester::apply("p13",
517 from_wkt<B>("BOX(10 90,20 90)"),
518 from_wkt<G>("POINT(25 -90)"),
519 0, -90, 0, 90);
520
521 // box contains north pole and point is south pole
522 tester::apply("p14",
523 from_wkt<B>("BOX(10 80,20 90)"),
524 from_wkt<G>("POINT(25 -90)"),
525 10, -90, 20, 90);
526
527 // box contains south pole and point is north pole
528 tester::apply("p15",
529 from_wkt<B>("BOX(10 -90,30 0)"),
530 from_wkt<G>("POINT(25 90)"),
531 10, -90, 30, 90);
532
533 // box and point are north pole
534 tester::apply("p15",
535 from_wkt<B>("BOX(10 90,20 90)"),
536 from_wkt<G>("POINT(25 90)"),
537 0, 90, 0, 90);
538
539 // box and point are south pole
540 tester::apply("p16",
541 from_wkt<B>("BOX(10 -90,20 -90)"),
542 from_wkt<G>("POINT(-25 -90)"),
543 0, -90, 0, -90);
544
545 // box contains both poles
546 tester::apply("p17",
547 from_wkt<B>("BOX(10 -90,10 90)"),
548 from_wkt<G>("POINT(10 80)"),
549 10, -90, 10, 90);
550
551 // box contains both poles
552 tester::apply("p17a",
553 from_wkt<B>("BOX(10 -90,10 90)"),
554 from_wkt<G>("POINT(25 80)"),
555 10, -90, 25, 90);
556
557 // box contains both poles
558 tester::apply("p18",
559 from_wkt<B>("BOX(10 -90,100 90)"),
560 from_wkt<G>("POINT(25 80)"),
561 10, -90, 100, 90);
562
563 // box contains both poles
564 tester::apply("p18a",
565 from_wkt<B>("BOX(10 -90,100 90)"),
566 from_wkt<G>("POINT(-175 80)"),
567 10, -90, 185, 90);
568
569 // box contains both poles
570 tester::apply("p18b",
571 from_wkt<B>("BOX(10 -90,100 90)"),
572 from_wkt<G>("POINT(-95 80)"),
573 -95, -90, 100, 90);
574
575 // box contains both poles and point is north pole
576 tester::apply("p19",
577 from_wkt<B>("BOX(10 -90,100 90)"),
578 from_wkt<G>("POINT(-95 90)"),
579 10, -90, 100, 90);
580
581 // box contains both poles and point is south pole
582 tester::apply("p20",
583 from_wkt<B>("BOX(10 -90,100 90)"),
584 from_wkt<G>("POINT(-95 -90)"),
585 10, -90, 100, 90);
586 }
587
588 BOOST_AUTO_TEST_CASE( expand_point )
589 {
590 test_expand_point<bg::cs::spherical_equatorial<bg::degree> >();
591 test_expand_point<bg::cs::geographic<bg::degree> >();
592 }
593
594
595 template <typename CoordinateSystem>
596 void test_expand_point_with_height()
597 {
598 typedef bg::model::point<double, 3, CoordinateSystem> point_type;
599 typedef bg::model::box<point_type> B;
600 typedef point_type G;
601 typedef test_expand_on_spheroid tester;
602
603 // deactivate this for now
604 tester::apply("ph01",
605 from_wkt<B>("BOX(0 0 20,5 5 100)"),
606 from_wkt<G>("POINT(10 10 80)"),
607 0, 0, 20, 10, 10, 100);
608
609 tester::apply("ph02",
610 from_wkt<B>("BOX(0 0 20,5 5 100)"),
611 from_wkt<G>("POINT(10 10 120)"),
612 0, 0, 20, 10, 10, 120);
613
614 tester::apply("ph03",
615 from_wkt<B>("BOX(0 0 20,5 5 100)"),
616 from_wkt<G>("POINT(10 10 5)"),
617 0, 0, 5, 10, 10, 100);
618 }
619
620 BOOST_AUTO_TEST_CASE( expand_point_with_height )
621 {
622 test_expand_point_with_height<bg::cs::spherical_equatorial<bg::degree> >();
623 test_expand_point_with_height<bg::cs::geographic<bg::degree> >();
624 }
625
626
627 BOOST_AUTO_TEST_CASE( expand_segment )
628 {
629 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
630 typedef bg::model::point<double, 2, coordinate_system_type> point_type;
631 typedef bg::model::box<point_type> B;
632 typedef bg::model::segment<point_type> G;
633 typedef test_expand_on_spheroid tester;
634
635 tester::apply("s01",
636 from_wkt<B>("BOX(20 20,50 50)"),
637 from_wkt<G>("SEGMENT(10 10,40 40)"),
638 10, 10, 50, 50);
639
640 tester::apply("s02",
641 from_wkt<B>("BOX(20 20,50 50)"),
642 from_wkt<G>("SEGMENT(10 10,40 10)"),
643 10, 10, 50, 50);
644
645 tester::apply("s03",
646 from_wkt<B>("BOX(5 5,50 10)"),
647 from_wkt<G>("SEGMENT(40 10,10 10)"),
648 5, 5, 50, 10.34527004614999,
649 4.0 * std::numeric_limits<double>::epsilon());
650
651 // segment ending at the north pole
652 tester::apply("s04",
653 from_wkt<B>("BOX(5 15,50 50)"),
654 from_wkt<G>("SEGMENT(40 45,80 90)"),
655 5, 15, 50, 90);
656
657 // segment ending at the north pole
658 tester::apply("s04a",
659 from_wkt<B>("BOX(5 15,30 30)"),
660 from_wkt<G>("SEGMENT(40 45,80 90)"),
661 5, 15, 40, 90);
662
663 // segment starting at the north pole
664 tester::apply("s05",
665 from_wkt<B>("BOX(5 15,50 50)"),
666 from_wkt<G>("SEGMENT(80 90,40 45)"),
667 5, 15, 50, 90);
668
669 // segment starting at the north pole
670 tester::apply("s05a",
671 from_wkt<B>("BOX(5 15,30 30)"),
672 from_wkt<G>("SEGMENT(80 90,40 45)"),
673 5, 15, 40, 90);
674
675 // segment passing through the south pole
676 tester::apply("s06",
677 from_wkt<B>("BOX(5 15,30 40)"),
678 from_wkt<G>("SEGMENT(-170 -45,10 -30)"),
679 -170, -90, 30, 40);
680
681 // segment degenerating to the north pole
682 tester::apply("s07",
683 from_wkt<B>("BOX(5 15,30 40)"),
684 from_wkt<G>("SEGMENT(10 90,20 90)"),
685 5, 15, 30, 90);
686
687 // segment degenerating to the south pole
688 tester::apply("s08",
689 from_wkt<B>("BOX(5 15,30 40)"),
690 from_wkt<G>("SEGMENT(10 -90,20 -90)"),
691 5, -90, 30, 40);
692
693 // box degenerating to the south pole
694 tester::apply("s09",
695 from_wkt<B>("BOX(10 -90,30 -90)"),
696 from_wkt<G>("SEGMENT(10 -30,100 45)"),
697 10, -90, 100, 45);
698
699 // box degenerating to the south pole
700 tester::apply("s09a",
701 from_wkt<B>("BOX(10 -90,130 -90)"),
702 from_wkt<G>("SEGMENT(10 -30,100 45)"),
703 10, -90, 100, 45);
704 }
705
706
707 BOOST_AUTO_TEST_CASE( expand_segment_with_height )
708 {
709 typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
710 typedef bg::model::point<double, 3, coordinate_system_type> point_type;
711 typedef bg::model::box<point_type> B;
712 typedef bg::model::segment<point_type> G;
713 typedef test_expand_on_spheroid tester;
714
715 tester::apply("sh01",
716 from_wkt<B>("BOX(20 20 100,50 50 1000)"),
717 from_wkt<G>("SEGMENT(10 10 150,40 40 500)"),
718 10, 10, 100, 50, 50, 1000);
719
720 tester::apply("sh02",
721 from_wkt<B>("BOX(20 20 100,50 50 1000)"),
722 from_wkt<G>("SEGMENT(10 10 60,40 40 1500)"),
723 10, 10, 60, 50, 50, 1500);
724
725 tester::apply("sh03",
726 from_wkt<B>("BOX(20 20 100,50 50 1000)"),
727 from_wkt<G>("SEGMENT(10 10 150,40 40 1500)"),
728 10, 10, 100, 50, 50, 1500);
729
730 tester::apply("sh04",
731 from_wkt<B>("BOX(20 20 100,50 50 1000)"),
732 from_wkt<G>("SEGMENT(10 10 60,40 40 800)"),
733 10, 10, 60, 50, 50, 1000);
734 }
735
736
737 template <typename CoordinateSystem>
738 void test_expand_box()
739 {
740 typedef bg::model::point<double, 2, CoordinateSystem> point_type;
741 typedef bg::model::box<point_type> B;
742 typedef bg::model::box<point_type> G;
743 typedef test_expand_on_spheroid tester;
744
745 tester::apply("b01",
746 from_wkt<B>("BOX(11 11,19 19)"),
747 from_wkt<G>("BOX(10 10,20 20)"),
748 10, 10, 20, 20);
749
750 tester::apply("b02",
751 from_wkt<B>("BOX(11 11,29 29)"),
752 from_wkt<G>("BOX(10 10,20 20)"),
753 10, 10, 29, 29);
754
755 tester::apply("b03",
756 from_wkt<B>("BOX(21 21,29 29)"),
757 from_wkt<G>("BOX(10 10,20 20)"),
758 10, 10, 29, 29);
759
760 tester::apply("b04",
761 from_wkt<B>("BOX(150 -10,200 60)"),
762 from_wkt<G>("BOX(-175 -20,-150 55)"),
763 150, -20, 210, 60);
764
765 tester::apply("b04a",
766 from_wkt<B>("BOX(150 -10,200 60)"),
767 from_wkt<G>("BOX(-175 -20,-170 55)"),
768 150, -20, 200, 60);
769
770 tester::apply("b04b",
771 from_wkt<B>("BOX(150 -10,200 60)"),
772 from_wkt<G>("BOX(-175 -20,-140 55)"),
773 150, -20, 220, 60);
774
775 tester::apply("b05",
776 from_wkt<B>("BOX(150 -10,170 60)"),
777 from_wkt<G>("BOX(179 -20,535 55)"),
778 179, -20, 535, 60);
779
780 tester::apply("b06",
781 from_wkt<B>("BOX(150 -10,170 60)"),
782 from_wkt<G>("BOX(179 -20,520 55)"),
783 179, -20, 530, 60);
784
785 tester::apply("b07",
786 from_wkt<B>("BOX(-100 -10,170 60)"),
787 from_wkt<G>("BOX(100 -20,400 55)"),
788 -180, -20, 180, 60);
789
790 tester::apply("b08",
791 from_wkt<B>("BOX(-100 -10,100 60)"),
792 from_wkt<G>("BOX(150 -20,150 55)"),
793 -100, -20, 150, 60);
794
795 tester::apply("b09",
796 from_wkt<B>("BOX(100 -10,400 60)"),
797 from_wkt<G>("BOX(0 -20,0 55)"),
798 100, -20, 400, 60);
799
800 // this is a border case:
801 // there are two possible MBRs with longitude intervals:
802 // [100, 430] and [70, 400]
803 tester::apply("b10",
804 from_wkt<B>("BOX(100 -10,400 60)"),
805 from_wkt<G>("BOX(70 -20,70 55)"),
806 70, -20, 400, 60,
807 100, -20, 430, 60);
808
809 tester::apply("b10a",
810 from_wkt<B>("BOX(100 -10,400 60)"),
811 from_wkt<G>("BOX(71 -20,71 55)"),
812 71, -20, 400, 60);
813
814 tester::apply("b10b",
815 from_wkt<B>("BOX(100 -10,400 60)"),
816 from_wkt<G>("BOX(69 -20,69 55)"),
817 100, -20, 429, 60);
818
819 tester::apply("b11",
820 from_wkt<B>("BOX(-90 -10,-90 60)"),
821 from_wkt<G>("BOX(90 -20,90 55)"),
822 -90, -20, 90, 60);
823
824 // first box is the south pole
825 tester::apply("b12",
826 from_wkt<B>("BOX(-90 -90,80 -90)"),
827 from_wkt<G>("BOX(90 -20,90 55)"),
828 90, -90, 90, 55);
829
830 // first box is the south pole
831 tester::apply("b12a",
832 from_wkt<B>("BOX(-90 -90,80 -90)"),
833 from_wkt<G>("BOX(90 -20,130 55)"),
834 90, -90, 130, 55);
835
836 // first box is the north pole
837 tester::apply("b13",
838 from_wkt<B>("BOX(-90 90,80 90)"),
839 from_wkt<G>("BOX(90 -20,90 55)"),
840 90, -20, 90, 90);
841
842 // first box is the north pole
843 tester::apply("b13a",
844 from_wkt<B>("BOX(-90 90,80 90)"),
845 from_wkt<G>("BOX(90 -20,190 55)"),
846 90, -20, 190, 90);
847
848 // both boxes are the north pole
849 tester::apply("b14",
850 from_wkt<B>("BOX(-90 90,80 90)"),
851 from_wkt<G>("BOX(90 90,190 90)"),
852 0, 90, 0, 90);
853
854 // both boxes are the south pole
855 tester::apply("b15",
856 from_wkt<B>("BOX(-90 -90,80 -90)"),
857 from_wkt<G>("BOX(90 -90,190 -90)"),
858 0, -90, 0, -90);
859
860 // one box is the south pole and the other the north pole
861 tester::apply("b16",
862 from_wkt<B>("BOX(-90 -90,80 -90)"),
863 from_wkt<G>("BOX(90 90,190 90)"),
864 0, -90, 0, 90);
865
866 // both boxes contain both poles but at different longitudes
867 tester::apply("b17",
868 from_wkt<B>("BOX(10 -90,10 90)"),
869 from_wkt<G>("BOX(20 -90,20 90)"),
870 10, -90, 20, 90);
871
872 // both boxes contain both poles but at different longitude ranges
873 tester::apply("b17",
874 from_wkt<B>("BOX(10 -90,20 90)"),
875 from_wkt<G>("BOX(40 -90,60 90)"),
876 10, -90, 60, 90);
877
878
879 // first box is a band
880 tester::apply("b18",
881 from_wkt<B>("BOX(0 10,360 20)"),
882 from_wkt<G>("BOX(-10 -40,20 10)"),
883 -180, -40, 180, 20);
884
885 // first box contains south and north pole and is a band
886 // (box covers the entire spheroid)
887 tester::apply("b19",
888 from_wkt<B>("BOX(0 -90,360 90)"),
889 from_wkt<G>("BOX(-10 -40,20 10)"),
890 -180, -90, 180, 90);
891
892 // the envelope of the two boxes is a band
893 tester::apply("b20",
894 from_wkt<B>("BOX(-180 -40,0 -30)"),
895 from_wkt<G>("BOX(0 -10,180 50)"),
896 -180, -40, 180, 50);
897
898 // the envelope of the two boxes is a band
899 tester::apply("b20a",
900 from_wkt<B>("BOX(-180 -40,0 -30)"),
901 from_wkt<G>("BOX(0 -10,185 50)"),
902 -180, -40, 180, 50);
903
904 // the envelope of the two boxes is a band
905 tester::apply("b20b",
906 from_wkt<B>("BOX(-179 -40,0 -30)"),
907 from_wkt<G>("BOX(0 -10,185 50)"),
908 -180, -40, 180, 50);
909 }
910
911 BOOST_AUTO_TEST_CASE( expand_box )
912 {
913 test_expand_box<bg::cs::spherical_equatorial<bg::degree> >();
914 test_expand_box<bg::cs::geographic<bg::degree> >();
915 }
916
917
918 template <typename CoordinateSystem>
919 void test_expand_box_with_height()
920 {
921 typedef bg::model::point<double, 3, CoordinateSystem> point_type;
922 typedef bg::model::box<point_type> B;
923 typedef bg::model::box<point_type> G;
924 typedef test_expand_on_spheroid tester;
925
926 tester::apply("bh01",
927 from_wkt<B>("BOX(11 11 100,19 19 1000)"),
928 from_wkt<G>("BOX(10 10 200,20 20 800)"),
929 10, 10, 100, 20, 20, 1000);
930
931 tester::apply("bh02",
932 from_wkt<B>("BOX(11 11 200,19 19 1000)"),
933 from_wkt<G>("BOX(10 10 100,20 20 800)"),
934 10, 10, 100, 20, 20, 1000);
935
936 tester::apply("bh03",
937 from_wkt<B>("BOX(11 11 100,19 19 800)"),
938 from_wkt<G>("BOX(10 10 200,20 20 1000)"),
939 10, 10, 100, 20, 20, 1000);
940
941 tester::apply("bh04",
942 from_wkt<B>("BOX(11 11 200,19 19 1000)"),
943 from_wkt<G>("BOX(10 10 100,20 20 800)"),
944 10, 10, 100, 20, 20, 1000);
945 }
946
947 BOOST_AUTO_TEST_CASE( expand_box_with_height )
948 {
949 test_expand_box_with_height<bg::cs::spherical_equatorial<bg::degree> >();
950 test_expand_box_with_height<bg::cs::geographic<bg::degree> >();
951 }