File indexing completed on 2025-01-18 09:35:03
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 = typename tag<Geometry1>::type,
0065 typename Tag1OrMulti = typename tag_cast<Tag1, multi_tag>::type>
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 using point_type = typename point_type<Geometry1>::type;
0075 typename helper_geometry<point_type>::type p;
0076 geometry::point_on_border(p, g1);
0077
0078 return ! geometry::covered_by(p, g2, strategy);
0079 }
0080 };
0081
0082 template <typename Geometry1, typename Geometry2, typename Tag1>
0083 struct disjoint_no_intersections_policy<Geometry1, Geometry2, Tag1, multi_tag>
0084 {
0085
0086
0087
0088 template <typename Strategy>
0089 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0090 {
0091
0092 for (auto it = boost::begin(g1); it != boost::end(g1); ++it)
0093 {
0094 typedef typename boost::range_value<Geometry1 const>::type value_type;
0095 if (! disjoint_no_intersections_policy<value_type const, Geometry2>
0096 ::apply(*it, g2, strategy))
0097 {
0098 return false;
0099 }
0100 }
0101 return true;
0102 }
0103 };
0104
0105
0106 template<typename Geometry1, typename Geometry2,
0107 typename NoIntersectionsPolicy
0108 = disjoint_no_intersections_policy<Geometry1, Geometry2> >
0109 struct disjoint_linear_areal
0110 {
0111
0112
0113
0114 template <typename Strategy>
0115 static inline bool apply(Geometry1 const& g1, Geometry2 const& g2, Strategy const& strategy)
0116 {
0117
0118 if ( !disjoint_linear<Geometry1, Geometry2>::apply(g1, g2, strategy) )
0119 {
0120 return false;
0121 }
0122
0123 return NoIntersectionsPolicy::apply(g1, g2, strategy);
0124 }
0125 };
0126
0127
0128
0129
0130 template
0131 <
0132 typename Segment,
0133 typename Areal,
0134 typename Tag = typename tag<Areal>::type
0135 >
0136 struct disjoint_segment_areal
0137 : not_implemented<Segment, Areal>
0138 {};
0139
0140
0141 template <typename Segment, typename Polygon>
0142 class disjoint_segment_areal<Segment, Polygon, polygon_tag>
0143 {
0144
0145 template <typename InteriorRings, typename Strategy>
0146 static inline
0147 bool check_interior_rings(InteriorRings const& interior_rings,
0148 Segment const& segment,
0149 Strategy const& strategy)
0150 {
0151 using ring_type = typename boost::range_value<InteriorRings>::type;
0152
0153 using unary_predicate_type = unary_disjoint_geometry_to_query_geometry
0154 <
0155 Segment,
0156 Strategy,
0157 disjoint_range_segment_or_box<ring_type, Segment>
0158 >;
0159
0160 return std::all_of(boost::begin(interior_rings),
0161 boost::end(interior_rings),
0162 unary_predicate_type(segment, strategy));
0163 }
0164
0165
0166 public:
0167 template <typename IntersectionStrategy>
0168 static inline bool apply(Segment const& segment,
0169 Polygon const& polygon,
0170 IntersectionStrategy const& strategy)
0171 {
0172 if (! disjoint_range_segment_or_box
0173 <
0174 typename geometry::ring_type<Polygon>::type,
0175 Segment
0176 >::apply(geometry::exterior_ring(polygon), segment, strategy))
0177 {
0178 return false;
0179 }
0180
0181 if (! check_interior_rings(geometry::interior_rings(polygon), segment, strategy))
0182 {
0183 return false;
0184 }
0185
0186 typename point_type<Segment>::type p;
0187 detail::assign_point_from_index<0>(segment, p);
0188
0189 return ! geometry::covered_by(p, polygon, strategy);
0190 }
0191 };
0192
0193
0194 template <typename Segment, typename MultiPolygon>
0195 struct disjoint_segment_areal<Segment, MultiPolygon, multi_polygon_tag>
0196 {
0197 template <typename IntersectionStrategy>
0198 static inline bool apply(Segment const& segment, MultiPolygon const& multipolygon,
0199 IntersectionStrategy const& strategy)
0200 {
0201 return multirange_constant_size_geometry
0202 <
0203 MultiPolygon, Segment
0204 >::apply(multipolygon, segment, strategy);
0205 }
0206 };
0207
0208
0209 template <typename Segment, typename Ring>
0210 struct disjoint_segment_areal<Segment, Ring, ring_tag>
0211 {
0212 template <typename IntersectionStrategy>
0213 static inline bool apply(Segment const& segment,
0214 Ring const& ring,
0215 IntersectionStrategy const& strategy)
0216 {
0217 if (! disjoint_range_segment_or_box<Ring, Segment>::apply(ring, segment, strategy))
0218 {
0219 return false;
0220 }
0221
0222 typename point_type<Segment>::type p;
0223 detail::assign_point_from_index<0>(segment, p);
0224
0225 return ! geometry::covered_by(p, ring, strategy);
0226 }
0227 };
0228
0229
0230 }}
0231 #endif
0232
0233
0234
0235
0236 #ifndef DOXYGEN_NO_DISPATCH
0237 namespace dispatch
0238 {
0239
0240
0241 template <typename Linear, typename Areal>
0242 struct disjoint<Linear, Areal, 2, linear_tag, areal_tag, false>
0243 : public detail::disjoint::disjoint_linear_areal<Linear, Areal>
0244 {};
0245
0246
0247 template <typename Areal, typename Linear>
0248 struct disjoint<Areal, Linear, 2, areal_tag, linear_tag, false>
0249 {
0250 template <typename Strategy>
0251 static inline bool apply(Areal const& areal, Linear const& linear,
0252 Strategy const& strategy)
0253 {
0254 return detail::disjoint::disjoint_linear_areal
0255 <
0256 Linear, Areal
0257 >::apply(linear, areal, strategy);
0258 }
0259 };
0260
0261
0262 template <typename Areal, typename Segment>
0263 struct disjoint<Areal, Segment, 2, areal_tag, segment_tag, false>
0264 {
0265 template <typename Strategy>
0266 static inline bool apply(Areal const& g1, Segment const& g2,
0267 Strategy const& strategy)
0268 {
0269 return detail::disjoint::disjoint_segment_areal
0270 <
0271 Segment, Areal
0272 >::apply(g2, g1, strategy);
0273 }
0274 };
0275
0276
0277 template <typename Segment, typename Areal>
0278 struct disjoint<Segment, Areal, 2, segment_tag, areal_tag, false>
0279 : detail::disjoint::disjoint_segment_areal<Segment, Areal>
0280 {};
0281
0282
0283 }
0284 #endif
0285
0286
0287 }}
0288
0289
0290 #endif