diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp')
-rw-r--r-- | boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp | 55 |
1 files changed, 23 insertions, 32 deletions
diff --git a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp index f51bd29007..bb7019c089 100644 --- a/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp +++ b/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2020 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2016, 2018. -// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2022. +// Modifications copyright (c) 2016-2022 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, @@ -21,6 +21,7 @@ #include <boost/geometry/algorithms/covered_by.hpp> #include <boost/geometry/algorithms/detail/disjoint/point_box.hpp> #include <boost/geometry/algorithms/detail/disjoint/box_box.hpp> +#include <boost/geometry/algorithms/detail/dummy_geometries.hpp> #include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp> #include <boost/geometry/geometries/box.hpp> @@ -38,7 +39,8 @@ template typename CsTag, typename Turns, typename Pieces, - typename DistanceStrategy + typename DistanceStrategy, + typename UmbrellaStrategy > class turn_in_piece_visitor @@ -46,6 +48,7 @@ class turn_in_piece_visitor Turns& m_turns; // because partition is currently operating on const input only Pieces const& m_pieces; // to check for piece-type DistanceStrategy const& m_distance_strategy; // to check if point is on original or one_sided + UmbrellaStrategy const& m_umbrella_strategy; template <typename Operation, typename Piece> inline bool skip(Operation const& op, Piece const& piece) const @@ -94,10 +97,12 @@ class turn_in_piece_visitor public: inline turn_in_piece_visitor(Turns& turns, Pieces const& pieces, - DistanceStrategy const& distance_strategy) + DistanceStrategy const& distance_strategy, + UmbrellaStrategy const& umbrella_strategy) : m_turns(turns) , m_pieces(pieces) , m_distance_strategy(distance_strategy) + , m_umbrella_strategy(umbrella_strategy) {} template <typename Turn, typename Piece> @@ -127,20 +132,24 @@ public: template <typename Turn, typename Piece, typename Border> inline bool apply(Turn const& turn, Piece const& piece, Border const& border) { - if (! geometry::covered_by(turn.point, border.m_envelope)) + if (! geometry::covered_by(turn.point, border.m_envelope, m_umbrella_strategy)) { // Easy check: if turn is not in the (expanded) envelope return true; } + if (piece.type == geometry::strategy::buffer::buffered_empty_side) + { + return false; + } + if (piece.type == geometry::strategy::buffer::buffered_point) { // Optimization for a buffer around points: if distance from center // is not between min/max radius, it is either inside or outside, // and more expensive checks are not necessary. - typedef typename Border::radius_type radius_type; - - radius_type const d = geometry::comparable_distance(piece.m_center, turn.point); + auto const d = geometry::comparable_distance(piece.m_center, turn.point, + m_umbrella_strategy); if (d < border.m_min_comparable_radius) { @@ -155,38 +164,20 @@ public: } // Check if buffer is one-sided (at this point), because then a point - // on the original is not considered as within. + // on the original border is not considered as within. bool const one_sided = has_zero_distance_at(turn.point); typename Border::state_type state; - if (! border.point_on_piece(turn.point, one_sided, turn.is_linear_end_point, state)) + if (! border.point_on_piece(turn.point, one_sided, + turn.is_linear_end_point, state)) { return true; } - if (state.code() == 1) + if (state.is_inside() && ! state.is_on_boundary()) { - // It is WITHIN a piece, or on the piece border, but not - // on the offsetted part of it. - - // TODO - at further removing rescaling, this threshold can be - // adapted, or ideally, go. - // This threshold is minimized to the point where fragile - // unit tests of hard cases start to fail (5 in multi_polygon) - // But it is acknowlegded that such a threshold depends on the - // scale of the input. - if (state.m_min_distance > 1.0e-5 || ! state.m_close_to_offset) - { - Turn& mutable_turn = m_turns[turn.turn_index]; - mutable_turn.is_turn_traversable = false; - - // Keep track of the information if this turn was close - // to an offset (without threshold). Because if it was, - // it might have been classified incorrectly and in the - // pretraversal step, it can in hindsight be classified - // as "outside". - mutable_turn.close_to_offset = state.m_close_to_offset; - } + Turn& mutable_turn = m_turns[turn.turn_index]; + mutable_turn.is_turn_traversable = false; } return true; |