mirror of
https://github.com/boostorg/geometry.git
synced 2025-05-11 21:44:04 +00:00
[relate] add optimization for L/L ommitting parts of the algorithm if the result mustnot be updated
This commit is contained in:
parent
cce6c71782
commit
d76c94d643
@ -35,13 +35,28 @@ class disjoint_linestring_pred
|
||||
public:
|
||||
disjoint_linestring_pred(Result & res,
|
||||
BoundaryChecker const& boundary_checker)
|
||||
: m_result_ptr(boost::addressof(res))
|
||||
, m_boundary_checker_ptr(boost::addressof(boundary_checker))
|
||||
{}
|
||||
: m_result(res)
|
||||
, m_boundary_checker(boundary_checker)
|
||||
, m_flags(0)
|
||||
{
|
||||
if ( ! may_update<interior, exterior, '1', TransposeResult>(m_result) )
|
||||
{
|
||||
m_flags |= 1;
|
||||
}
|
||||
if ( ! may_update<boundary, exterior, '0', TransposeResult>(m_result) )
|
||||
{
|
||||
m_flags |= 2;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Linestring>
|
||||
bool operator()(Linestring const& linestring)
|
||||
{
|
||||
if ( m_flags == 3 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::size_t count = boost::size(linestring);
|
||||
|
||||
// invalid input
|
||||
@ -52,25 +67,28 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
update<interior, exterior, '1', TransposeResult>(*m_result_ptr);
|
||||
update<interior, exterior, '1', TransposeResult>(m_result);
|
||||
m_flags |= 1;
|
||||
|
||||
// check if there is a boundary
|
||||
if ( m_boundary_checker_ptr->template
|
||||
if ( m_flags < 2
|
||||
&& ( m_boundary_checker.template
|
||||
is_endpoint_boundary<boundary_front>(range::front(linestring))
|
||||
|| m_boundary_checker_ptr->template
|
||||
is_endpoint_boundary<boundary_back>(range::back(linestring)) )
|
||||
|| m_boundary_checker.template
|
||||
is_endpoint_boundary<boundary_back>(range::back(linestring)) ) )
|
||||
{
|
||||
update<boundary, exterior, '0', TransposeResult>(*m_result_ptr);
|
||||
|
||||
return false;
|
||||
update<boundary, exterior, '0', TransposeResult>(m_result);
|
||||
m_flags |= 2;
|
||||
}
|
||||
|
||||
return !m_result_ptr->interrupt;
|
||||
return m_flags != 3
|
||||
&& ! m_result.interrupt;
|
||||
}
|
||||
|
||||
private:
|
||||
Result * m_result_ptr;
|
||||
const BoundaryChecker * m_boundary_checker_ptr;
|
||||
Result & m_result;
|
||||
BoundaryChecker const& m_boundary_checker;
|
||||
unsigned m_flags;
|
||||
};
|
||||
|
||||
//enum linestring_kind { linestring_exterior, linestring_point, linestring_closed, linestring_open };
|
||||
@ -239,8 +257,12 @@ struct linear_linear
|
||||
// TODO: turns must be sorted and followed only if it's possible to go out and in on the same point
|
||||
// for linear geometries union operation must be detected which I guess would be quite often
|
||||
|
||||
// TODO: ADD A CHECK TO THE RESULT INDICATING IF THE FIRST AND/OR SECOND GEOMETRY MUST BE ANALYSED
|
||||
|
||||
if ( may_update<interior, interior, '1'>(result)
|
||||
|| may_update<interior, boundary, '0'>(result)
|
||||
|| may_update<interior, exterior, '1'>(result)
|
||||
|| may_update<boundary, interior, '0'>(result)
|
||||
|| may_update<boundary, boundary, '0'>(result)
|
||||
|| may_update<boundary, exterior, '0'>(result) )
|
||||
{
|
||||
// x, u, i, c
|
||||
typedef turns::less
|
||||
@ -262,6 +284,12 @@ struct linear_linear
|
||||
if ( result.interrupt )
|
||||
return;
|
||||
|
||||
if ( may_update<interior, interior, '1', true>(result)
|
||||
|| may_update<interior, boundary, '0', true>(result)
|
||||
|| may_update<interior, exterior, '1', true>(result)
|
||||
|| may_update<boundary, interior, '0', true>(result)
|
||||
|| may_update<boundary, boundary, '0', true>(result)
|
||||
|| may_update<boundary, exterior, '0', true>(result) )
|
||||
{
|
||||
// x, u, i, c
|
||||
typedef turns::less
|
||||
|
@ -35,6 +35,12 @@ namespace detail { namespace relate {
|
||||
|
||||
enum field { interior = 0, boundary = 1, exterior = 2 };
|
||||
|
||||
// TODO: IF THE RESULT IS UPDATED WITH THE MAX POSSIBLE VALUE FOR SOME PAIR OF GEOEMTRIES
|
||||
// THE VALUE ALREADY STORED MUSN'T BE CHECKED
|
||||
// update() calls chould be replaced with set() in those cases
|
||||
// but for safety reasons (STATIC_ASSERT) we should check if parameter D is valid and set() doesn't do that
|
||||
// so some additional function could be added, e.g. set_dim()
|
||||
|
||||
// matrix
|
||||
|
||||
// TODO add height?
|
||||
|
@ -348,10 +348,11 @@ void test_linestring_linestring()
|
||||
// OTHER MASKS
|
||||
{
|
||||
namespace bgdr = bg::detail::relate;
|
||||
ls ls1, ls2, ls3;
|
||||
ls ls1, ls2, ls3, ls4;
|
||||
bg::read_wkt("LINESTRING(0 0,2 0)", ls1);
|
||||
bg::read_wkt("LINESTRING(2 0,4 0)", ls2);
|
||||
bg::read_wkt("LINESTRING(1 0,1 1)", ls3);
|
||||
bg::read_wkt("LINESTRING(1 0,4 0)", ls4);
|
||||
BOOST_CHECK(bgdr::relate(ls1, ls2, bgdr::mask9("FT*******")
|
||||
|| bgdr::mask9("F**T*****")
|
||||
|| bgdr::mask9("F***T****")));
|
||||
@ -361,6 +362,7 @@ void test_linestring_linestring()
|
||||
BOOST_CHECK(bgdr::relate(ls3, ls1, bgdr::mask9("FT*******")
|
||||
|| bgdr::mask9("F**T*****")
|
||||
|| bgdr::mask9("F***T****")));
|
||||
BOOST_CHECK(bgdr::relate(ls2, ls4, bgdr::mask9("T*F**F***"))); // within
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user