123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- // Boost.Geometry (aka GGL, Generic Geometry Library)
- // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
- // This file was modified by Oracle on 2017-2020.
- // Modifications copyright (c) 2017-2020, Oracle and/or its affiliates.
- // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
- // Use, modification and distribution is subject to the Boost Software License,
- // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
- #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
- #include <cstddef>
- #include <string>
- #include <boost/range/begin.hpp>
- #include <boost/range/end.hpp>
- #include <boost/range/value_type.hpp>
- #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
- #include <boost/geometry/algorithms/detail/has_self_intersections.hpp>
- #if defined(BOOST_GEOMETRY_DEBUG_INTERSECTION) || defined(BOOST_GEOMETRY_OVERLAY_REPORT_WKT)
- # include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
- # include <boost/geometry/io/wkt/wkt.hpp>
- #endif
- namespace boost { namespace geometry
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace overlay
- {
- template <typename Turns>
- inline void clear_visit_info(Turns& turns)
- {
- for (auto& turn : turns)
- {
- for (auto& op : turn.operations)
- {
- op.visited.clear();
- }
- }
- }
- struct backtrack_state
- {
- bool m_good;
- inline backtrack_state() : m_good(true) {}
- inline void reset() { m_good = true; }
- inline bool good() const { return m_good; }
- };
- enum traverse_error_type
- {
- traverse_error_none,
- traverse_error_no_next_ip_at_start,
- traverse_error_no_next_ip,
- traverse_error_dead_end_at_start,
- traverse_error_dead_end,
- traverse_error_visit_again,
- traverse_error_endless_loop
- };
- inline std::string traverse_error_string(traverse_error_type error)
- {
- switch (error)
- {
- case traverse_error_none : return "";
- case traverse_error_no_next_ip_at_start : return "No next IP at start";
- case traverse_error_no_next_ip : return "No next IP";
- case traverse_error_dead_end_at_start : return "Dead end at start";
- case traverse_error_dead_end : return "Dead end";
- case traverse_error_visit_again : return "Visit again";
- case traverse_error_endless_loop : return "Endless loop";
- default : return "";
- }
- return "";
- }
- template
- <
- typename Geometry1,
- typename Geometry2
- >
- class backtrack_check_self_intersections
- {
- struct state : public backtrack_state
- {
- bool m_checked;
- inline state()
- : m_checked(true)
- {}
- };
- public :
- typedef state state_type;
- template
- <
- typename Operation,
- typename Rings, typename Ring, typename Turns,
- typename Strategy,
- typename RobustPolicy,
- typename Visitor
- >
- static inline void apply(std::size_t size_at_start,
- Rings& rings,
- Ring& ring,
- Turns& turns,
- typename boost::range_value<Turns>::type const& turn,
- Operation& operation,
- traverse_error_type traverse_error,
- Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- Strategy const& strategy,
- RobustPolicy const& robust_policy,
- state_type& state,
- Visitor& visitor)
- {
- visitor.visit_traverse_reject(turns, turn, operation, traverse_error);
- state.m_good = false;
- // Check self-intersections and throw exception if appropriate
- if (! state.m_checked)
- {
- state.m_checked = true;
- has_self_intersections(geometry1, strategy, robust_policy);
- has_self_intersections(geometry2, strategy, robust_policy);
- }
- // Make bad output clean
- rings.resize(size_at_start);
- geometry::traits::clear<typename boost::range_value<Rings>::type>::apply(ring);
- // Reject this as a starting point
- operation.visited.set_rejected();
- // And clear all visit info
- clear_visit_info(turns);
- }
- };
- #ifdef BOOST_GEOMETRY_OVERLAY_REPORT_WKT
- template
- <
- typename Geometry1,
- typename Geometry2
- >
- class backtrack_debug
- {
- public :
- typedef backtrack_state state_type;
- template <typename Operation, typename Rings, typename Turns>
- static inline void apply(std::size_t size_at_start,
- Rings& rings, typename boost::range_value<Rings>::type& ring,
- Turns& turns, Operation& operation,
- std::string const& reason,
- Geometry1 const& geometry1,
- Geometry2 const& geometry2,
- state_type& state
- )
- {
- std::cout << " REJECT " << reason << std::endl;
- state.m_good = false;
- rings.resize(size_at_start);
- ring.clear();
- operation.visited.set_rejected();
- clear_visit_info(turns);
- int c = 0;
- for (int i = 0; i < turns.size(); i++)
- {
- for (int j = 0; j < 2; j++)
- {
- if (turns[i].operations[j].visited.rejected())
- {
- c++;
- }
- }
- }
- std::cout << "BACKTRACK (" << reason << " )"
- << " " << c << " of " << turns.size() << " rejected"
- << std::endl;
- std::cout
- << geometry::wkt(geometry1) << std::endl
- << geometry::wkt(geometry2) << std::endl;
- }
- };
- #endif // BOOST_GEOMETRY_OVERLAY_REPORT_WKT
- }} // namespace detail::overlay
- #endif // DOXYGEN_NO_DETAIL
- }} // namespace boost::geometry
- #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_BACKTRACK_CHECK_SI_HPP
|