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