1 // Boost.Geometry (aka GGL, Generic Geometry Library)
4 // Copyright (c) 2014-2021 Oracle and/or its affiliates.
5 // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
6 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
7 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
9 // Licensed under the Boost Software License version 1.0.
10 // http://www.boost.org/users/license.html
12 #ifndef BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
13 #define BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP
17 #include <boost/range/begin.hpp>
18 #include <boost/range/end.hpp>
19 #include <boost/range/value_type.hpp>
21 #include <boost/geometry/core/reverse_dispatch.hpp>
22 #include <boost/geometry/core/tag.hpp>
23 #include <boost/geometry/core/tag_cast.hpp>
24 #include <boost/geometry/core/tags.hpp>
26 #include <boost/geometry/iterators/segment_iterator.hpp>
28 #include <boost/geometry/algorithms/distance.hpp>
29 #include <boost/geometry/algorithms/intersects.hpp>
30 #include <boost/geometry/algorithms/not_implemented.hpp>
33 namespace boost { namespace geometry
39 namespace detail { namespace distance_brute_force
42 struct distance_from_bg
45 struct use_distance_from_bg
48 std::is_same<typename tag<G>::type, point_tag>::value
49 || std::is_same<typename tag<G>::type, segment_tag>::value
50 || std::is_same<typename tag<G>::type, box_tag>::value
54 template <typename Geometry1, typename Geometry2, typename Strategy>
56 typename distance_result<Geometry1, Geometry2, Strategy>::type
57 apply(Geometry1 const& geometry1,
58 Geometry2 const& geometry2,
59 Strategy const& strategy)
61 BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg<Geometry1>::value),
62 "Unexpected kind of Geometry1",
64 BOOST_GEOMETRY_STATIC_ASSERT((use_distance_from_bg<Geometry2>::value),
65 "Unexpected kind of Geometry2",
68 return geometry::distance(geometry1, geometry2, strategy);
73 template <typename Geometry1, typename Geometry2, typename Strategy>
75 typename distance_result<Geometry1, Geometry2, Strategy>::type
76 bg_distance(Geometry1 const& geometry1,
77 Geometry2 const& geometry2,
78 Strategy const& strategy)
80 return distance_from_bg::apply(geometry1, geometry2, strategy);
84 template <typename Policy>
87 template <typename Geometry, typename Iterator, typename Strategy>
88 static inline typename distance_result
91 typename std::iterator_traits<Iterator>::value_type,
94 apply(Geometry const& geometry, Iterator begin, Iterator end,
95 Strategy const& strategy)
97 typedef typename distance_result
100 typename std::iterator_traits<Iterator>::value_type,
102 >::type distance_type;
105 distance_type d_min(0);
106 for (Iterator it = begin; it != end; ++it, first = false)
108 distance_type d = Policy::apply(geometry, *it, strategy);
110 if ( first || d < d_min )
121 }} // namespace detail::distance_brute_force
132 typename Tag1 = typename tag_cast
134 typename tag<Geometry1>::type,
138 typename Tag2 = typename tag_cast
140 typename tag<Geometry2>::type,
144 bool Reverse = reverse_dispatch<Geometry1, Geometry2>::type::value
146 struct distance_brute_force
147 : not_implemented<Geometry1, Geometry2>
158 struct distance_brute_force<Geometry1, Geometry2, Strategy, Tag1, Tag2, true>
160 static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
161 apply(Geometry1 const& geometry1,
162 Geometry2 const& geometry2,
163 Strategy const& strategy)
165 return distance_brute_force
167 Geometry2, Geometry1, Strategy
168 >::apply(geometry2, geometry1, strategy);
172 //===================================================================
180 struct distance_brute_force
182 Point1, Point2, Strategy,
183 point_tag, point_tag, false
184 > : detail::distance_brute_force::distance_from_bg
194 struct distance_brute_force
196 Point, Segment, Strategy,
197 point_tag, segment_tag, false
198 > : detail::distance_brute_force::distance_from_bg
207 struct distance_brute_force
209 Point, Linear, Strategy,
210 point_tag, linear_tag, false
213 typedef typename distance_result
215 Point, Linear, Strategy
216 >::type distance_type;
218 static inline distance_type apply(Point const& point,
219 Linear const& linear,
220 Strategy const& strategy)
222 return detail::distance_brute_force::one_to_many
224 detail::distance_brute_force::distance_from_bg
226 geometry::segments_begin(linear),
227 geometry::segments_end(linear),
238 struct distance_brute_force
240 Point, Ring, Strategy,
241 point_tag, ring_tag, false
244 typedef typename distance_result
246 Point, Ring, Strategy
247 >::type distance_type;
249 static inline distance_type apply(Point const& point,
251 Strategy const& strategy)
254 if (geometry::covered_by(point, ring))
259 return detail::distance_brute_force::one_to_many
264 typename std::iterator_traits
266 segment_iterator<Ring const>
271 geometry::segments_begin(ring),
272 geometry::segments_end(ring),
277 //TODO do it more brute force (also in all polygon-geometry cases)
284 struct distance_brute_force
286 Point, Polygon, Strategy,
287 point_tag, polygon_tag, false
290 typedef typename distance_result
292 Point, Polygon, Strategy
293 >::type distance_type;
295 static inline distance_type apply(Point const& point,
296 Polygon const& polygon,
297 Strategy const& strategy)
299 return geometry::distance(point, polygon, strategy);
309 struct distance_brute_force
311 Point, Box, Strategy,
312 point_tag, box_tag, false
313 > : detail::distance_brute_force::distance_from_bg
322 struct distance_brute_force
324 Point, MultiPoint, Strategy,
325 point_tag, multi_point_tag, false
328 typedef typename distance_result
330 Point, MultiPoint, Strategy
331 >::type distance_type;
333 static inline distance_type apply(Point const& p,
334 MultiPoint const& mp,
335 Strategy const& strategy)
337 return detail::distance_brute_force::one_to_many
339 detail::distance_brute_force::distance_from_bg
340 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
347 typename MultiPolygon,
350 struct distance_brute_force
352 Point, MultiPolygon, Strategy,
353 point_tag, multi_polygon_tag, false
356 typedef typename distance_result
358 Point, MultiPolygon, Strategy
359 >::type distance_type;
361 static inline distance_type apply(Point const& p,
362 MultiPolygon const& mp,
363 Strategy const& strategy)
365 return detail::distance_brute_force::one_to_many
370 typename boost::range_value<MultiPolygon>::type,
373 >::apply(p, boost::begin(mp), boost::end(mp), strategy);
377 //=======================================================================
385 struct distance_brute_force
387 Linear, Segment, Strategy,
388 linear_tag, segment_tag, false
391 typedef typename distance_result
393 Linear, Segment, Strategy
394 >::type distance_type;
396 static inline distance_type apply(Linear const& linear,
397 Segment const& segment,
398 Strategy const& strategy)
400 return detail::distance_brute_force::one_to_many
402 detail::distance_brute_force::distance_from_bg
404 geometry::segments_begin(linear),
405 geometry::segments_end(linear),
417 struct distance_brute_force
419 Linear1, Linear2, Strategy,
420 linear_tag, linear_tag, false
423 typedef typename distance_result
425 Linear1, Linear2, Strategy
426 >::type distance_type;
428 static inline distance_type apply(Linear1 const& linear1,
429 Linear2 const& linear2,
430 Strategy const& strategy)
432 return detail::distance_brute_force::one_to_many
437 typename std::iterator_traits
439 segment_iterator<Linear2 const>
444 geometry::segments_begin(linear2),
445 geometry::segments_end(linear2),
456 struct distance_brute_force
458 Linear, Ring, Strategy,
459 linear_tag, ring_tag, false
462 typedef typename distance_result
464 Linear, Ring, Strategy
465 >::type distance_type;
467 static inline distance_type apply(Linear const& linear,
469 Strategy const& strategy)
471 return detail::distance_brute_force::one_to_many
476 typename std::iterator_traits
478 segment_iterator<Ring const>
483 geometry::segments_begin(ring),
484 geometry::segments_end(ring),
495 struct distance_brute_force
497 Linear, Polygon, Strategy,
498 linear_tag, polygon_tag, false
501 typedef typename distance_result
503 Linear, Polygon, Strategy
504 >::type distance_type;
506 static inline distance_type apply(Linear const& linear,
507 Polygon const& polygon,
508 Strategy const& strategy)
510 return detail::distance_brute_force::one_to_many
515 typename std::iterator_traits
517 segment_iterator<Linear const>
522 geometry::segments_begin(linear),
523 geometry::segments_end(linear),
535 struct distance_brute_force
537 Linear, Box, Strategy,
538 linear_tag, box_tag, false
541 typedef typename distance_result
543 Linear, Box, Strategy
544 >::type distance_type;
546 static inline distance_type apply(Linear const& linear,
548 Strategy const& strategy)
550 return detail::distance_brute_force::one_to_many
552 detail::distance_brute_force::distance_from_bg
554 geometry::segments_begin(linear),
555 geometry::segments_end(linear),
566 struct distance_brute_force
568 Linear, MultiPoint, Strategy,
569 linear_tag, multi_point_tag, false
572 typedef typename distance_result
574 Linear, MultiPoint, Strategy
575 >::type distance_type;
577 static inline distance_type apply(Linear const& linear,
578 MultiPoint const& mp,
579 Strategy const& strategy)
581 return detail::distance_brute_force::one_to_many
586 typename boost::range_value<MultiPoint>::type,
589 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
596 typename MultiPolygon,
599 struct distance_brute_force
601 Linear, MultiPolygon, Strategy,
602 linear_tag, multi_polygon_tag, false
605 typedef typename distance_result
607 Linear, MultiPolygon, Strategy
608 >::type distance_type;
610 static inline distance_type apply(Linear const& linear,
611 MultiPolygon const& mp,
612 Strategy const& strategy)
614 return detail::distance_brute_force::one_to_many
619 typename boost::range_value<MultiPolygon>::type,
622 >::apply(linear, boost::begin(mp), boost::end(mp), strategy);
626 //=================================================================
634 struct distance_brute_force
636 Polygon, Segment, Strategy,
637 polygon_tag, segment_tag, false
640 typedef typename distance_result
642 Polygon, Segment, Strategy
643 >::type distance_type;
645 static inline distance_type apply(Polygon const& polygon,
646 Segment const& segment,
647 Strategy const& strategy)
649 return geometry::distance(segment, polygon, strategy);
659 struct distance_brute_force
661 Polygon, Linear, Strategy,
662 polygon_tag, linear_tag, false
665 typedef typename distance_result
667 Polygon, Linear, Strategy
668 >::type distance_type;
670 static inline distance_type apply(Polygon const& polygon,
671 Linear const& linear,
672 Strategy const& strategy)
674 return detail::distance_brute_force::one_to_many
679 typename std::iterator_traits
681 segment_iterator<Linear const>
686 geometry::segments_begin(linear),
687 geometry::segments_end(linear),
698 struct distance_brute_force
700 Polygon1, Polygon2, Strategy,
701 polygon_tag, polygon_tag, false
704 typedef typename distance_result
706 Polygon1, Polygon2, Strategy
707 >::type distance_type;
709 static inline distance_type apply(Polygon1 const& polygon1,
710 Polygon2 const& polygon2,
711 Strategy const& strategy)
713 return geometry::distance(polygon1, polygon2, strategy);
724 struct distance_brute_force
726 Polygon, MultiPoint, Strategy,
727 polygon_tag, multi_point_tag, false
730 typedef typename distance_result
732 Polygon, MultiPoint, Strategy
733 >::type distance_type;
735 static inline distance_type apply(Polygon const& polygon,
736 MultiPoint const& mp,
737 Strategy const& strategy)
739 return detail::distance_brute_force::one_to_many
744 typename boost::range_value<MultiPoint>::type,
747 >::apply(polygon, boost::begin(mp), boost::end(mp), strategy);
754 typename MultiPolygon,
757 struct distance_brute_force
759 Polygon, MultiPolygon, Strategy,
760 polygon_tag, multi_polygon_tag, false
763 typedef typename distance_result
765 Polygon, MultiPolygon, Strategy
766 >::type distance_type;
768 static inline distance_type apply(Polygon const& poly,
769 MultiPolygon const& mp,
770 Strategy const& strategy)
772 return detail::distance_brute_force::one_to_many
777 typename boost::range_value<MultiPolygon>::type,
780 >::apply(poly, boost::begin(mp), boost::end(mp), strategy);
790 struct distance_brute_force
792 Polygon, Ring, Strategy,
793 polygon_tag, ring_tag, false
796 typedef typename distance_result
798 Polygon, Ring, Strategy
799 >::type distance_type;
801 static inline distance_type apply(Polygon const& polygon,
803 Strategy const& strategy)
805 return geometry::distance(ring, polygon, strategy);
815 struct distance_brute_force
817 Polygon, Box, Strategy,
818 polygon_tag, box_tag, false
821 typedef typename distance_result
823 Polygon, Box, Strategy
824 >::type distance_type;
826 static inline distance_type apply(Polygon const& polygon,
828 Strategy const& strategy)
830 return geometry::distance(box, polygon, strategy);
834 //========================================================================
838 typename MultiPoint1,
839 typename MultiPoint2,
842 struct distance_brute_force
844 MultiPoint1, MultiPoint2, Strategy,
845 multi_point_tag, multi_point_tag, false
848 typedef typename distance_result
850 MultiPoint1, MultiPoint2, Strategy
851 >::type distance_type;
853 static inline distance_type apply(MultiPoint1 const& mp1,
854 MultiPoint2 const& mp2,
855 Strategy const& strategy)
857 return detail::distance_brute_force::one_to_many
862 typename boost::range_value<MultiPoint2>::type,
865 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
875 struct distance_brute_force
877 MultiPoint, Linear, Strategy,
878 multi_point_tag, linear_tag, false
881 typedef typename distance_result
883 MultiPoint, Linear, Strategy
884 >::type distance_type;
886 static inline distance_type apply(MultiPoint const& mp,
888 Strategy const& strategy)
890 return detail::distance_brute_force::one_to_many
895 typename boost::range_value<Linear>::type,
898 >::apply(mp, boost::begin(l), boost::end(l), strategy);
905 typename MultiPolygon,
908 struct distance_brute_force
910 MultiPoint, MultiPolygon, Strategy,
911 multi_point_tag, multi_polygon_tag, false
914 typedef typename distance_result
916 MultiPoint, MultiPolygon, Strategy
917 >::type distance_type;
919 static inline distance_type apply(MultiPoint const& mp,
920 MultiPolygon const& mpl,
921 Strategy const& strategy)
923 return detail::distance_brute_force::one_to_many
928 typename boost::range_value<MultiPolygon>::type,
931 >::apply(mp, boost::begin(mpl), boost::end(mpl), strategy);
941 struct distance_brute_force
943 MultiPoint, Segment, Strategy,
944 multi_point_tag, segment_tag, false
947 typedef typename distance_result
949 MultiPoint, Segment, Strategy
950 >::type distance_type;
952 static inline distance_type apply(MultiPoint const& mp,
953 Segment const& segment,
954 Strategy const& strategy)
956 return detail::distance_brute_force::one_to_many
958 detail::distance_brute_force::distance_from_bg
959 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
969 struct distance_brute_force
971 MultiPoint, Ring, Strategy,
972 multi_point_tag, ring_tag, false
975 typedef typename distance_result
977 MultiPoint, Ring, Strategy
978 >::type distance_type;
980 static inline distance_type apply(MultiPoint const& mp,
982 Strategy const& strategy)
986 return detail::distance_brute_force::one_to_many
991 typename std::iterator_traits
993 segment_iterator<Ring const>
998 geometry::segments_begin(ring),
999 geometry::segments_end(ring),
1006 typename MultiPoint,
1010 struct distance_brute_force
1012 MultiPoint, Box, Strategy,
1013 multi_point_tag, box_tag, false
1016 typedef typename distance_result
1018 MultiPoint, Box, Strategy
1019 >::type distance_type;
1021 static inline distance_type apply(MultiPoint const& mp,
1023 Strategy const& strategy)
1025 return detail::distance_brute_force::one_to_many
1027 distance_brute_force
1030 typename boost::range_value<MultiPoint>::type,
1033 >::apply(box, boost::begin(mp), boost::end(mp), strategy);
1037 //=====================================================================
1041 typename MultiPolygon1,
1042 typename MultiPolygon2,
1045 struct distance_brute_force
1047 MultiPolygon1, MultiPolygon2, Strategy,
1048 multi_polygon_tag, multi_polygon_tag, false
1051 typedef typename distance_result
1053 MultiPolygon1, MultiPolygon2, Strategy
1054 >::type distance_type;
1056 static inline distance_type apply(MultiPolygon1 const& mp1,
1057 MultiPolygon2 const& mp2,
1058 Strategy const& strategy)
1060 return detail::distance_brute_force::one_to_many
1062 distance_brute_force
1065 typename boost::range_value<MultiPolygon2>::type,
1068 >::apply(mp1, boost::begin(mp2), boost::end(mp2), strategy);
1074 typename MultiPolygon,
1078 struct distance_brute_force
1080 MultiPolygon, Segment, Strategy,
1081 multi_polygon_tag, segment_tag, false
1084 typedef typename distance_result
1086 MultiPolygon, Segment, Strategy
1087 >::type distance_type;
1089 static inline distance_type apply(MultiPolygon const& mp,
1090 Segment const& segment,
1091 Strategy const& strategy)
1093 return detail::distance_brute_force::one_to_many
1095 distance_brute_force
1098 typename boost::range_value<MultiPolygon>::type,
1101 >::apply(segment, boost::begin(mp), boost::end(mp), strategy);
1107 typename MultiPolygon,
1111 struct distance_brute_force
1113 MultiPolygon, Ring, Strategy,
1114 multi_polygon_tag, ring_tag, false
1117 typedef typename distance_result
1119 MultiPolygon, Ring, Strategy
1120 >::type distance_type;
1122 static inline distance_type apply(MultiPolygon const& mp,
1124 Strategy const& strategy)
1126 return detail::distance_brute_force::one_to_many
1128 distance_brute_force
1131 typename boost::range_value<MultiPolygon>::type,
1134 >::apply(ring, boost::begin(mp), boost::end(mp), strategy);
1140 typename MultiPolygon,
1144 struct distance_brute_force
1146 MultiPolygon, Box, Strategy,
1147 multi_polygon_tag, box_tag, false
1150 typedef typename distance_result
1152 MultiPolygon, Box, Strategy
1153 >::type distance_type;
1155 static inline distance_type apply(MultiPolygon const& mp,
1157 Strategy const& strategy)
1159 return detail::distance_brute_force::one_to_many
1161 distance_brute_force
1164 typename boost::range_value<MultiPolygon>::type,
1167 >::apply(box, boost::begin(mp), boost::end(mp), strategy);
1172 //========================================================================
1180 struct distance_brute_force
1182 Ring, Box, Strategy,
1183 ring_tag, box_tag, false
1186 typedef typename distance_result
1189 >::type distance_type;
1191 static inline distance_type apply(Ring const& ring,
1193 Strategy const& strategy)
1195 return detail::distance_brute_force::one_to_many
1197 distance_brute_force
1200 typename std::iterator_traits
1202 segment_iterator<Ring const>
1207 geometry::segments_begin(ring),
1208 geometry::segments_end(ring),
1219 struct distance_brute_force
1221 Ring1, Ring2, Strategy,
1222 ring_tag, ring_tag, false
1225 typedef typename distance_result
1227 Ring1, Ring2, Strategy
1228 >::type distance_type;
1230 static inline distance_type apply(Ring1 const& ring1,
1232 Strategy const& strategy)
1234 return detail::distance_brute_force::one_to_many
1236 distance_brute_force
1239 typename std::iterator_traits
1241 segment_iterator<Ring2 const>
1246 geometry::segments_begin(ring2),
1247 geometry::segments_end(ring2),
1252 //========================================================================
1260 struct distance_brute_force
1262 Segment1, Segment2, Strategy,
1263 segment_tag, segment_tag, false
1264 > : detail::distance_brute_force::distance_from_bg
1273 struct distance_brute_force
1275 Segment, Ring, Strategy,
1276 segment_tag, ring_tag, false
1279 typedef typename distance_result
1281 Segment, Ring, Strategy
1282 >::type distance_type;
1284 static inline distance_type apply(Segment const& segment,
1286 Strategy const& strategy)
1288 return detail::distance_brute_force::one_to_many
1290 distance_brute_force
1293 typename std::iterator_traits
1295 segment_iterator<Ring const>
1300 geometry::segments_begin(ring),
1301 geometry::segments_end(ring),
1312 struct distance_brute_force
1314 Segment, Box, Strategy,
1315 segment_tag, box_tag, false
1316 > : detail::distance_brute_force::distance_from_bg
1319 //====================================================================
1327 struct distance_brute_force
1329 Box1, Box2, Strategy,
1330 box_tag, box_tag, false
1331 > : detail::distance_brute_force::distance_from_bg
1334 } // namespace dispatch
1340 template <typename Geometry1, typename Geometry2, typename Strategy>
1341 inline typename distance_result<Geometry1, Geometry2, Strategy>::type
1342 distance_brute_force(Geometry1 const& geometry1,
1343 Geometry2 const& geometry2,
1344 Strategy const& strategy)
1346 return dispatch::distance_brute_force
1348 Geometry1, Geometry2, Strategy
1349 >::apply(geometry1, geometry2, strategy);
1352 } // namespace unit_test
1355 }} // namespace boost::geometry
1356 #endif // BOOST_GEOMETRY_TEST_DISTANCE_BRUTE_FORCE_HPP