Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:35:07

0001 // Boost.Geometry
0002 
0003 // Copyright (c) 2014-2021, Oracle and/or its affiliates.
0004 
0005 // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
0006 // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
0007 
0008 // Licensed under the Boost Software License version 1.0.
0009 // http://www.boost.org/users/license.html
0010 
0011 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP
0012 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP
0013 
0014 #include <sstream>
0015 #include <string>
0016 
0017 #include <boost/geometry/algorithms/detail/visit.hpp>
0018 #include <boost/geometry/algorithms/dispatch/is_valid.hpp>
0019 #include <boost/geometry/core/cs.hpp>
0020 #include <boost/geometry/core/visit.hpp>
0021 #include <boost/geometry/geometries/adapted/boost_variant.hpp> // For backward compatibility
0022 #include <boost/geometry/geometries/concepts/check.hpp>
0023 #include <boost/geometry/policies/is_valid/default_policy.hpp>
0024 #include <boost/geometry/policies/is_valid/failing_reason_policy.hpp>
0025 #include <boost/geometry/policies/is_valid/failure_type_policy.hpp>
0026 #include <boost/geometry/strategies/default_strategy.hpp>
0027 #include <boost/geometry/strategies/detail.hpp>
0028 #include <boost/geometry/strategies/relate/services.hpp>
0029 
0030 
0031 namespace boost { namespace geometry
0032 {
0033 
0034 namespace resolve_strategy
0035 {
0036 
0037 template
0038 <
0039     typename Strategy,
0040     bool IsUmbrella = strategies::detail::is_umbrella_strategy<Strategy>::value
0041 >
0042 struct is_valid
0043 {
0044     template <typename Geometry, typename VisitPolicy>
0045     static inline bool apply(Geometry const& geometry,
0046                              VisitPolicy& visitor,
0047                              Strategy const& strategy)
0048     {
0049         return dispatch::is_valid<Geometry>::apply(geometry, visitor, strategy);
0050     }
0051 
0052 };
0053 
0054 template <typename Strategy>
0055 struct is_valid<Strategy, false>
0056 {
0057     template <typename Geometry, typename VisitPolicy>
0058     static inline bool apply(Geometry const& geometry,
0059                              VisitPolicy& visitor,
0060                              Strategy const& strategy)
0061     {
0062         using strategies::relate::services::strategy_converter;
0063         return dispatch::is_valid
0064             <
0065                 Geometry
0066             >::apply(geometry, visitor,
0067                      strategy_converter<Strategy>::get(strategy));
0068     }
0069 };
0070 
0071 template <>
0072 struct is_valid<default_strategy, false>
0073 {
0074     template <typename Geometry, typename VisitPolicy>
0075     static inline bool apply(Geometry const& geometry,
0076                              VisitPolicy& visitor,
0077                              default_strategy)
0078     {
0079         // NOTE: Currently the strategy is only used for Areal geometries
0080         typedef typename strategies::relate::services::default_strategy
0081             <
0082                 Geometry, Geometry
0083             >::type strategy_type;
0084 
0085         return dispatch::is_valid<Geometry>::apply(geometry, visitor,
0086                                                    strategy_type());
0087     }
0088 };
0089 
0090 } // namespace resolve_strategy
0091 
0092 namespace resolve_dynamic
0093 {
0094 
0095 template <typename Geometry, typename Tag = typename tag<Geometry>::type>
0096 struct is_valid
0097 {
0098     template <typename VisitPolicy, typename Strategy>
0099     static inline bool apply(Geometry const& geometry,
0100                              VisitPolicy& visitor,
0101                              Strategy const& strategy)
0102     {
0103         concepts::check<Geometry const>();
0104 
0105         return resolve_strategy::is_valid
0106                 <
0107                     Strategy
0108                 >::apply(geometry, visitor, strategy);
0109     }
0110 };
0111 
0112 template <typename Geometry>
0113 struct is_valid<Geometry, dynamic_geometry_tag>
0114 {
0115     template <typename VisitPolicy, typename Strategy>
0116     static inline bool apply(Geometry const& geometry,
0117                              VisitPolicy& policy_visitor,
0118                              Strategy const& strategy)
0119     {
0120         bool result = true;
0121         traits::visit<Geometry>::apply([&](auto const& g)
0122         {
0123             result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
0124         }, geometry);
0125         return result;
0126     }
0127 };
0128 
0129 template <typename Geometry>
0130 struct is_valid<Geometry, geometry_collection_tag>
0131 {
0132     template <typename VisitPolicy, typename Strategy>
0133     static inline bool apply(Geometry const& geometry,
0134                              VisitPolicy& policy_visitor,
0135                              Strategy const& strategy)
0136     {
0137         bool result = true;
0138         detail::visit_breadth_first([&](auto const& g)
0139         {
0140             result = is_valid<util::remove_cref_t<decltype(g)>>::apply(g, policy_visitor, strategy);
0141             return result;
0142         }, geometry);
0143         return result;
0144     }
0145 };
0146 
0147 } // namespace resolve_dynamic
0148 
0149 
0150 // Undocumented for now
0151 template <typename Geometry, typename VisitPolicy, typename Strategy>
0152 inline bool is_valid(Geometry const& geometry,
0153                      VisitPolicy& visitor,
0154                      Strategy const& strategy)
0155 {
0156     return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
0157 }
0158 
0159 
0160 /*!
0161 \brief \brief_check{is valid (in the OGC sense)}
0162 \ingroup is_valid
0163 \tparam Geometry \tparam_geometry
0164 \tparam Strategy \tparam_strategy{Is_valid}
0165 \param geometry \param_geometry
0166 \param strategy \param_strategy{is_valid}
0167 \return \return_check{is valid (in the OGC sense);
0168 furthermore, the following geometries are considered valid:
0169 multi-geometries with no elements,
0170 linear geometries containing spikes,
0171 areal geometries with duplicate (consecutive) points}
0172 
0173 \qbk{distinguish,with strategy}
0174 \qbk{[include reference/algorithms/is_valid.qbk]}
0175 */
0176 template <typename Geometry, typename Strategy>
0177 inline bool is_valid(Geometry const& geometry, Strategy const& strategy)
0178 {
0179     is_valid_default_policy<> visitor;
0180     return resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
0181 }
0182 
0183 /*!
0184 \brief \brief_check{is valid (in the OGC sense)}
0185 \ingroup is_valid
0186 \tparam Geometry \tparam_geometry
0187 \param geometry \param_geometry
0188 \return \return_check{is valid (in the OGC sense);
0189     furthermore, the following geometries are considered valid:
0190     multi-geometries with no elements,
0191     linear geometries containing spikes,
0192     areal geometries with duplicate (consecutive) points}
0193 
0194 \qbk{[include reference/algorithms/is_valid.qbk]}
0195 */
0196 template <typename Geometry>
0197 inline bool is_valid(Geometry const& geometry)
0198 {
0199     return is_valid(geometry, default_strategy());
0200 }
0201 
0202 
0203 /*!
0204 \brief \brief_check{is valid (in the OGC sense)}
0205 \ingroup is_valid
0206 \tparam Geometry \tparam_geometry
0207 \tparam Strategy \tparam_strategy{Is_valid}
0208 \param geometry \param_geometry
0209 \param failure An enumeration value indicating that the geometry is
0210     valid or not, and if not valid indicating the reason why
0211 \param strategy \param_strategy{is_valid}
0212 \return \return_check{is valid (in the OGC sense);
0213     furthermore, the following geometries are considered valid:
0214     multi-geometries with no elements,
0215     linear geometries containing spikes,
0216     areal geometries with duplicate (consecutive) points}
0217 
0218 \qbk{distinguish,with failure value and strategy}
0219 \qbk{[include reference/algorithms/is_valid_with_failure.qbk]}
0220 */
0221 template <typename Geometry, typename Strategy>
0222 inline bool is_valid(Geometry const& geometry, validity_failure_type& failure, Strategy const& strategy)
0223 {
0224     failure_type_policy<> visitor;
0225     bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
0226     failure = visitor.failure();
0227     return result;
0228 }
0229 
0230 /*!
0231 \brief \brief_check{is valid (in the OGC sense)}
0232 \ingroup is_valid
0233 \tparam Geometry \tparam_geometry
0234 \param geometry \param_geometry
0235 \param failure An enumeration value indicating that the geometry is
0236     valid or not, and if not valid indicating the reason why
0237 \return \return_check{is valid (in the OGC sense);
0238     furthermore, the following geometries are considered valid:
0239     multi-geometries with no elements,
0240     linear geometries containing spikes,
0241     areal geometries with duplicate (consecutive) points}
0242 
0243 \qbk{distinguish,with failure value}
0244 \qbk{[include reference/algorithms/is_valid_with_failure.qbk]}
0245 */
0246 template <typename Geometry>
0247 inline bool is_valid(Geometry const& geometry, validity_failure_type& failure)
0248 {
0249     return is_valid(geometry, failure, default_strategy());
0250 }
0251 
0252 
0253 /*!
0254 \brief \brief_check{is valid (in the OGC sense)}
0255 \ingroup is_valid
0256 \tparam Geometry \tparam_geometry
0257 \tparam Strategy \tparam_strategy{Is_valid}
0258 \param geometry \param_geometry
0259 \param message A string containing a message stating if the geometry
0260     is valid or not, and if not valid a reason why
0261 \param strategy \param_strategy{is_valid}
0262 \return \return_check{is valid (in the OGC sense);
0263     furthermore, the following geometries are considered valid:
0264     multi-geometries with no elements,
0265     linear geometries containing spikes,
0266     areal geometries with duplicate (consecutive) points}
0267 
0268 \qbk{distinguish,with message and strategy}
0269 \qbk{[include reference/algorithms/is_valid_with_message.qbk]}
0270 */
0271 template <typename Geometry, typename Strategy>
0272 inline bool is_valid(Geometry const& geometry, std::string& message, Strategy const& strategy)
0273 {
0274     std::ostringstream stream;
0275     failing_reason_policy<> visitor(stream);
0276     bool result = resolve_dynamic::is_valid<Geometry>::apply(geometry, visitor, strategy);
0277     message = stream.str();
0278     return result;
0279 }
0280 
0281 /*!
0282 \brief \brief_check{is valid (in the OGC sense)}
0283 \ingroup is_valid
0284 \tparam Geometry \tparam_geometry
0285 \param geometry \param_geometry
0286 \param message A string containing a message stating if the geometry
0287     is valid or not, and if not valid a reason why
0288 \return \return_check{is valid (in the OGC sense);
0289     furthermore, the following geometries are considered valid:
0290     multi-geometries with no elements,
0291     linear geometries containing spikes,
0292     areal geometries with duplicate (consecutive) points}
0293 
0294 \qbk{distinguish,with message}
0295 \qbk{[include reference/algorithms/is_valid_with_message.qbk]}
0296 */
0297 template <typename Geometry>
0298 inline bool is_valid(Geometry const& geometry, std::string& message)
0299 {
0300     return is_valid(geometry, message, default_strategy());
0301 }
0302 
0303 
0304 }} // namespace boost::geometry
0305 
0306 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_INTERFACE_HPP