mirror of
https://github.com/boostorg/geometry.git
synced 2026-01-31 20:22:09 +00:00
[dissolve] using preferred operations, they are now also used to determine
the order in which turns are traversed (first preferred). This introduces a specific traverse umbrella class for dissolve
This commit is contained in:
@@ -344,6 +344,60 @@ struct traversal_ring_creator
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Rings>
|
||||
void iterate_with_preference(std::size_t phase,
|
||||
Rings& rings, std::size_t& finalized_ring_size,
|
||||
typename Backtrack::state_type& state)
|
||||
{
|
||||
for (std::size_t turn_index = 0; turn_index < m_turns.size(); ++turn_index)
|
||||
{
|
||||
turn_type const& turn = m_turns[turn_index];
|
||||
|
||||
if (turn.discarded || turn.blocked())
|
||||
{
|
||||
// Skip discarded and blocked turns
|
||||
continue;
|
||||
}
|
||||
|
||||
turn_operation_type const& op0 = turn.operations[0];
|
||||
turn_operation_type const& op1 = turn.operations[1];
|
||||
|
||||
if (phase == 0)
|
||||
{
|
||||
if (! op0.enriched.prefer_start && ! op1.enriched.prefer_start)
|
||||
{
|
||||
// Not preferred, take next one
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (turn.both(operation_continue))
|
||||
{
|
||||
// Traverse only one turn, the one with the SMALLEST remaining distance
|
||||
// to avoid skipping a turn in between, which can happen in rare cases
|
||||
// (e.g. #130)
|
||||
int const op_index
|
||||
= op0.remaining_distance <= op1.remaining_distance ? 0 : 1;
|
||||
|
||||
traverse_with_operation(turn, turn_index, op_index,
|
||||
rings, finalized_ring_size, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool const forward = op0.enriched.prefer_start;
|
||||
|
||||
int op_index = forward ? 0 : 1;
|
||||
int const increment = forward ? 1 : -1;
|
||||
|
||||
for (int i = 0; i < 2; i++, op_index += increment)
|
||||
{
|
||||
traverse_with_operation(turn, turn_index, op_index,
|
||||
rings, finalized_ring_size, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
traversal_type m_trav;
|
||||
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2018 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_EXTENSIONS_ALGORITHMS_DISSOLVE_TRAVERSE_HPP
|
||||
#define BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_TRAVERSE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/traversal_ring_creator.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace dissolve
|
||||
{
|
||||
|
||||
|
||||
/*!
|
||||
\brief Traverses through intersection points / geometries. This version
|
||||
for dissolves calls traversal_ring_creator in two phases
|
||||
\ingroup dissolve
|
||||
*/
|
||||
template <typename Backtrack>
|
||||
class traverse
|
||||
{
|
||||
|
||||
public :
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename IntersectionStrategy,
|
||||
typename RobustPolicy,
|
||||
typename Turns,
|
||||
typename Rings,
|
||||
typename TurnInfoMap,
|
||||
typename Clusters,
|
||||
typename Visitor
|
||||
>
|
||||
static inline void apply(Geometry const& geometry,
|
||||
IntersectionStrategy const& intersection_strategy,
|
||||
RobustPolicy const& robust_policy,
|
||||
Turns& turns, Rings& rings,
|
||||
TurnInfoMap& turn_info_map,
|
||||
Clusters& clusters,
|
||||
Visitor& visitor)
|
||||
{
|
||||
detail::overlay::traversal_ring_creator
|
||||
<
|
||||
false, false, overlay_dissolve,
|
||||
Geometry, Geometry,
|
||||
Turns, TurnInfoMap, Clusters,
|
||||
IntersectionStrategy,
|
||||
RobustPolicy, Visitor,
|
||||
Backtrack
|
||||
> trav(geometry, geometry, turns, turn_info_map, clusters,
|
||||
intersection_strategy, robust_policy, visitor);
|
||||
|
||||
std::size_t finalized_ring_size = boost::size(rings);
|
||||
|
||||
typename Backtrack::state_type state;
|
||||
|
||||
for (std::size_t phase = 0; phase < 2; phase++)
|
||||
{
|
||||
trav.iterate_with_preference(phase, rings, finalized_ring_size, state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::dissolve
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_EXTENSIONS_ALGORITHMS_DISSOLVE_TRAVERSE_HPP
|
||||
@@ -44,6 +44,7 @@
|
||||
|
||||
#include <boost/geometry/strategies/intersection.hpp>
|
||||
|
||||
#include <boost/geometry/extensions/algorithms/detail/overlay/dissolve_traverse.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -219,7 +220,7 @@ struct dissolve_ring_or_polygon
|
||||
|
||||
cluster_type clusters;
|
||||
|
||||
// Enrich/traverse the polygons twice: first for union...
|
||||
// Enrich/traverse the polygons
|
||||
typename Strategy::side_strategy_type const
|
||||
side_strategy = strategy.get_side_strategy();
|
||||
|
||||
@@ -233,14 +234,8 @@ struct dissolve_ring_or_polygon
|
||||
|
||||
std::map<ring_identifier, overlay::ring_turn_info> turn_info_per_ring;
|
||||
|
||||
detail::overlay::traverse
|
||||
<
|
||||
false, false,
|
||||
Geometry, Geometry,
|
||||
overlay_dissolve,
|
||||
backtrack_for_dissolve<Geometry>
|
||||
>::apply(geometry, geometry,
|
||||
strategy, rescale_policy,
|
||||
detail::dissolve::traverse<backtrack_for_dissolve<Geometry> >
|
||||
::apply(geometry, strategy, rescale_policy,
|
||||
turns, rings, turn_info_per_ring, clusters, visitor);
|
||||
|
||||
visitor.visit_turns(3, turns);
|
||||
|
||||
Reference in New Issue
Block a user