diff --git a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp index 08f176865..78fa03798 100644 --- a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp +++ b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp @@ -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 // WARNING! This class stores pointers! // Passing a reference to local variable will result in undefined behavior! - -// TODO: rename to point_id_ref? template -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 - bool operator()(point_identifier const& pid) const + bool operator()(point_info 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 +template 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_info; + typedef detail::relate::point_info 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::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 other_entry_points; // TODO: use map here or sorted vector? + overlay::operation_type m_exit_operation; + const TurnInfo * m_exit_turn_ptr; + std::vector m_other_entry_points; // TODO: use map here or sorted vector? }; template @@ -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 -//struct normalized_range_type -//{ -// static const iterate_direction direction = order_as_direction::value>::value; -// static const closure_selector closure = geometry::closure::value; -// -// typedef typename ring_type::type ring_type; -// typedef typename reversible_view -// < -// typename boost::mpl::if_c -// < -// boost::is_const::value, -// ring_type const, -// ring_type -// >::type, -// direction -// >::type reversible_type; -// typedef typename closeable_view -// < -// typename boost::mpl::if_c -// < -// boost::is_const::value, -// reversible_type const, -// reversible_type -// >::type, -// closure -// >::type closeable_type; -// -// typedef closeable_type type; -//}; -// -//template -//struct normalized_range -//{ -// template -// static inline -// typename normalized_range_type::type -// apply(Range & rng) -// { -// typename normalized_range_type::reversible_type -// rev_view(rng); -// typename normalized_range_type::closeable_type -// view(rev_view); -// -//// ERROR! HERE THE REFERENCE TO LOCAL rev_view IS RETURNED! -// return view; -// } -//}; -// -//template -//inline -//typename normalized_range_type::type -//normalized_sub_range(Geometry & geometry, Id const& id) -//{ -// return normalized_range::apply(detail::sub_range(geometry, id)); -//} }} // namespace detail::relate #endif // DOXYGEN_NO_DETAIL diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index 27c5b8ef2..40c161582 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -935,7 +935,7 @@ struct linear_areal private: exit_watcher m_exit_watcher; - segment_watcher m_seg_watcher; + segment_watcher m_seg_watcher; TurnInfo * m_previous_turn_ptr; overlay::operation_type m_previous_operation; unsigned m_boundary_counter; diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index 371481ff0..aab01f2e2 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -102,126 +102,6 @@ private: unsigned m_flags; }; -//enum linestring_kind { linestring_exterior, linestring_point, linestring_closed, linestring_open }; -// -//template -//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::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 -//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 -// 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(*m_result_ptr); -// m_detected_mask_point |= 1; -// } -// // point on boundary -// else if ( pig == 0 ) -// { -// update(*m_result_ptr); -// m_detected_mask_point |= 2; -// } -// // point outside -// else -// { -// update(*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(*m_result_ptr); -// -// // check if there is a boundary -// if ( m_boundary_checker_ptr->template -// is_endpoint_boundary(range::front(linestring)) -// || m_boundary_checker_ptr->template -// is_endpoint_boundary(range::back(linestring)) ) -// { -// update(*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 struct linear_linear { @@ -833,7 +713,7 @@ struct linear_linear private: exit_watcher m_exit_watcher; - segment_watcher m_seg_watcher; + segment_watcher m_seg_watcher; const TurnInfo * m_previous_turn_ptr; overlay::operation_type m_previous_operation; const TurnInfo * m_degenerated_turn_ptr;