123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DISCARD_DUPLICATE_TURNS_HPP
- #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DISCARD_DUPLICATE_TURNS_HPP
- #include <map>
- #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
- #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp>
- namespace boost { namespace geometry
- {
- #ifndef DOXYGEN_NO_DETAIL
- namespace detail { namespace overlay
- {
- inline bool same_multi_and_ring_id(segment_identifier const& first,
- segment_identifier const& second)
- {
- return first.ring_index == second.ring_index
- && first.multi_index == second.multi_index;
- }
- template <typename Geometry0, typename Geometry1>
- inline bool is_consecutive(segment_identifier const& first,
- segment_identifier const& second,
- Geometry0 const& geometry0,
- Geometry1 const& geometry1)
- {
- if (first.source_index == second.source_index
- && first.ring_index == second.ring_index
- && first.multi_index == second.multi_index)
- {
-
-
- signed_size_type const sd = first.source_index == 0
- ? segment_distance(geometry0, first, second)
- : segment_distance(geometry1, first, second);
- return sd <= 1;
- }
- return false;
- }
- template <typename Turn, typename Geometry0, typename Geometry1>
- inline bool corresponding_turn(Turn const& turn, Turn const& start_turn,
- Geometry0 const& geometry0,
- Geometry1 const& geometry1)
- {
- std::size_t count = 0;
- for (std::size_t i = 0; i < 2; i++)
- {
- for (std::size_t j = 0; j < 2; j++)
- {
- if (same_multi_and_ring_id(turn.operations[i].seg_id,
- start_turn.operations[j].seg_id))
- {
-
- if (is_consecutive(turn.operations[i].seg_id,
- start_turn.operations[j].seg_id,
- geometry0, geometry1)
- && is_consecutive(turn.operations[1 - i].seg_id,
- start_turn.operations[1 - j].seg_id,
- geometry0, geometry1))
- {
- count++;
- }
- }
- }
- }
-
-
- return count == 2;
- }
- template <typename Turns, typename Geometry0, typename Geometry1>
- inline void discard_duplicate_start_turns(Turns& turns,
- Geometry0 const& geometry0,
- Geometry1 const& geometry1)
- {
-
-
-
-
-
-
- using multi_and_ring_id_type = std::pair<signed_size_type, signed_size_type>;
- auto adapt_id = [](segment_identifier const& seg_id)
- {
- return multi_and_ring_id_type{seg_id.multi_index, seg_id.ring_index};
- };
-
- std::map<multi_and_ring_id_type, std::vector<std::size_t>> start_turns_per_segment;
- std::size_t index = 0;
- for (auto const& turn : turns)
- {
- if (turn.method == method_start)
- {
- for (auto const& op : turn.operations)
- {
- start_turns_per_segment[adapt_id(op.seg_id)].push_back(index);
- }
- }
- index++;
- }
-
-
- for (auto const& turn : turns)
- {
-
-
- if (turn.method != method_crosses && turn.method != method_start)
- {
- for (auto const& op : turn.operations)
- {
- auto it = start_turns_per_segment.find(adapt_id(op.seg_id));
- if (it != start_turns_per_segment.end())
- {
- for (std::size_t const& i : it->second)
- {
- if (turns[i].cluster_id != turn.cluster_id)
- {
-
-
-
- continue;
- }
- if (corresponding_turn(turn, turns[i],
- geometry0, geometry1))
- {
- turns[i].discarded = true;
- }
- }
- }
- }
- }
- index++;
- }
- }
- }}
- #endif
- }}
- #endif
|