mirror of
https://github.com/boostorg/geometry.git
synced 2026-01-31 20:22:09 +00:00
[buffer][is_valid][overlay] Use area strategy got from intersection strategy.
This commit is contained in:
@@ -142,10 +142,20 @@ struct buffered_piece_collection
|
||||
robust_point_type
|
||||
>::type robust_comparable_radius_type;
|
||||
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
typedef typename IntersectionStrategy::side_strategy_type side_strategy_type;
|
||||
|
||||
typedef typename IntersectionStrategy::template area_strategy
|
||||
<
|
||||
typename cs_tag<point_type>::type
|
||||
>::type side_strategy;
|
||||
point_type
|
||||
>::type area_strategy_type;
|
||||
|
||||
typedef typename IntersectionStrategy::template area_strategy
|
||||
<
|
||||
robust_point_type
|
||||
>::type robust_area_strategy_type;
|
||||
|
||||
typedef typename area_strategy_type::return_type area_result_type;
|
||||
typedef typename robust_area_strategy_type::return_type robust_area_result_type;
|
||||
|
||||
typedef typename geometry::rescale_policy_type
|
||||
<
|
||||
@@ -306,7 +316,10 @@ struct buffered_piece_collection
|
||||
|
||||
cluster_type m_clusters;
|
||||
|
||||
IntersectionStrategy const& m_intersection_strategy;
|
||||
IntersectionStrategy m_intersection_strategy;
|
||||
side_strategy_type m_side_strategy;
|
||||
area_strategy_type m_area_strategy;
|
||||
robust_area_strategy_type m_robust_area_strategy;
|
||||
RobustPolicy const& m_robust_policy;
|
||||
|
||||
struct redundant_turn
|
||||
@@ -321,6 +334,9 @@ struct buffered_piece_collection
|
||||
RobustPolicy const& robust_policy)
|
||||
: m_first_piece_index(-1)
|
||||
, m_intersection_strategy(intersection_strategy)
|
||||
, m_side_strategy(intersection_strategy.get_side_strategy())
|
||||
, m_area_strategy(intersection_strategy.template get_area_strategy<point_type>())
|
||||
, m_robust_area_strategy(intersection_strategy.template get_area_strategy<robust_point_type>())
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
@@ -699,7 +715,7 @@ struct buffered_piece_collection
|
||||
++it)
|
||||
{
|
||||
piece& pc = *it;
|
||||
if (geometry::area(pc.robust_ring) < 0)
|
||||
if (geometry::area(pc.robust_ring, m_robust_area_strategy) < 0)
|
||||
{
|
||||
// Rings can be ccw:
|
||||
// - in a concave piece
|
||||
@@ -1220,14 +1236,9 @@ struct buffered_piece_collection
|
||||
|
||||
inline void enrich()
|
||||
{
|
||||
typedef typename strategy::side::services::default_strategy
|
||||
<
|
||||
typename cs_tag<Ring>::type
|
||||
>::type side_strategy_type;
|
||||
|
||||
enrich_intersection_points<false, false, overlay_buffer>(m_turns,
|
||||
m_clusters, offsetted_rings, offsetted_rings,
|
||||
m_robust_policy, side_strategy_type());
|
||||
m_robust_policy, m_side_strategy);
|
||||
}
|
||||
|
||||
// Discards all rings which do have not-OK intersection points only.
|
||||
@@ -1314,7 +1325,7 @@ struct buffered_piece_collection
|
||||
buffered_ring<Ring>& ring = *it;
|
||||
if (! ring.has_intersections()
|
||||
&& boost::size(ring) > 0u
|
||||
&& geometry::area(ring) < 0)
|
||||
&& geometry::area(ring, m_area_strategy) < 0)
|
||||
{
|
||||
if (! point_coveredby_original(geometry::range::front(ring)))
|
||||
{
|
||||
@@ -1391,7 +1402,7 @@ struct buffered_piece_collection
|
||||
template <typename GeometryOutput, typename OutputIterator>
|
||||
inline OutputIterator assign(OutputIterator out) const
|
||||
{
|
||||
typedef detail::overlay::ring_properties<point_type> properties;
|
||||
typedef detail::overlay::ring_properties<point_type, area_result_type> properties;
|
||||
|
||||
std::map<ring_identifier, properties> selected;
|
||||
|
||||
@@ -1407,7 +1418,7 @@ struct buffered_piece_collection
|
||||
if (! it->has_intersections()
|
||||
&& ! it->is_untouched_outside_original)
|
||||
{
|
||||
properties p = properties(*it);
|
||||
properties p = properties(*it, m_area_strategy);
|
||||
if (p.valid)
|
||||
{
|
||||
ring_identifier id(0, index, -1);
|
||||
@@ -1423,7 +1434,7 @@ struct buffered_piece_collection
|
||||
it != boost::end(traversed_rings);
|
||||
++it, ++index)
|
||||
{
|
||||
properties p = properties(*it);
|
||||
properties p = properties(*it, m_area_strategy);
|
||||
if (p.valid)
|
||||
{
|
||||
ring_identifier id(2, index, -1);
|
||||
|
||||
@@ -115,7 +115,10 @@ struct is_properly_oriented
|
||||
geometry::closure<Ring>::value
|
||||
> ring_area_type;
|
||||
|
||||
typedef typename default_area_result<Ring>::type area_result_type;
|
||||
typedef typename Strategy::template area_strategy
|
||||
<
|
||||
point_type
|
||||
>::type::return_type area_result_type;
|
||||
|
||||
typename ring_area_predicate
|
||||
<
|
||||
|
||||
@@ -107,21 +107,19 @@ static inline bool within_selected_input(Item const& item2,
|
||||
}
|
||||
|
||||
|
||||
template <typename Point>
|
||||
template <typename Point, typename AreaType>
|
||||
struct ring_info_helper
|
||||
{
|
||||
typedef typename geometry::default_area_result<Point>::type area_type;
|
||||
|
||||
ring_identifier id;
|
||||
area_type real_area;
|
||||
area_type abs_area;
|
||||
AreaType real_area;
|
||||
AreaType abs_area;
|
||||
model::box<Point> envelope;
|
||||
|
||||
inline ring_info_helper()
|
||||
: real_area(0), abs_area(0)
|
||||
{}
|
||||
|
||||
inline ring_info_helper(ring_identifier i, area_type a)
|
||||
inline ring_info_helper(ring_identifier i, AreaType const& a)
|
||||
: id(i), real_area(a), abs_area(geometry::math::abs(a))
|
||||
{}
|
||||
};
|
||||
@@ -234,11 +232,15 @@ inline void assign_parents(Geometry1 const& geometry1,
|
||||
typedef typename RingMap::mapped_type ring_info_type;
|
||||
typedef typename ring_info_type::point_type point_type;
|
||||
typedef model::box<point_type> box_type;
|
||||
typedef typename Strategy::template area_strategy
|
||||
<
|
||||
point_type
|
||||
>::type::return_type area_result_type;
|
||||
|
||||
typedef typename RingMap::iterator map_iterator_type;
|
||||
|
||||
{
|
||||
typedef ring_info_helper<point_type> helper;
|
||||
typedef ring_info_helper<point_type, area_result_type> helper;
|
||||
typedef std::vector<helper> vector_type;
|
||||
typedef typename boost::range_iterator<vector_type const>::type vector_iterator_type;
|
||||
|
||||
|
||||
@@ -197,7 +197,16 @@ inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
|
||||
typename geometry::ring_type<GeometryOut>::type
|
||||
> ring_container_type;
|
||||
|
||||
typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
|
||||
typedef typename geometry::point_type<Geometry1>::type point_type1;
|
||||
|
||||
typedef ring_properties
|
||||
<
|
||||
point_type1,
|
||||
typename Strategy::template area_strategy
|
||||
<
|
||||
point_type1
|
||||
>::type::return_type
|
||||
> properties;
|
||||
|
||||
// Silence warning C4127: conditional expression is constant
|
||||
#if defined(_MSC_VER)
|
||||
@@ -309,7 +318,7 @@ std::cout << "get turns" << std::endl;
|
||||
#ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
|
||||
std::cout << "enrich" << std::endl;
|
||||
#endif
|
||||
typename Strategy::side_strategy_type side_strategy;
|
||||
typename Strategy::side_strategy_type side_strategy = strategy.get_side_strategy();
|
||||
cluster_type clusters;
|
||||
|
||||
geometry::enrich_intersection_points<Reverse1, Reverse2, OverlayType>(turns,
|
||||
@@ -341,10 +350,13 @@ std::cout << "traverse" << std::endl;
|
||||
std::map<ring_identifier, ring_turn_info> turn_info_per_ring;
|
||||
get_ring_turn_info<OverlayType>(turn_info_per_ring, turns, clusters);
|
||||
|
||||
typedef typename Strategy::template area_strategy<point_type>::type area_strategy_type;
|
||||
|
||||
typedef ring_properties
|
||||
<
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> properties;
|
||||
<
|
||||
point_type,
|
||||
typename area_strategy_type::return_type
|
||||
> properties;
|
||||
|
||||
// Select all rings which are NOT touched by any intersection point
|
||||
std::map<ring_identifier, properties> selected_ring_properties;
|
||||
@@ -353,13 +365,15 @@ std::cout << "traverse" << std::endl;
|
||||
|
||||
// Add rings created during traversal
|
||||
{
|
||||
area_strategy_type const area_strategy = strategy.template get_area_strategy<point_type>();
|
||||
|
||||
ring_identifier id(2, 0, -1);
|
||||
for (typename boost::range_iterator<ring_container_type>::type
|
||||
it = boost::begin(rings);
|
||||
it != boost::end(rings);
|
||||
++it)
|
||||
{
|
||||
selected_ring_properties[id] = properties(*it);
|
||||
selected_ring_properties[id] = properties(*it, area_strategy);
|
||||
selected_ring_properties[id].reversed = ReverseOut;
|
||||
id.multi_index++;
|
||||
}
|
||||
|
||||
@@ -27,11 +27,11 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace overlay
|
||||
{
|
||||
|
||||
template <typename Point>
|
||||
template <typename Point, typename AreaType>
|
||||
struct ring_properties
|
||||
{
|
||||
typedef Point point_type;
|
||||
typedef typename default_area_result<Point>::type area_type;
|
||||
typedef AreaType area_type;
|
||||
|
||||
bool valid;
|
||||
|
||||
@@ -56,13 +56,13 @@ struct ring_properties
|
||||
, parent_area(-1)
|
||||
{}
|
||||
|
||||
template <typename RingOrBox>
|
||||
inline ring_properties(RingOrBox const& ring_or_box)
|
||||
template <typename RingOrBox, typename AreaStrategy>
|
||||
inline ring_properties(RingOrBox const& ring_or_box, AreaStrategy const& strategy)
|
||||
: reversed(false)
|
||||
, discarded(false)
|
||||
, parent_area(-1)
|
||||
{
|
||||
this->area = geometry::area(ring_or_box);
|
||||
this->area = geometry::area(ring_or_box, strategy);
|
||||
valid = geometry::point_on_border(this->point, ring_or_box);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,41 +59,45 @@ namespace dispatch
|
||||
template <typename Box>
|
||||
struct select_rings<box_tag, Box>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap>
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Box const& box, Geometry const& ,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties)
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box);
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap>
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Box const& box,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties)
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box);
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(box, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Ring>
|
||||
struct select_rings<ring_tag, Ring>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap>
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Ring const& ring, Geometry const& ,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties)
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(ring);
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(ring, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap>
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Ring const& ring,
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties)
|
||||
ring_identifier const& id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
if (boost::size(ring) > 0)
|
||||
{
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(ring);
|
||||
ring_properties[id] = typename RingPropertyMap::mapped_type(ring, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -102,14 +106,15 @@ namespace dispatch
|
||||
template <typename Polygon>
|
||||
struct select_rings<polygon_tag, Polygon>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap>
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Polygon const& polygon, Geometry const& geometry,
|
||||
ring_identifier id, RingPropertyMap& ring_properties)
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(polygon), geometry, id, ring_properties);
|
||||
per_ring::apply(exterior_ring(polygon), geometry, id, ring_properties, strategy);
|
||||
|
||||
typename interior_return_type<Polygon const>::type
|
||||
rings = interior_rings(polygon);
|
||||
@@ -117,18 +122,19 @@ namespace dispatch
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
id.ring_index++;
|
||||
per_ring::apply(*it, geometry, id, ring_properties);
|
||||
per_ring::apply(*it, geometry, id, ring_properties, strategy);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename RingPropertyMap>
|
||||
template <typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Polygon const& polygon,
|
||||
ring_identifier id, RingPropertyMap& ring_properties)
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::ring_type<Polygon>::type ring_type;
|
||||
typedef select_rings<ring_tag, ring_type> per_ring;
|
||||
|
||||
per_ring::apply(exterior_ring(polygon), id, ring_properties);
|
||||
per_ring::apply(exterior_ring(polygon), id, ring_properties, strategy);
|
||||
|
||||
typename interior_return_type<Polygon const>::type
|
||||
rings = interior_rings(polygon);
|
||||
@@ -136,7 +142,7 @@ namespace dispatch
|
||||
it = boost::begin(rings); it != boost::end(rings); ++it)
|
||||
{
|
||||
id.ring_index++;
|
||||
per_ring::apply(*it, id, ring_properties);
|
||||
per_ring::apply(*it, id, ring_properties, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -144,9 +150,10 @@ namespace dispatch
|
||||
template <typename Multi>
|
||||
struct select_rings<multi_polygon_tag, Multi>
|
||||
{
|
||||
template <typename Geometry, typename RingPropertyMap>
|
||||
template <typename Geometry, typename RingPropertyMap, typename AreaStrategy>
|
||||
static inline void apply(Multi const& multi, Geometry const& geometry,
|
||||
ring_identifier id, RingPropertyMap& ring_properties)
|
||||
ring_identifier id, RingPropertyMap& ring_properties,
|
||||
AreaStrategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
@@ -159,7 +166,7 @@ namespace dispatch
|
||||
for (iterator_type it = boost::begin(multi); it != boost::end(multi); ++it)
|
||||
{
|
||||
id.ring_index = -1;
|
||||
per_polygon::apply(*it, geometry, id, ring_properties);
|
||||
per_polygon::apply(*it, geometry, id, ring_properties, strategy);
|
||||
id.multi_index++;
|
||||
}
|
||||
}
|
||||
@@ -311,12 +318,16 @@ inline void select_rings(Geometry1 const& geometry1, Geometry2 const& geometry2,
|
||||
{
|
||||
typedef typename geometry::tag<Geometry1>::type tag1;
|
||||
typedef typename geometry::tag<Geometry2>::type tag2;
|
||||
typedef typename geometry::point_type<Geometry1>::type point1_type;
|
||||
typedef typename geometry::point_type<Geometry2>::type point2_type;
|
||||
|
||||
RingPropertyMap all_ring_properties;
|
||||
dispatch::select_rings<tag1, Geometry1>::apply(geometry1, geometry2,
|
||||
ring_identifier(0, -1, -1), all_ring_properties);
|
||||
ring_identifier(0, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point1_type>());
|
||||
dispatch::select_rings<tag2, Geometry2>::apply(geometry2, geometry1,
|
||||
ring_identifier(1, -1, -1), all_ring_properties);
|
||||
ring_identifier(1, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point2_type>());
|
||||
|
||||
update_ring_selection<OverlayType>(geometry1, geometry2, turn_info_per_ring,
|
||||
all_ring_properties, selected_ring_properties,
|
||||
@@ -337,10 +348,12 @@ inline void select_rings(Geometry const& geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename geometry::tag<Geometry>::type tag;
|
||||
typedef typename geometry::point_type<Geometry>::type point_type;
|
||||
|
||||
RingPropertyMap all_ring_properties;
|
||||
dispatch::select_rings<tag, Geometry>::apply(geometry,
|
||||
ring_identifier(0, -1, -1), all_ring_properties);
|
||||
ring_identifier(0, -1, -1), all_ring_properties,
|
||||
strategy.template get_area_strategy<point_type>());
|
||||
|
||||
update_ring_selection<OverlayType>(geometry, geometry, turn_info_per_ring,
|
||||
all_ring_properties, selected_ring_properties,
|
||||
|
||||
Reference in New Issue
Block a user