mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
[relate] refactor relate helpers.
Remove unused, commented-out code. Improve the names.
This commit is contained in:
@@ -23,9 +23,8 @@ namespace boost { namespace geometry
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace relate {
|
||||
|
||||
// TODO:
|
||||
// For 1-point linestrings or with all equal points turns won't be generated!
|
||||
// Check for those degenerated cases may be connected with this one!
|
||||
// NOTE: This iterates through single geometries for which turns were not generated.
|
||||
// It doesn't mean that the geometry is disjoint, only that no turns were detected.
|
||||
|
||||
template <std::size_t OpId,
|
||||
typename Geometry,
|
||||
@@ -130,14 +129,12 @@ struct for_each_disjoint_geometry_if<OpId, Geometry, Tag, true>
|
||||
|
||||
// WARNING! This class stores pointers!
|
||||
// Passing a reference to local variable will result in undefined behavior!
|
||||
|
||||
// TODO: rename to point_id_ref?
|
||||
template <typename Point>
|
||||
class point_identifier
|
||||
class point_info
|
||||
{
|
||||
public:
|
||||
point_identifier() : sid_ptr(0), pt_ptr(0) {}
|
||||
point_identifier(segment_identifier const& sid, Point const& pt)
|
||||
point_info() : sid_ptr(NULL), pt_ptr(NULL) {}
|
||||
point_info(Point const& pt, segment_identifier const& sid)
|
||||
: sid_ptr(boost::addressof(sid))
|
||||
, pt_ptr(boost::addressof(pt))
|
||||
{}
|
||||
@@ -165,10 +162,10 @@ private:
|
||||
|
||||
// WARNING! This class stores pointers!
|
||||
// Passing a reference to local variable will result in undefined behavior!
|
||||
class same_single_geometry
|
||||
class same_single
|
||||
{
|
||||
public:
|
||||
same_single_geometry(segment_identifier const& sid)
|
||||
same_single(segment_identifier const& sid)
|
||||
: sid_ptr(boost::addressof(sid))
|
||||
{}
|
||||
|
||||
@@ -178,7 +175,7 @@ public:
|
||||
}
|
||||
|
||||
template <typename Point>
|
||||
bool operator()(point_identifier<Point> const& pid) const
|
||||
bool operator()(point_info<Point> const& pid) const
|
||||
{
|
||||
return operator()(pid.seg_id());
|
||||
}
|
||||
@@ -206,12 +203,12 @@ private:
|
||||
|
||||
// WARNING! This class stores pointers!
|
||||
// Passing a reference to local variable will result in undefined behavior!
|
||||
template <typename SameRange = same_single_geometry>
|
||||
template <typename SameRange = same_single>
|
||||
class segment_watcher
|
||||
{
|
||||
public:
|
||||
segment_watcher()
|
||||
: m_seg_id_ptr(0)
|
||||
: m_seg_id_ptr(NULL)
|
||||
{}
|
||||
|
||||
bool update(segment_identifier const& seg_id)
|
||||
@@ -234,20 +231,23 @@ class exit_watcher
|
||||
static const std::size_t other_op_id = (OpId + 1) % 2;
|
||||
|
||||
typedef typename TurnInfo::point_type point_type;
|
||||
typedef point_identifier<point_type> point_info;
|
||||
typedef detail::relate::point_info<point_type> point_info;
|
||||
|
||||
public:
|
||||
exit_watcher()
|
||||
: exit_operation(overlay::operation_none)
|
||||
, exit_turn(0)
|
||||
: m_exit_operation(overlay::operation_none)
|
||||
, m_exit_turn_ptr(NULL)
|
||||
{}
|
||||
|
||||
void enter(TurnInfo const& turn)
|
||||
{
|
||||
other_entry_points.push_back(
|
||||
point_info(turn.operations[other_op_id].seg_id, turn.point) );
|
||||
m_other_entry_points.push_back(
|
||||
point_info(turn.point, turn.operations[other_op_id].seg_id) );
|
||||
}
|
||||
|
||||
// TODO: exit_per_geometry parameter looks not very safe
|
||||
// wrong value may be easily passed
|
||||
|
||||
void exit(TurnInfo const& turn, bool exit_per_geometry = true)
|
||||
{
|
||||
//segment_identifier const& seg_id = turn.operations[op_id].seg_id;
|
||||
@@ -256,22 +256,22 @@ public:
|
||||
|
||||
typedef typename std::vector<point_info>::iterator point_iterator;
|
||||
// search for the entry point in the same range of other geometry
|
||||
point_iterator entry_it = std::find_if(other_entry_points.begin(),
|
||||
other_entry_points.end(),
|
||||
same_single_geometry(other_id));
|
||||
point_iterator entry_it = std::find_if(m_other_entry_points.begin(),
|
||||
m_other_entry_points.end(),
|
||||
same_single(other_id));
|
||||
|
||||
// this end point has corresponding entry point
|
||||
if ( entry_it != other_entry_points.end() )
|
||||
if ( entry_it != m_other_entry_points.end() )
|
||||
{
|
||||
// erase the corresponding entry point
|
||||
other_entry_points.erase(entry_it);
|
||||
m_other_entry_points.erase(entry_it);
|
||||
|
||||
if ( exit_per_geometry || other_entry_points.empty() )
|
||||
if ( exit_per_geometry || m_other_entry_points.empty() )
|
||||
{
|
||||
// here we know that we possibly left LS
|
||||
// we must still check if we didn't get back on the same point
|
||||
exit_operation = exit_op;
|
||||
exit_turn = boost::addressof(turn);
|
||||
m_exit_operation = exit_op;
|
||||
m_exit_turn_ptr = boost::addressof(turn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,53 +279,53 @@ public:
|
||||
bool is_outside() const
|
||||
{
|
||||
// if we didn't entered anything in the past, we're outside
|
||||
return other_entry_points.empty();
|
||||
return m_other_entry_points.empty();
|
||||
}
|
||||
|
||||
bool is_outside(TurnInfo const& turn) const
|
||||
{
|
||||
return other_entry_points.empty()
|
||||
|| std::find_if(other_entry_points.begin(),
|
||||
other_entry_points.end(),
|
||||
same_single_geometry(
|
||||
return m_other_entry_points.empty()
|
||||
|| std::find_if(m_other_entry_points.begin(),
|
||||
m_other_entry_points.end(),
|
||||
same_single(
|
||||
turn.operations[other_op_id].seg_id))
|
||||
== other_entry_points.end();
|
||||
== m_other_entry_points.end();
|
||||
}
|
||||
|
||||
overlay::operation_type get_exit_operation() const
|
||||
{
|
||||
return exit_operation;
|
||||
return m_exit_operation;
|
||||
}
|
||||
|
||||
point_type const& get_exit_point() const
|
||||
{
|
||||
BOOST_ASSERT(exit_operation != overlay::operation_none);
|
||||
BOOST_ASSERT(exit_turn);
|
||||
return exit_turn->point;
|
||||
BOOST_ASSERT(m_exit_operation != overlay::operation_none);
|
||||
BOOST_ASSERT(m_exit_turn_ptr);
|
||||
return m_exit_turn_ptr->point;
|
||||
}
|
||||
|
||||
TurnInfo const& get_exit_turn() const
|
||||
{
|
||||
BOOST_ASSERT(exit_operation != overlay::operation_none);
|
||||
BOOST_ASSERT(exit_turn);
|
||||
return *exit_turn;
|
||||
BOOST_ASSERT(m_exit_operation != overlay::operation_none);
|
||||
BOOST_ASSERT(m_exit_turn_ptr);
|
||||
return *m_exit_turn_ptr;
|
||||
}
|
||||
|
||||
void reset_detected_exit()
|
||||
{
|
||||
exit_operation = overlay::operation_none;
|
||||
m_exit_operation = overlay::operation_none;
|
||||
}
|
||||
|
||||
void reset()
|
||||
{
|
||||
exit_operation = overlay::operation_none;
|
||||
other_entry_points.clear();
|
||||
m_exit_operation = overlay::operation_none;
|
||||
m_other_entry_points.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
overlay::operation_type exit_operation;
|
||||
const TurnInfo * exit_turn;
|
||||
std::vector<point_info> other_entry_points; // TODO: use map here or sorted vector?
|
||||
overlay::operation_type m_exit_operation;
|
||||
const TurnInfo * m_exit_turn_ptr;
|
||||
std::vector<point_info> m_other_entry_points; // TODO: use map here or sorted vector?
|
||||
};
|
||||
|
||||
template <std::size_t OpId, typename Turn>
|
||||
@@ -392,65 +392,6 @@ static inline bool is_ip_on_boundary(IntersectionPoint const& ip,
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO: The tool like this would be useful but this can't be done with the current implementation of
|
||||
// reversible and closeable views because the reference to local variable would be returned!
|
||||
|
||||
//template <typename Geometry>
|
||||
//struct normalized_range_type
|
||||
//{
|
||||
// static const iterate_direction direction = order_as_direction<geometry::point_order<Geometry>::value>::value;
|
||||
// static const closure_selector closure = geometry::closure<Geometry>::value;
|
||||
//
|
||||
// typedef typename ring_type<Geometry>::type ring_type;
|
||||
// typedef typename reversible_view
|
||||
// <
|
||||
// typename boost::mpl::if_c
|
||||
// <
|
||||
// boost::is_const<Geometry>::value,
|
||||
// ring_type const,
|
||||
// ring_type
|
||||
// >::type,
|
||||
// direction
|
||||
// >::type reversible_type;
|
||||
// typedef typename closeable_view
|
||||
// <
|
||||
// typename boost::mpl::if_c
|
||||
// <
|
||||
// boost::is_const<Geometry>::value,
|
||||
// reversible_type const,
|
||||
// reversible_type
|
||||
// >::type,
|
||||
// closure
|
||||
// >::type closeable_type;
|
||||
//
|
||||
// typedef closeable_type type;
|
||||
//};
|
||||
//
|
||||
//template <typename Geometry>
|
||||
//struct normalized_range
|
||||
//{
|
||||
// template <typename Range>
|
||||
// static inline
|
||||
// typename normalized_range_type<Geometry>::type
|
||||
// apply(Range & rng)
|
||||
// {
|
||||
// typename normalized_range_type<Geometry>::reversible_type
|
||||
// rev_view(rng);
|
||||
// typename normalized_range_type<Geometry>::closeable_type
|
||||
// view(rev_view);
|
||||
//
|
||||
//// ERROR! HERE THE REFERENCE TO LOCAL rev_view IS RETURNED!
|
||||
// return view;
|
||||
// }
|
||||
//};
|
||||
//
|
||||
//template <typename Geometry, typename Id>
|
||||
//inline
|
||||
//typename normalized_range_type<Geometry>::type
|
||||
//normalized_sub_range(Geometry & geometry, Id const& id)
|
||||
//{
|
||||
// return normalized_range<Geometry>::apply(detail::sub_range(geometry, id));
|
||||
//}
|
||||
|
||||
}} // namespace detail::relate
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -935,7 +935,7 @@ struct linear_areal
|
||||
|
||||
private:
|
||||
exit_watcher<TurnInfo, op_id> m_exit_watcher;
|
||||
segment_watcher<same_single_geometry> m_seg_watcher;
|
||||
segment_watcher<same_single> m_seg_watcher;
|
||||
TurnInfo * m_previous_turn_ptr;
|
||||
overlay::operation_type m_previous_operation;
|
||||
unsigned m_boundary_counter;
|
||||
|
||||
@@ -102,126 +102,6 @@ private:
|
||||
unsigned m_flags;
|
||||
};
|
||||
|
||||
//enum linestring_kind { linestring_exterior, linestring_point, linestring_closed, linestring_open };
|
||||
//
|
||||
//template <typename Linestring>
|
||||
//linestring_kind check_linestring_kind(Linestring const& ls)
|
||||
//{
|
||||
// std::size_t count = boost::size(ls);
|
||||
// if ( count == 0 )
|
||||
// return linestring_exterior;
|
||||
// else if ( count == 1 )
|
||||
// return linestring_point;
|
||||
// else
|
||||
// {
|
||||
// bool equal_fb = equals::equals_point_point(range::front(ls), range::back(ls));
|
||||
// if ( equal_fb )
|
||||
// {
|
||||
// typedef typename boost::range_iterator<Linestring const>::type iterator;
|
||||
// iterator first = boost::begin(ls);
|
||||
// ++first;
|
||||
// iterator last = boost::end(ls);
|
||||
// --last;
|
||||
// for ( iterator it = first ; it != last ; ++it )
|
||||
// {
|
||||
// if ( !equals::equals_point_point(range::front(ls), *it) )
|
||||
// return linestring_closed;
|
||||
// }
|
||||
//
|
||||
// return linestring_point;
|
||||
// }
|
||||
// else
|
||||
// return linestring_open;
|
||||
// }
|
||||
//}
|
||||
|
||||
// Called in a loop for:
|
||||
// Ls/Ls - worst O(N) - 1x point_in_geometry(MLs)
|
||||
// Ls/MLs - worst O(N) - 1x point_in_geometry(MLs)
|
||||
// MLs/Ls - worst O(N^2) - Bx point_in_geometry(Ls)
|
||||
// MLs/MLs - worst O(N^2) - Bx point_in_geometry(Ls)
|
||||
// TODO: later use spatial index
|
||||
//template <std::size_t OpId, typename Result, typename BoundaryChecker, typename OtherGeometry>
|
||||
//class disjoint_linestring_pred_with_point_size_handling
|
||||
//{
|
||||
// static const bool transpose_result = OpId != 0;
|
||||
//
|
||||
//public:
|
||||
// disjoint_linestring_pred_with_point_size_handling(Result & res,
|
||||
// BoundaryChecker & boundary_checker,
|
||||
// OtherGeometry const& other_geometry)
|
||||
// : m_result_ptr(boost::addressof(res))
|
||||
// , m_boundary_checker_ptr(boost::addressof(boundary_checker))
|
||||
// , m_other_geometry(boost::addressof(other_geometry))
|
||||
// , m_detected_mask_point(0)
|
||||
// , m_detected_open_boundary(false)
|
||||
// {}
|
||||
//
|
||||
// template <typename Linestring>
|
||||
// bool operator()(Linestring const& linestring)
|
||||
// {
|
||||
// linestring_kind lk = check_linestring_kind(linestring);
|
||||
//
|
||||
// if ( lk == linestring_point ) // just an optimization
|
||||
// {
|
||||
// if ( m_detected_mask_point != 7 )
|
||||
// {
|
||||
// // check the relation
|
||||
// int pig = within::point_in_geometry(range::front(linestring), *m_other_geometry);
|
||||
//
|
||||
// // point inside
|
||||
// if ( pig > 0 )
|
||||
// {
|
||||
// update<interior, interior, '0', transpose_result>(*m_result_ptr);
|
||||
// m_detected_mask_point |= 1;
|
||||
// }
|
||||
// // point on boundary
|
||||
// else if ( pig == 0 )
|
||||
// {
|
||||
// update<interior, boundary, '0', transpose_result>(*m_result_ptr);
|
||||
// m_detected_mask_point |= 2;
|
||||
// }
|
||||
// // point outside
|
||||
// else
|
||||
// {
|
||||
// update<interior, exterior, '0', transpose_result>(*m_result_ptr);
|
||||
// m_detected_mask_point |= 4;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// // NOTE: For closed Linestrings I/I=1 could be set automatically
|
||||
// // but for MultiLinestrings endpoints of closed Linestrings must also be checked for boundary
|
||||
// else if ( lk == linestring_open || lk == linestring_closed )
|
||||
// {
|
||||
// if ( !m_detected_open_boundary ) // just an optimization
|
||||
// {
|
||||
// update<interior, exterior, '1', transpose_result>(*m_result_ptr);
|
||||
//
|
||||
// // check if there is a boundary
|
||||
// if ( m_boundary_checker_ptr->template
|
||||
// is_endpoint_boundary<boundary_front>(range::front(linestring))
|
||||
// || m_boundary_checker_ptr->template
|
||||
// is_endpoint_boundary<boundary_back>(range::back(linestring)) )
|
||||
// {
|
||||
// update<boundary, exterior, '0', transpose_result>(*m_result_ptr);
|
||||
//
|
||||
// m_detected_open_boundary = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// bool all_detected = m_detected_mask_point == 7 && m_detected_open_boundary;
|
||||
// return !all_detected && !m_result_ptr->interrupt;
|
||||
// }
|
||||
//
|
||||
//private:
|
||||
// Result * m_result_ptr;
|
||||
// BoundaryChecker * m_boundary_checker_ptr;
|
||||
// const OtherGeometry * m_other_geometry;
|
||||
// char m_detected_mask_point;
|
||||
// bool m_detected_open_boundary;
|
||||
//};
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct linear_linear
|
||||
{
|
||||
@@ -833,7 +713,7 @@ struct linear_linear
|
||||
|
||||
private:
|
||||
exit_watcher<TurnInfo, OpId> m_exit_watcher;
|
||||
segment_watcher<same_single_geometry> m_seg_watcher;
|
||||
segment_watcher<same_single> m_seg_watcher;
|
||||
const TurnInfo * m_previous_turn_ptr;
|
||||
overlay::operation_type m_previous_operation;
|
||||
const TurnInfo * m_degenerated_turn_ptr;
|
||||
|
||||
Reference in New Issue
Block a user