File indexing completed on 2025-09-18 08:42:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
0023 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISJOINT_LINEAR_AREAL_HPP
0024
0025 #include <iterator>
0026
0027 #include <boost/range/begin.hpp>
0028 #include <boost/range/end.hpp>
0029 #include <boost/range/value_type.hpp>
0030
0031 #include <boost/geometry/core/closure.hpp>
0032 #include <boost/geometry/core/point_type.hpp>
0033 #include <boost/geometry/core/ring_type.hpp>
0034 #include <boost/geometry/core/exterior_ring.hpp>
0035 #include <boost/geometry/core/interior_rings.hpp>
0036 #include <boost/geometry/core/tag.hpp>
0037 #include <boost/geometry/core/tag_cast.hpp>
0038 #include <boost/geometry/core/tags.hpp>
0039
0040 #include <boost/geometry/algorithms/detail/covered_by/implementation.hpp>
0041 #include <boost/geometry/algorithms/not_implemented.hpp>
0042
0043 #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
0044 #include <boost/geometry/algorithms/detail/point_on_border.hpp>
0045
0046 #include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
0047 #include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
0048 #include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
0049 #include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
0050 #include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
0051
0052 #include <boost/geometry/algorithms/dispatch/disjoint.hpp>
0053
0054 #include <boost/geometry/geometries/helper_geometry.hpp>
0055
0056 namespace boost { namespace geometry
0057 {
0058
0059 #ifndef DOXYGEN_NO_DETAIL
0060 namespace detail { namespace disjoint
0061 {
0062
0063 template <typename Geometry1, typename Geometry2,
0064 typename Tag1 = tag_t<Geometry1>,
0065 typename Tag1OrMulti = tag_cast_t<Tag1, multi_tag>>
0066 struct disjoint_no_intersections_policy
0067 {
0068
0069
0070
0071 template <typename Strategy>
0072 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0073 {
0074 typename helper_geometry<point_type_t<Geometry1>>::type p;
0075 geometry::point_on_border(p, g1);
0076
0077 return ! geometry::covered_by(p, g2, strategy);
0078 }
0079 };
0080
0081 template <typename Geometry1, typename Geometry2, typename Tag1>
0082 struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
0083 {
0084
0085
0086
0087 template <typename Strategy>
0088 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0089 {
0090
0091 for (auto it = boost::begin(g1); it != boost::end(g1); ++it)
0092 {
0093 typedef typename boost::range_value<Geometry1 const>::type value_type;
0094 if (! disjoint_no_intersections_policy<value_type const, Geometry2>
0095 ::apply(*it, g2, strategy))
0096 {
0097 return false;
0098 }
0099 }
0100 return true;
0101 }
0102 };
0103
0104
0105 template<typename Geometry1, typename Geometry2,
0106 typename NoIntersectionsPolicy
0107 = disjoint_no_intersections_policy<Geometry1, Geometry2> >
0108 struct disjoint_linear_areal
0109 {
0110
0111
0112
0113 template <typename Strategy>
0114 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0115 {
0116
0117 if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
0118 {
0119 return false;
0120 }
0121
0122 return NoIntersectionsPolicy::apply(g1, g2, strategy);
0123 }
0124 };
0125
0126
0127
0128
0129 template
0130 <
0131 typename Segment,
0132 typename Areal,
0133 typename Tag = tag_t<Areal>
0134 >
0135 struct disjoint_segment_areal
0136 : not_implemented<Segment, Areal>
0137 {};
0138
0139
0140 template <typename Segment, typename Polygon>
0141 class disjoint_segment_areal<Segment, Polygon, polygon_tag>
0142 {
0143
0144 template <typename InteriorRings, typename Strategy>
0145 static inline
0146 bool check_interior_rings(InteriorRings const& interior_rings,
0147 Segment const& segment,
0148 Strategy const& strategy)
0149 {
0150 using ring_type = typename boost::range_value<InteriorRings>::type;
0151
0152 using unary_predicate_type = unary_disjoint_geometry_to_query_geometry
0153 <
0154 Segment,
0155 Strategy,
0156 disjoint_range_segment_or_box<ring_type, Segment>
0157 >;
0158
0159 return std::all_of(boost::begin(interior_rings),
0160 boost::end(interior_rings),
0161 unary_predicate_type(segment, strategy));
0162 }
0163
0164
0165 public:
0166 template <typename IntersectionStrategy>
0167 static inline bool apply(Segment const& segment,
0168 Polygon const& polygon,
0169 IntersectionStrategy const& strategy)
0170 {
0171 if (! disjoint_range_segment_or_box
0172 <
0173 geometry::ring_type_t<Polygon>,
0174 Segment
0175 >::apply(geometry::exterior_ring(polygon), segment, strategy))
0176 {
0177 return false;
0178 }
0179
0180 if (! check_interior_rings(geometry::interior_rings(polygon), segment, strategy))
0181 {
0182 return false;
0183 }
0184
0185 point_type_t<Segment> p;
0186 detail::assign_point_from_index<0>(segment, p);
0187
0188 return ! geometry::covered_by(p, polygon, strategy);
0189 }
0190 };
0191
0192
0193 template <typename Segment, typename MultiPolygon>
0194 struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
0195 {
0196 template <typename IntersectionStrategy>
0197 static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
0198 IntersectionStrategy const& strategy)
0199 {
0200 return multirange_constant_size_geometry
0201 <
0202 MultiPolygon, Segment
0203 >::apply(multipolygon, segment, strategy);
0204 }
0205 };
0206
0207
0208 template <typename Segment, typename Ring>
0209 struct disjoint_segment_areal<Segment, Ring, ring_tag>
0210 {
0211 template <typename IntersectionStrategy>
0212 static inline bool apply(Segment const& segment,
0213 Ring const& ring,
0214 IntersectionStrategy const& strategy)
0215 {
0216 if (! disjoint_range_segment_or_box<Ring, Segment>::apply(ring, segment, strategy))
0217 {
0218 return false;
0219 }
0220
0221 point_type_t<Segment> p;
0222 detail::assign_point_from_index<0>(segment, p);
0223
0224 return ! geometry::covered_by(p, ring, strategy);
0225 }
0226 };
0227
0228
0229 }}
0230 #endif
0231
0232
0233
0234
0235 #ifndef DOXYGEN_NO_DISPATCH
0236 namespace dispatch
0237 {
0238
0239
0240 template <typename Linear, typename Areal>
0241 struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
0242 : public detail::disjoint::disjoint_linear_areal<Linear, Areal>
0243 {};
0244
0245
0246 template <typename Areal, typename Linear>
0247 struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
0248 {
0249 template <typename Strategy>
0250 static inline bool apply(Areal const& areal, Linear const& linear,
0251 Strategy const& strategy)
0252 {
0253 return detail::disjoint::disjoint_linear_areal
0254 <
0255 Linear, Areal
0256 >::apply(linear, areal, strategy);
0257 }
0258 };
0259
0260
0261 template <typename Areal, typename Segment>
0262 struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
0263 {
0264 template <typename Strategy>
0265 static inline bool apply(Areal const& g1, Segment const& g2,
0266 Strategy const& strategy)
0267 {
0268 return detail::disjoint::disjoint_segment_areal
0269 <
0270 Segment, Areal
0271 >::apply(g2, g1, strategy);
0272 }
0273 };
0274
0275
0276 template <typename Segment, typename Areal>
0277 struct disjoint<Segment, Areal, 2, segment_tag, areal_tag, false>
0278 : detail::disjoint::disjoint_segment_areal<Segment, Areal>
0279 {};
0280
0281
0282 }
0283 #endif
0284
0285
0286 }}
0287
0288
0289 #endif