forked from boostorg/geometry
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[clusters] detection is refactored to a simpler sweeping algorithm
This fixes a part (around 30%) of the remaining errors in the recursive buffer check
- Loading branch information
1 parent
29a6a9f
commit eee7fc5
Showing
22 changed files
with
738 additions
and
483 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
include/boost/geometry/algorithms/detail/overlay/approximately_equals.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
// Boost.Geometry (aka GGL, Generic Geometry Library) | ||
|
||
// Copyright (c) 2021 Barend Gehrels, Amsterdam, the Netherlands. | ||
|
||
// 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_APPROXIMATELY_EQUALS_HPP | ||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPROXIMATELY_EQUALS_HPP | ||
|
||
#include <boost/geometry/core/access.hpp> | ||
#include <boost/geometry/util/math.hpp> | ||
#include <boost/geometry/util/select_coordinate_type.hpp> | ||
#include <boost/geometry/util/select_most_precise.hpp> | ||
|
||
namespace boost { namespace geometry | ||
{ | ||
|
||
#ifndef DOXYGEN_NO_DETAIL | ||
namespace detail { namespace overlay | ||
{ | ||
|
||
template <typename Point1, typename Point2, typename E> | ||
inline bool approximately_equals(Point1 const& a, Point2 const& b, | ||
E const& multiplier) | ||
{ | ||
using coor_t = typename select_coordinate_type<Point1, Point2>::type; | ||
using calc_t = typename geometry::select_most_precise<coor_t, E>::type; | ||
|
||
calc_t const& a0 = geometry::get<0>(a); | ||
calc_t const& b0 = geometry::get<0>(b); | ||
calc_t const& a1 = geometry::get<1>(a); | ||
calc_t const& b1 = geometry::get<1>(b); | ||
|
||
math::detail::equals_factor_policy<calc_t> policy(a0, b0, a1, b1); | ||
policy.factor *= multiplier; | ||
|
||
return math::detail::equals_by_policy(a0, b0, policy) | ||
&& math::detail::equals_by_policy(a1, b1, policy); | ||
} | ||
|
||
}} // namespace detail::overlay | ||
#endif //DOXYGEN_NO_DETAIL | ||
|
||
|
||
}} // namespace boost::geometry | ||
|
||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPROXIMATELY_EQUALS_HPP |
132 changes: 132 additions & 0 deletions
132
include/boost/geometry/algorithms/detail/overlay/discard_duplicate_turns.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
// Boost.Geometry (aka GGL, Generic Geometry Library) | ||
|
||
// Copyright (c) 2021 Barend Gehrels, Amsterdam, the Netherlands. | ||
|
||
// 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_DISCARD_DUPLICATE_TURNS_HPP | ||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DISCARD_DUPLICATE_TURNS_HPP | ||
|
||
#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 | ||
{ | ||
|
||
|
||
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.piece_index == second.piece_index | ||
&& first.multi_index == second.multi_index) | ||
{ | ||
// If the segment distance is 1, there are no segments in between | ||
// and the segments are consecutive. | ||
signed_size_type const sd = first.source_index == 0 | ||
? segment_distance(geometry0, first, second) | ||
: segment_distance(geometry1, first, second); | ||
return sd == 1; | ||
} | ||
return false; | ||
} | ||
|
||
|
||
// Returns true if two turns correspond to each other in the sense that one has | ||
// "method_start" and the other has "method_touch" or "method_interior" at that | ||
// same point (but with next segment) | ||
template <typename Turn, typename Geometry0, typename Geometry1> | ||
inline bool corresponding_turn(Turn const& turn, Turn const& start_turn, | ||
Geometry0 const& geometry0, | ||
Geometry1 const& geometry1) | ||
{ | ||
for (std::size_t i = 0; i < 2; i++) | ||
{ | ||
for (std::size_t j = 0; j < 2; j++) | ||
{ | ||
if (turn.operations[i].seg_id == start_turn.operations[j].seg_id | ||
&& (turn.method == method_touch | ||
|| turn.method == method_touch_interior)) | ||
{ | ||
// Verify if the other operation is consecutive | ||
return is_consecutive(turn.operations[1 - i].seg_id, | ||
start_turn.operations[1 - j].seg_id, | ||
geometry0, geometry1); | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
|
||
template <typename Turns, typename Geometry0, typename Geometry1> | ||
inline void discard_duplicate_start_turns(Turns& turns, | ||
Geometry0 const& geometry0, | ||
Geometry1 const& geometry1) | ||
{ | ||
// Start turns are generated, in case the previous turn is missed | ||
// But often it is not missed, and then it should still be deleted | ||
// This is how it can be | ||
// (in float, collinear, points far apart due to floating point precision) | ||
// [m, i s:0, v:6 1/1 (1) // u s:1, v:5 pnt (2.54044, 3.12623)] | ||
// [s, i s:0, v:7 0/1 (0) // u s:1, v:5 pnt (2.70711, 3.29289)] | ||
|
||
// 1 Build map (segment->turnids) of start turns | ||
std::map<segment_identifier, 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 (const auto& op : turn.operations) | ||
{ | ||
start_turns_per_segment[op.seg_id].push_back(index); | ||
} | ||
} | ||
index++; | ||
} | ||
|
||
// 2: Verify all other turns if they are present in the map, and if so, | ||
// if they have the other turns as corresponding | ||
for (auto const& turn : turns) | ||
{ | ||
if (turn.method != method_start) | ||
{ | ||
for (const auto& op : turn.operations) | ||
{ | ||
auto it = start_turns_per_segment.find(op.seg_id); | ||
if (it != start_turns_per_segment.end()) | ||
{ | ||
for (std::size_t const& i : it->second) | ||
{ | ||
if (corresponding_turn(turn, turns[i], | ||
geometry0, geometry1)) | ||
{ | ||
turns[i].discarded = true; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
index++; | ||
} | ||
} | ||
|
||
|
||
}} // namespace detail::overlay | ||
#endif //DOXYGEN_NO_DETAIL | ||
|
||
|
||
}} // namespace boost::geometry | ||
|
||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_DISCARD_DUPLICATE_TURNS_HPP |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.