[relate] refactor relate helpers.

Remove unused, commented-out code.
Improve the names.
This commit is contained in:
Adam Wulkiewicz
2014-04-27 16:08:30 +02:00
parent 6bbabf9867
commit d41be62461
3 changed files with 47 additions and 226 deletions

View File

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

View File

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

View File

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