File indexing completed on 2025-12-16 09:51:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
0012 #define BOOST_GEOMETRY_STRATEGIES_RELATE_CARTESIAN_HPP
0013
0014
0015
0016 #include <boost/geometry/strategies/agnostic/point_in_box_by_side.hpp>
0017 #include <boost/geometry/strategies/cartesian/intersection.hpp>
0018 #include <boost/geometry/strategies/cartesian/box_in_box.hpp>
0019 #include <boost/geometry/strategies/cartesian/point_in_point.hpp>
0020 #include <boost/geometry/strategies/cartesian/point_in_poly_crossings_multiply.hpp>
0021 #include <boost/geometry/strategies/cartesian/point_in_poly_franklin.hpp>
0022 #include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
0023 #include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
0024
0025 #include <boost/geometry/strategies/distance/detail.hpp>
0026 #include <boost/geometry/strategies/distance/services.hpp>
0027 #include <boost/geometry/strategies/envelope/cartesian.hpp>
0028 #include <boost/geometry/strategies/relate/services.hpp>
0029 #include <boost/geometry/strategies/detail.hpp>
0030
0031 #include <boost/geometry/strategy/cartesian/area.hpp>
0032 #include <boost/geometry/strategy/cartesian/side_robust.hpp>
0033 #include <boost/geometry/strategy/cartesian/side_by_triangle.hpp>
0034 #include <boost/geometry/strategy/cartesian/area_box.hpp>
0035
0036 #include <boost/geometry/util/type_traits.hpp>
0037
0038
0039 namespace boost { namespace geometry
0040 {
0041
0042 namespace strategies { namespace relate
0043 {
0044
0045 template <typename CalculationType = void>
0046 class cartesian
0047 : public strategies::envelope::cartesian<CalculationType>
0048 {
0049 public:
0050
0051
0052 template <typename Geometry>
0053 static auto area(Geometry const&,
0054 std::enable_if_t<! util::is_box<Geometry>::value> * = nullptr)
0055 {
0056 return strategy::area::cartesian<CalculationType>();
0057 }
0058
0059 template <typename Geometry>
0060 static auto area(Geometry const&,
0061 std::enable_if_t<util::is_box<Geometry>::value> * = nullptr)
0062 {
0063 return strategy::area::cartesian_box<CalculationType>();
0064 }
0065
0066
0067
0068 template <typename Geometry1, typename Geometry2>
0069 static auto covered_by(Geometry1 const&, Geometry2 const&,
0070 std::enable_if_t
0071 <
0072 util::is_pointlike<Geometry1>::value
0073 && util::is_box<Geometry2>::value
0074 > * = nullptr)
0075 {
0076 return strategy::covered_by::cartesian_point_box();
0077 }
0078
0079 template <typename Geometry1, typename Geometry2>
0080 static auto covered_by(Geometry1 const&, Geometry2 const&,
0081 std::enable_if_t
0082 <
0083 util::is_box<Geometry1>::value
0084 && util::is_box<Geometry2>::value
0085 > * = nullptr)
0086 {
0087 return strategy::covered_by::cartesian_box_box();
0088 }
0089
0090
0091
0092 template <typename Geometry1, typename Geometry2>
0093 static auto disjoint(Geometry1 const&, Geometry2 const&,
0094 std::enable_if_t
0095 <
0096 util::is_box<Geometry1>::value
0097 && util::is_box<Geometry2>::value
0098 > * = nullptr)
0099 {
0100 return strategy::disjoint::cartesian_box_box();
0101 }
0102
0103 template <typename Geometry1, typename Geometry2>
0104 static auto disjoint(Geometry1 const&, Geometry2 const&,
0105 std::enable_if_t
0106 <
0107 util::is_segment<Geometry1>::value
0108 && util::is_box<Geometry2>::value
0109 > * = nullptr)
0110 {
0111
0112 return strategy::disjoint::segment_box();
0113 }
0114
0115
0116
0117 template <typename Geometry1, typename Geometry2>
0118 static auto relate(Geometry1 const&, Geometry2 const&,
0119 std::enable_if_t
0120 <
0121 util::is_pointlike<Geometry1>::value
0122 && util::is_pointlike<Geometry2>::value
0123 > * = nullptr)
0124 {
0125 return strategy::within::cartesian_point_point();
0126 }
0127
0128 template <typename Geometry1, typename Geometry2>
0129 static auto relate(Geometry1 const&, Geometry2 const&,
0130 std::enable_if_t
0131 <
0132 util::is_pointlike<Geometry1>::value
0133 && ( util::is_linear<Geometry2>::value
0134 || util::is_polygonal<Geometry2>::value )
0135 > * = nullptr)
0136 {
0137 return strategy::within::cartesian_winding<void, void, CalculationType>();
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148 static auto relate(
0149
0150
0151
0152
0153
0154
0155 )
0156 {
0157 return strategy::intersection::cartesian_segments<CalculationType>();
0158 }
0159
0160 template <typename Geometry1, typename Geometry2>
0161 static auto comparable_distance(Geometry1 const&, Geometry2 const&,
0162 distance::detail::enable_if_pp_t<Geometry1, Geometry2> * = nullptr)
0163 {
0164 return strategy::distance::comparable::pythagoras<CalculationType>();
0165 }
0166
0167
0168
0169 static auto side()
0170 {
0171 using side_strategy_type
0172 = typename strategy::side::services::default_strategy
0173 <cartesian_tag, CalculationType>::type;
0174 return side_strategy_type();
0175 }
0176
0177
0178
0179 template <typename Geometry1, typename Geometry2>
0180 static auto within(Geometry1 const&, Geometry2 const&,
0181 std::enable_if_t
0182 <
0183 util::is_pointlike<Geometry1>::value
0184 && util::is_box<Geometry2>::value
0185 > * = nullptr)
0186 {
0187 return strategy::within::cartesian_point_box();
0188 }
0189
0190 template <typename Geometry1, typename Geometry2>
0191 static auto within(Geometry1 const&, Geometry2 const&,
0192 std::enable_if_t
0193 <
0194 util::is_box<Geometry1>::value
0195 && util::is_box<Geometry2>::value
0196 > * = nullptr)
0197 {
0198 return strategy::within::cartesian_box_box();
0199 }
0200
0201 template <typename ComparePolicy, typename EqualsPolicy>
0202 using compare_type = typename strategy::compare::cartesian
0203 <
0204 ComparePolicy,
0205 EqualsPolicy,
0206 -1
0207 >;
0208 };
0209
0210
0211 namespace services
0212 {
0213
0214 template <typename Geometry1, typename Geometry2>
0215 struct default_strategy<Geometry1, Geometry2, cartesian_tag, cartesian_tag>
0216 {
0217 using type = strategies::relate::cartesian<>;
0218 };
0219
0220
0221 template <>
0222 struct strategy_converter<strategy::within::cartesian_point_point>
0223 {
0224 static auto get(strategy::within::cartesian_point_point const& )
0225 {
0226 return strategies::relate::cartesian<>();
0227 }
0228 };
0229
0230 template <>
0231 struct strategy_converter<strategy::within::cartesian_point_box>
0232 {
0233 static auto get(strategy::within::cartesian_point_box const&)
0234 {
0235 return strategies::relate::cartesian<>();
0236 }
0237 };
0238
0239 template <>
0240 struct strategy_converter<strategy::covered_by::cartesian_point_box>
0241 {
0242 static auto get(strategy::covered_by::cartesian_point_box const&)
0243 {
0244 return strategies::relate::cartesian<>();
0245 }
0246 };
0247
0248 template <>
0249 struct strategy_converter<strategy::covered_by::cartesian_box_box>
0250 {
0251 static auto get(strategy::covered_by::cartesian_box_box const&)
0252 {
0253 return strategies::relate::cartesian<>();
0254 }
0255 };
0256
0257 template <>
0258 struct strategy_converter<strategy::disjoint::cartesian_box_box>
0259 {
0260 static auto get(strategy::disjoint::cartesian_box_box const&)
0261 {
0262 return strategies::relate::cartesian<>();
0263 }
0264 };
0265
0266 template <>
0267 struct strategy_converter<strategy::disjoint::segment_box>
0268 {
0269 static auto get(strategy::disjoint::segment_box const&)
0270 {
0271 return strategies::relate::cartesian<>();
0272 }
0273 };
0274
0275 template <>
0276 struct strategy_converter<strategy::within::cartesian_box_box>
0277 {
0278 static auto get(strategy::within::cartesian_box_box const&)
0279 {
0280 return strategies::relate::cartesian<>();
0281 }
0282 };
0283
0284 template <typename P1, typename P2, typename CalculationType>
0285 struct strategy_converter<strategy::within::cartesian_winding<P1, P2, CalculationType>>
0286 {
0287 static auto get(strategy::within::cartesian_winding<P1, P2, CalculationType> const& )
0288 {
0289 return strategies::relate::cartesian<CalculationType>();
0290 }
0291 };
0292
0293 template <typename CalculationType>
0294 struct strategy_converter<strategy::intersection::cartesian_segments<CalculationType>>
0295 {
0296 static auto get(strategy::intersection::cartesian_segments<CalculationType> const& )
0297 {
0298 return strategies::relate::cartesian<CalculationType>();
0299 }
0300 };
0301
0302 template <typename CalculationType>
0303 struct strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
0304 {
0305 struct altered_strategy
0306 : strategies::relate::cartesian<CalculationType>
0307 {
0308 template <typename Geometry1, typename Geometry2>
0309 static auto covered_by(Geometry1 const&, Geometry2 const&,
0310 std::enable_if_t
0311 <
0312 util::is_pointlike<Geometry1>::value
0313 && util::is_box<Geometry2>::value
0314 > * = nullptr)
0315 {
0316 return strategy::covered_by::cartesian_point_box_by_side<CalculationType>();
0317 }
0318
0319 template <typename Geometry1, typename Geometry2>
0320 static auto within(Geometry1 const&, Geometry2 const&,
0321 std::enable_if_t
0322 <
0323 util::is_pointlike<Geometry1>::value
0324 && util::is_box<Geometry2>::value
0325 > * = nullptr)
0326 {
0327 return strategy::within::cartesian_point_box_by_side<CalculationType>();
0328 }
0329 };
0330
0331 static auto get(strategy::covered_by::cartesian_point_box_by_side<CalculationType> const&)
0332 {
0333 return altered_strategy();
0334 }
0335
0336 static auto get(strategy::within::cartesian_point_box_by_side<CalculationType> const&)
0337 {
0338 return altered_strategy();
0339 }
0340 };
0341
0342 template <typename CalculationType>
0343 struct strategy_converter<strategy::covered_by::cartesian_point_box_by_side<CalculationType>>
0344 : strategy_converter<strategy::within::cartesian_point_box_by_side<CalculationType>>
0345 {};
0346
0347 template <typename P1, typename P2, typename CalculationType>
0348 struct strategy_converter<strategy::within::franklin<P1, P2, CalculationType>>
0349 {
0350 struct altered_strategy
0351 : strategies::relate::cartesian<CalculationType>
0352 {
0353 template <typename Geometry1, typename Geometry2>
0354 static auto relate(Geometry1 const&, Geometry2 const&,
0355 std::enable_if_t
0356 <
0357 util::is_pointlike<Geometry1>::value
0358 && ( util::is_linear<Geometry2>::value
0359 || util::is_polygonal<Geometry2>::value )
0360 > * = nullptr)
0361 {
0362 return strategy::within::franklin<void, void, CalculationType>();
0363 }
0364 };
0365
0366 static auto get(strategy::within::franklin<P1, P2, CalculationType> const&)
0367 {
0368 return altered_strategy();
0369 }
0370 };
0371
0372 template <typename P1, typename P2, typename CalculationType>
0373 struct strategy_converter<strategy::within::crossings_multiply<P1, P2, CalculationType>>
0374 {
0375 struct altered_strategy
0376 : strategies::relate::cartesian<CalculationType>
0377 {
0378 template <typename Geometry1, typename Geometry2>
0379 static auto relate(Geometry1 const&, Geometry2 const&,
0380 std::enable_if_t
0381 <
0382 util::is_pointlike<Geometry1>::value
0383 && ( util::is_linear<Geometry2>::value
0384 || util::is_polygonal<Geometry2>::value )
0385 > * = nullptr)
0386 {
0387 return strategy::within::crossings_multiply<void, void, CalculationType>();
0388 }
0389 };
0390
0391 static auto get(strategy::within::crossings_multiply<P1, P2, CalculationType> const&)
0392 {
0393 return altered_strategy();
0394 }
0395 };
0396
0397
0398 template <typename CalculationType>
0399 struct strategy_converter<strategy::side::side_by_triangle<CalculationType>>
0400 {
0401 static auto get(strategy::side::side_by_triangle<CalculationType> const&)
0402 {
0403 return strategies::relate::cartesian<CalculationType>();
0404 }
0405 };
0406
0407 template <typename CalculationType>
0408 struct strategy_converter<strategy::side::side_robust<CalculationType>>
0409 {
0410 static auto get(strategy::side::side_robust<CalculationType> const&)
0411 {
0412 return strategies::relate::cartesian<CalculationType>();
0413 }
0414 };
0415
0416
0417 }
0418
0419 }}
0420
0421 }}
0422
0423 #endif