[buffer][is_valid][overlay] Use area strategy got from intersection strategy.

This commit is contained in:
Adam Wulkiewicz
2017-07-04 04:45:37 +02:00
parent 4122cab822
commit 8a12ebdb69
6 changed files with 103 additions and 60 deletions

View File

@@ -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);

View File

@@ -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
<

View File

@@ -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;

View File

@@ -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++;
}

View File

@@ -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);
}

View File

@@ -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,