File indexing completed on 2025-01-18 09:35:20
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020 #ifndef BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
0021 #define BOOST_GEOMETRY_ALGORITHMS_CROSSES_HPP
0022
0023 #include <cstddef>
0024
0025 #include <boost/geometry/algorithms/detail/gc_topological_dimension.hpp>
0026 #include <boost/geometry/algorithms/detail/relate/relate_impl.hpp>
0027 #include <boost/geometry/algorithms/relate.hpp>
0028 #include <boost/geometry/core/access.hpp>
0029 #include <boost/geometry/geometries/adapted/boost_variant.hpp>
0030 #include <boost/geometry/geometries/concepts/check.hpp>
0031 #include <boost/geometry/strategies/default_strategy.hpp>
0032 #include <boost/geometry/strategies/detail.hpp>
0033 #include <boost/geometry/strategies/relate/cartesian.hpp>
0034 #include <boost/geometry/strategies/relate/geographic.hpp>
0035 #include <boost/geometry/strategies/relate/spherical.hpp>
0036 #include <boost/geometry/views/detail/geometry_collection_view.hpp>
0037
0038
0039 namespace boost { namespace geometry
0040 {
0041
0042 #ifndef DOXYGEN_NO_DISPATCH
0043 namespace dispatch
0044 {
0045
0046
0047 template
0048 <
0049 typename Geometry1,
0050 typename Geometry2,
0051 typename Tag1 = typename tag<Geometry1>::type,
0052 typename Tag2 = typename tag<Geometry2>::type
0053 >
0054 struct crosses
0055 : detail::relate::relate_impl
0056 <
0057 detail::de9im::static_mask_crosses_type,
0058 Geometry1,
0059 Geometry2
0060 >
0061 {};
0062
0063
0064 template <typename Geometry1, typename Geometry2>
0065 struct crosses<Geometry1, Geometry2, geometry_collection_tag, geometry_collection_tag>
0066 {
0067 template <typename Strategy>
0068 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0069 Strategy const& strategy)
0070 {
0071 int const dimension1 = detail::gc_topological_dimension(geometry1);
0072 int const dimension2 = detail::gc_topological_dimension(geometry2);
0073
0074 if (dimension1 >= 0 && dimension2 >= 0)
0075 {
0076 if (dimension1 < dimension2)
0077 {
0078 return detail::relate::relate_impl
0079 <
0080 detail::de9im::static_mask_crosses_d1_le_d2_type,
0081 Geometry1,
0082 Geometry2
0083 >::apply(geometry1, geometry2, strategy);
0084 }
0085 else if (dimension1 > dimension2)
0086 {
0087 return detail::relate::relate_impl
0088 <
0089 detail::de9im::static_mask_crosses_d2_le_d1_type,
0090 Geometry1,
0091 Geometry2
0092 >::apply(geometry1, geometry2, strategy);
0093 }
0094 else if (dimension1 == 1 && dimension2 == 1)
0095 {
0096 return detail::relate::relate_impl
0097 <
0098 detail::de9im::static_mask_crosses_d1_1_d2_1_type,
0099 Geometry1,
0100 Geometry2
0101 >::apply(geometry1, geometry2, strategy);
0102 }
0103 }
0104
0105 return false;
0106 }
0107 };
0108
0109 template <typename Geometry1, typename Geometry2, typename Tag1>
0110 struct crosses<Geometry1, Geometry2, Tag1, geometry_collection_tag>
0111 {
0112 template <typename Strategy>
0113 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0114 Strategy const& strategy)
0115 {
0116 using gc1_view_t = detail::geometry_collection_view<Geometry1>;
0117 return crosses
0118 <
0119 gc1_view_t, Geometry2
0120 >::apply(gc1_view_t(geometry1), geometry2, strategy);
0121 }
0122 };
0123
0124 template <typename Geometry1, typename Geometry2, typename Tag2>
0125 struct crosses<Geometry1, Geometry2, geometry_collection_tag, Tag2>
0126 {
0127 template <typename Strategy>
0128 static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2,
0129 Strategy const& strategy)
0130 {
0131 using gc2_view_t = detail::geometry_collection_view<Geometry2>;
0132 return crosses
0133 <
0134 Geometry1, gc2_view_t
0135 >::apply(geometry1, gc2_view_t(geometry2), strategy);
0136 }
0137 };
0138
0139
0140 }
0141 #endif
0142
0143
0144 namespace resolve_strategy
0145 {
0146
0147 template
0148 <
0149 typename Strategy,
0150 bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0151 >
0152 struct crosses
0153 {
0154 template <typename Geometry1, typename Geometry2>
0155 static inline bool apply(Geometry1 const& geometry1,
0156 Geometry2 const& geometry2,
0157 Strategy const& strategy)
0158 {
0159 concepts::check<Geometry1 const>();
0160 concepts::check<Geometry2 const>();
0161
0162 return dispatch::crosses
0163 <
0164 Geometry1, Geometry2
0165 >::apply(geometry1, geometry2, strategy);
0166 }
0167 };
0168
0169 template <typename Strategy>
0170 struct crosses<Strategy, false>
0171 {
0172 template <typename Geometry1, typename Geometry2>
0173 static inline bool apply(Geometry1 const& geometry1,
0174 Geometry2 const& geometry2,
0175 Strategy const& strategy)
0176 {
0177
0178 using strategies::relate::services::strategy_converter;
0179 return crosses
0180 <
0181 decltype(strategy_converter<Strategy>::get(strategy))
0182 >::apply(geometry1, geometry2,
0183 strategy_converter<Strategy>::get(strategy));
0184 }
0185 };
0186
0187 template <>
0188 struct crosses<default_strategy, false>
0189 {
0190 template <typename Geometry1, typename Geometry2>
0191 static inline bool apply(Geometry1 const& geometry1,
0192 Geometry2 const& geometry2,
0193 default_strategy)
0194 {
0195
0196 typedef typename strategies::relate::services::default_strategy
0197 <
0198 Geometry1,
0199 Geometry2
0200 >::type strategy_type;
0201
0202 return crosses
0203 <
0204 strategy_type
0205 >::apply(geometry1, geometry2, strategy_type());
0206 }
0207 };
0208
0209 }
0210
0211
0212 namespace resolve_dynamic
0213 {
0214
0215 template
0216 <
0217 typename Geometry1, typename Geometry2,
0218 typename Tag1 = typename geometry::tag<Geometry1>::type,
0219 typename Tag2 = typename geometry::tag<Geometry2>::type
0220 >
0221 struct crosses
0222 {
0223 template <typename Strategy>
0224 static inline bool apply(Geometry1 const& geometry1,
0225 Geometry2 const& geometry2,
0226 Strategy const& strategy)
0227 {
0228 return resolve_strategy::crosses
0229 <
0230 Strategy
0231 >::apply(geometry1, geometry2, strategy);
0232 }
0233 };
0234
0235
0236 template <typename DynamicGeometry1, typename Geometry2, typename Tag2>
0237 struct crosses<DynamicGeometry1, Geometry2, dynamic_geometry_tag, Tag2>
0238 {
0239 template <typename Strategy>
0240 static inline bool apply(DynamicGeometry1 const& geometry1,
0241 Geometry2 const& geometry2,
0242 Strategy const& strategy)
0243 {
0244 bool result = false;
0245 traits::visit<DynamicGeometry1>::apply([&](auto const& g1)
0246 {
0247 result = resolve_strategy::crosses
0248 <
0249 Strategy
0250 >::apply(g1, geometry2, strategy);
0251 }, geometry1);
0252 return result;
0253 }
0254 };
0255
0256
0257 template <typename Geometry1, typename DynamicGeometry2, typename Tag1>
0258 struct crosses<Geometry1, DynamicGeometry2, Tag1, dynamic_geometry_tag>
0259 {
0260 template <typename Strategy>
0261 static inline bool apply(Geometry1 const& geometry1,
0262 DynamicGeometry2 const& geometry2,
0263 Strategy const& strategy)
0264 {
0265 bool result = false;
0266 traits::visit<DynamicGeometry2>::apply([&](auto const& g2)
0267 {
0268 result = resolve_strategy::crosses
0269 <
0270 Strategy
0271 >::apply(geometry1, g2, strategy);
0272 }, geometry2);
0273 return result;
0274 }
0275 };
0276
0277
0278 template <typename DynamicGeometry1, typename DynamicGeometry2>
0279 struct crosses<DynamicGeometry1, DynamicGeometry2, dynamic_geometry_tag, dynamic_geometry_tag>
0280 {
0281 template <typename Strategy>
0282 static inline bool apply(DynamicGeometry1 const& geometry1,
0283 DynamicGeometry2 const& geometry2,
0284 Strategy const& strategy)
0285 {
0286 bool result = false;
0287 traits::visit<DynamicGeometry1, DynamicGeometry2>::apply([&](auto const& g1, auto const& g2)
0288 {
0289 result = resolve_strategy::crosses
0290 <
0291 Strategy
0292 >::apply(g1, g2, strategy);
0293 }, geometry1, geometry2);
0294 return result;
0295 }
0296 };
0297
0298
0299 }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316 template <typename Geometry1, typename Geometry2, typename Strategy>
0317 inline bool crosses(Geometry1 const& geometry1,
0318 Geometry2 const& geometry2,
0319 Strategy const& strategy)
0320 {
0321 return resolve_dynamic::crosses
0322 <
0323 Geometry1, Geometry2
0324 >::apply(geometry1, geometry2, strategy);
0325 }
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343 template <typename Geometry1, typename Geometry2>
0344 inline bool crosses(Geometry1 const& geometry1, Geometry2 const& geometry2)
0345 {
0346 return resolve_dynamic::crosses
0347 <
0348 Geometry1, Geometry2
0349 >::apply(geometry1, geometry2, default_strategy());
0350 }
0351
0352 }}
0353
0354 #endif