mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-10 11:32:15 +00:00
[relate] add support for non-simple non-equal Polygons in A/A.
Currently simple interrupt policy is used. This approach works is there are IPs, Polygons are simple and not equal.
This commit is contained in:
@@ -57,7 +57,7 @@ private:
|
||||
};
|
||||
|
||||
// The implementation of an algorithm calculating relate() for A/A
|
||||
template <typename Geometry1, typename Geometry2, bool TransposeResult = false>
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct areal_areal
|
||||
{
|
||||
// check Linear / Areal
|
||||
@@ -72,8 +72,10 @@ struct areal_areal
|
||||
template <typename Result>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
|
||||
{
|
||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||
|
||||
// The result should be FFFFFFFFF
|
||||
set<exterior, exterior, result_dimension<Geometry2>::value, TransposeResult>(result);// FFFFFFFFd, d in [1,9] or T
|
||||
set<exterior, exterior, result_dimension<Geometry2>::value>(result);// FFFFFFFFd, d in [1,9] or T
|
||||
|
||||
if ( result.interrupt )
|
||||
return;
|
||||
@@ -83,9 +85,9 @@ struct areal_areal
|
||||
typedef typename std::vector<turn_type>::iterator turn_iterator;
|
||||
std::vector<turn_type> turns;
|
||||
|
||||
//interrupt_policy_areal_areal<Geometry1, Geometry2, Result> interrupt_policy(geometry1, geometry2, result);
|
||||
interrupt_policy_areal_areal<Geometry1, Geometry2, Result> interrupt_policy(geometry1, geometry2, result);
|
||||
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2/*, interrupt_policy*/);
|
||||
turns::get_turns<Geometry1, Geometry2>::apply(turns, geometry1, geometry2, interrupt_policy);
|
||||
if ( result.interrupt )
|
||||
return;
|
||||
//
|
||||
@@ -272,35 +274,40 @@ struct areal_areal
|
||||
|
||||
for (iterator it = boost::begin(turns) ; it != boost::end(turns) ; ++it)
|
||||
{
|
||||
if ( it->operations[0].operation == overlay::operation_intersection )
|
||||
{
|
||||
bool const no_interior_rings
|
||||
= geometry::num_interior_rings(
|
||||
single_geometry(m_areal, it->operations[1].seg_id)) == 0;
|
||||
|
||||
// WARNING! THIS IS TRUE ONLY IF THE POLYGON IS SIMPLE!
|
||||
// OR WITHOUT INTERIOR RINGS (AND OF COURSE VALID)
|
||||
if ( no_interior_rings )
|
||||
update<interior, interior, '1', TransposeResult>(m_result);
|
||||
}
|
||||
else if ( it->operations[0].operation == overlay::operation_continue )
|
||||
{
|
||||
update<interior, boundary, '1', TransposeResult>(m_result);
|
||||
is_boundary_found = true;
|
||||
}
|
||||
else if ( ( it->operations[0].operation == overlay::operation_union
|
||||
|| it->operations[0].operation == overlay::operation_blocked )
|
||||
&& it->operations[0].position == overlay::position_middle )
|
||||
{
|
||||
// TODO: here we could also check the boundaries and set BB at this point
|
||||
update<interior, boundary, '0', TransposeResult>(m_result);
|
||||
}
|
||||
per_turn<0, false>(*it);
|
||||
per_turn<1, true>(*it);
|
||||
}
|
||||
|
||||
return m_result.interrupt;
|
||||
}
|
||||
|
||||
private:
|
||||
template <std::size_t Id, bool TransposeResult, typename Turn>
|
||||
inline void per_turn(Turn const& turn)
|
||||
{
|
||||
// THIS WON'T WORK FOR NON-SIMPLE GEOMETRIES!
|
||||
|
||||
overlay::operation_type op = turn.operations[Id].operation;
|
||||
|
||||
if ( op == overlay::operation_intersection )
|
||||
{
|
||||
update<interior, interior, '2', TransposeResult>(m_result);
|
||||
update<boundary, interior, '1', TransposeResult>(m_result);
|
||||
update<boundary, boundary, '0', TransposeResult>(m_result);
|
||||
}
|
||||
else if ( op == overlay::operation_continue ||
|
||||
op == overlay::operation_blocked )
|
||||
{
|
||||
update<boundary, boundary, '1', TransposeResult>(m_result);
|
||||
}
|
||||
else if ( op == overlay::operation_union )
|
||||
{
|
||||
update<boundary, boundary, '0', TransposeResult>(m_result);
|
||||
update<boundary, exterior, '1', TransposeResult>(m_result);
|
||||
update<interior, exterior, '2', TransposeResult>(m_result);
|
||||
}
|
||||
}
|
||||
|
||||
Result & m_result;
|
||||
Geometry1 const& m_geometry1;
|
||||
Geometry2 const& m_geometry2;
|
||||
|
||||
@@ -146,6 +146,8 @@ struct linear_areal
|
||||
template <typename Result>
|
||||
static inline void apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Result & result)
|
||||
{
|
||||
// TODO: If Areal geometry may have infinite size, change the following line:
|
||||
|
||||
// The result should be FFFFFFFFF
|
||||
set<exterior, exterior, result_dimension<Geometry2>::value, TransposeResult>(result);// FFFFFFFFd, d in [1,9] or T
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
#include <boost/geometry/algorithms/detail/relate/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/linear_areal.hpp>
|
||||
//#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/areal_areal.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -178,6 +178,11 @@ struct relate<MultiPolygon, MultiLinestring, multi_polygon_tag, multi_linestring
|
||||
: detail::relate::areal_linear<MultiPolygon, MultiLinestring>
|
||||
{};
|
||||
|
||||
template <typename Polygon1, typename Polygon2>
|
||||
struct relate<Polygon1, Polygon2, polygon_tag, polygon_tag>
|
||||
: detail::relate::areal_areal<Polygon1, Polygon2>
|
||||
{};
|
||||
|
||||
}} // namespace detail_dispatch::relate
|
||||
|
||||
namespace detail { namespace relate {
|
||||
|
||||
@@ -622,23 +622,37 @@ void polygon_polygon()
|
||||
{
|
||||
typedef bg::model::polygon<P> poly;
|
||||
|
||||
//to_svg<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
// "POLYGON((10 0,10 10,20 10,20 0,10 0))",
|
||||
// "pp1.svg");
|
||||
// touching
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((10 0,10 10,20 10,20 0,10 0))",
|
||||
"FF2F11212");
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((0 -10,0 0,10 0,10 -10,0 -10))",
|
||||
"FF2F11212");
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((10 0,15 10,20 10,20 0,10 0))",
|
||||
"FF2F01212");
|
||||
|
||||
//to_svg<poly, poly>("POLYGON((0 0,0 10,10 10,15 5,10 0,0 0))",
|
||||
// "POLYGON((10 0,5 5,10 10,20 10,20 0,10 0))",
|
||||
// "pp11.svg");
|
||||
// containing
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((5 5,5 10,6 10,6 5,5 5))",
|
||||
"212F11FF2");
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((5 5,5 10,6 5,5 5))",
|
||||
"212F01FF2");
|
||||
|
||||
//to_svg<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
// "POLYGON((5 0,5 10,20 10,20 0,5 0))",
|
||||
// "pp2.svg");
|
||||
// overlapping
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((5 0,5 10,20 10,20 0,5 0))",
|
||||
"212111212");
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,15 5,10 0,0 0))",
|
||||
"POLYGON((10 0,5 5,10 10,20 10,20 0,10 0))",
|
||||
"212101212");
|
||||
|
||||
//to_svg<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
// "POLYGON((0 -10,0 0,10 0,10 -10,0 -10))",
|
||||
// "pp3.svg");
|
||||
|
||||
|
||||
// equal
|
||||
test_geometry<poly, poly>("POLYGON((0 0,0 10,10 10,10 0,0 0))",
|
||||
"POLYGON((10 10,10 5,10 0,5 0,0 0,0 10,5 10,10 10))",
|
||||
"2FFF1FFF2");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
|
||||
Reference in New Issue
Block a user