// Boost.Geometry (aka GGL, Generic Geometry Library) // Copyright (c) 2014-2017, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_LINEAR_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_LINEAR_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace is_valid { template struct is_valid_linestring { template static inline bool apply(Linestring const& linestring, VisitPolicy& visitor, Strategy const& strategy) { if (has_invalid_coordinate::apply(linestring, visitor)) { return false; } if (boost::size(linestring) < 2) { return visitor.template apply(); } std::size_t num_distinct = detail::num_distinct_consecutive_points < Linestring, 3u, true, not_equal_to::type> >::apply(linestring); if (num_distinct < 2u) { return visitor.template apply(); } if (num_distinct == 2u) { return visitor.template apply(); } return ! has_spikes < Linestring, closed >::apply(linestring, visitor, strategy.get_side_strategy()); } }; }} // namespace detail::is_valid #endif // DOXYGEN_NO_DETAIL #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { // A linestring is a curve. // A curve is 1-dimensional so it has to have at least two distinct // points. // A curve is simple if it does not pass through the same point twice, // with the possible exception of its two endpoints // // There is an option here as to whether spikes are allowed for linestrings; // here we pass this as an additional template parameter: allow_spikes // If allow_spikes is set to true, spikes are allowed, false otherwise. // By default, spikes are disallowed // // Reference: OGC 06-103r4 (6.1.6.1) template struct is_valid < Linestring, linestring_tag, AllowEmptyMultiGeometries > : detail::is_valid::is_valid_linestring {}; // A MultiLinestring is a MultiCurve // A MultiCurve is simple if all of its elements are simple and the // only intersections between any two elements occur at Points that // are on the boundaries of both elements. // // Reference: OGC 06-103r4 (6.1.8.1; Fig. 9) template class is_valid < MultiLinestring, multi_linestring_tag, AllowEmptyMultiGeometries > { private: template struct per_linestring { per_linestring(VisitPolicy& policy, Strategy const& strategy) : m_policy(policy) , m_strategy(strategy) {} template inline bool apply(Linestring const& linestring) const { return detail::is_valid::is_valid_linestring < Linestring >::apply(linestring, m_policy, m_strategy); } VisitPolicy& m_policy; Strategy const& m_strategy; }; public: template static inline bool apply(MultiLinestring const& multilinestring, VisitPolicy& visitor, Strategy const& strategy) { if (BOOST_GEOMETRY_CONDITION( AllowEmptyMultiGeometries && boost::empty(multilinestring))) { return visitor.template apply(); } typedef per_linestring per_ls; return detail::check_iterator_range < per_ls, false // do not check for empty multilinestring (done above) >::apply(boost::begin(multilinestring), boost::end(multilinestring), per_ls(visitor, strategy)); } }; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_IS_VALID_LINEAR_HPP