From 333cfdccfb14100b259b852271cab9e6175fb457 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 28 Apr 2014 10:29:45 +0300 Subject: [PATCH 01/11] [turns] rename less functor from less_seg_dist_other_op to less_seg_fraction_other_op (to indicate that the fraction comparison is now used) --- .../geometry/algorithms/detail/overlay/linear_linear.hpp | 2 +- .../geometry/algorithms/detail/turns/compare_turns.hpp | 4 ++-- test/algorithms/test_get_turns_ll_invariance.hpp | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp index d0a4d56f0..3db50f589 100644 --- a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -201,7 +201,7 @@ protected: // sort by seg_id, distance, and operation std::sort(boost::begin(turns), boost::end(turns), - detail::turns::less_seg_dist_other_op<>()); + detail::turns::less_seg_fraction_other_op<>()); // remove duplicate turns turns::remove_duplicate_turns diff --git a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp index f06140b7b..7e21c654e 100644 --- a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp @@ -27,14 +27,14 @@ namespace detail { namespace turns // TURNS SORTING AND SEARCHING // sort turns by G1 - source_index == 0 by: -// seg_id -> distance -> other_id -> operation +// seg_id -> fraction -> other_id -> operation template < typename IdLess = std::less, int N = 0, int U = 1, int I = 2, int B = 3, int C = 4, int O = 0, std::size_t OpId = 0 > -struct less_seg_dist_other_op +struct less_seg_fraction_other_op { BOOST_STATIC_ASSERT(OpId < 2); diff --git a/test/algorithms/test_get_turns_ll_invariance.hpp b/test/algorithms/test_get_turns_ll_invariance.hpp index 460face4e..b0c981e64 100644 --- a/test/algorithms/test_get_turns_ll_invariance.hpp +++ b/test/algorithms/test_get_turns_ll_invariance.hpp @@ -122,16 +122,16 @@ public: filter_continue_turns::apply(rturns_wo_cont); std::sort(boost::begin(turns_all), boost::end(turns_all), - bg_turns::less_seg_dist_other_op<>()); + bg_turns::less_seg_fraction_other_op<>()); std::sort(boost::begin(turns_wo_cont), boost::end(turns_wo_cont), - bg_turns::less_seg_dist_other_op<>()); + bg_turns::less_seg_fraction_other_op<>()); std::sort(boost::begin(rturns_all), boost::end(rturns_all), - bg_turns::less_seg_dist_other_op >()); + bg_turns::less_seg_fraction_other_op >()); std::sort(boost::begin(rturns_wo_cont), boost::end(rturns_wo_cont), - bg_turns::less_seg_dist_other_op >()); + bg_turns::less_seg_fraction_other_op >()); remove_duplicate_turns::apply(turns_all); remove_duplicate_turns::apply(turns_wo_cont); From f25e0c2d7ee9fa5639c9fece27af043842ced50b Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 28 Apr 2014 12:07:08 +0300 Subject: [PATCH 02/11] [test][set ops] separate tests with multiple points as different test cases --- .../algorithms/intersection_linear_linear.cpp | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/test/algorithms/intersection_linear_linear.cpp b/test/algorithms/intersection_linear_linear.cpp index 930cb0f41..5f5b9821b 100644 --- a/test/algorithms/intersection_linear_linear.cpp +++ b/test/algorithms/intersection_linear_linear.cpp @@ -667,6 +667,28 @@ BOOST_AUTO_TEST_CASE( test_intersection_linestring_multilinestring ) from_wkt("MULTILINESTRING((1 0,18 0,19 0))"), "lmli18a" ); +} + + + + + + +#ifndef BOOST_GEOMETRY_TEST_NO_DEGENERATE +BOOST_AUTO_TEST_CASE( test_intersection_l_ml_degenerate ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; + std::cout << "*** LINESTRING / MULTILINESTRING INTERSECTION" + << " (DEGENERATE) ***" + << std::endl; + std::cout << std::endl; +#endif + + typedef linestring_type L; + typedef multi_linestring_type ML; + + typedef test_intersection_of_geometries tester; // the following test cases concern linestrings with duplicate // points and possibly linestrings with zero length. @@ -719,7 +741,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_linestring_multilinestring ) "lmli20d" ); } - +#endif // BOOST_GEOMETRY_TEST_NO_DEGENERATE @@ -738,7 +760,7 @@ BOOST_AUTO_TEST_CASE( test_intersection_multilinestring_linestring ) typedef test_intersection_of_geometries tester; - // the inertsection code automatically reverses the order of the + // the intersection code automatically reverses the order of the // geometries according to the geometry IDs. // all calls below are actually reversed, and internally the // intersection of the linestring with the multi-linestring is @@ -1071,8 +1093,28 @@ BOOST_AUTO_TEST_CASE( test_intersection_multilinestring_multilinestring ) #endif "mlmli18a" ); +} + + + + +#ifndef BOOST_GEOMETRY_TEST_NO_DEGENERATE +BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; + std::cout << "*** MULTILINESTRING / MULTILINESTRING INTERSECTION" + << " (DEGENERATE) ***" + << std::endl; + std::cout << std::endl; +#endif + + typedef multi_linestring_type ML; + + typedef test_intersection_of_geometries tester; + // the following test cases concern linestrings with duplicate // points and possibly linestrings with zero length. @@ -1165,3 +1207,4 @@ BOOST_AUTO_TEST_CASE( test_intersection_multilinestring_multilinestring ) "mlmli20e" ); } +#endif // BOOST_GEOMETRY_TEST_NO_DEGENERATE From 82ce56765ddd187803144872661bc2565f5b8e1a Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 28 Apr 2014 12:07:56 +0300 Subject: [PATCH 03/11] [test][set ops] separate test with duplicate points as different test cases; add test cases with spikes; --- test/algorithms/difference_linear_linear.cpp | 148 +++++++++++++++++++ 1 file changed, 148 insertions(+) diff --git a/test/algorithms/difference_linear_linear.cpp b/test/algorithms/difference_linear_linear.cpp index ecbcb438f..4da8e4174 100644 --- a/test/algorithms/difference_linear_linear.cpp +++ b/test/algorithms/difference_linear_linear.cpp @@ -616,6 +616,13 @@ BOOST_AUTO_TEST_CASE( test_difference_linestring_multilinestring ) from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10))"), "lmldf19" ); + + tester::apply + (from_wkt("LINESTRING(0 0,10 0)"), + from_wkt("MULTILINESTRING((-1 0,0 0),(10 0,12 0))"), + from_wkt("MULTILINESTRING((0 0,10 0))"), + "lmldf20" + ); } @@ -907,6 +914,34 @@ BOOST_AUTO_TEST_CASE( test_difference_multilinestring_multilinestring ) "mlmldf18a" ); + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((-1 0,0 0),(10 0,12 0))"), + from_wkt("MULTILINESTRING((0 0,10 0))"), + "mlmldf19" + ); +} + + + + + + +#ifndef BOOST_GEOMETRY_TEST_NO_DEGENERATE +BOOST_AUTO_TEST_CASE( test_difference_ml_ml_degenerate ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; + std::cout << "*** MULTILINESTRING / MULTILINESTRING DIFFERENCE" + << " (DEGENERATE) ***" + << std::endl; + std::cout << std::endl; +#endif + + typedef multi_linestring_type ML; + + typedef test_difference_of_geometries tester; + // the following test cases concern linestrings with duplicate // points and possibly linestrings with zero length. @@ -975,3 +1010,116 @@ BOOST_AUTO_TEST_CASE( test_difference_multilinestring_multilinestring ) "mlmldf23" ); } +#endif // BOOST_GEOMETRY_TEST_NO_DEGENERATE + + + + +BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; + std::cout << "*** MULTILINESTRING / MULTILINESTRING DIFFERENCE" + << " (WITH SPIKES) ***" + << std::endl; + std::cout << std::endl; +#endif + + typedef multi_linestring_type ML; + + typedef test_difference_of_geometries tester; + + // the following test cases concern linestrings with spikes + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,5 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + "mlmldf-spikes-01" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((9 0,1 0,5 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + "mlmldf-spikes-02" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,2 0,8 0,3 0,7 0,4 0,5 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + "mlmldf-spikes-03" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,3 0,2 0,4 0,3 0,5 0,4 0,6 0,\ + 5 0,7 0,6 0,8 0,7 0,9 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + "mlmldf-spikes-04" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),\ + (9 1,9 0,9 2))"), + from_wkt("MULTILINESTRING((0 0,1 0),(6 0,7 0),(8 0,10 0))"), + "mlmldf-spikes-05" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),\ + (9 0,9 2,9 1))"), + from_wkt("MULTILINESTRING((0 0,1 0),(6 0,7 0),(8 0,10 0))"), + "mlmldf-spikes-05a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(9 0,6 0,8 0),\ + (11 0,8 0,12 0))"), + from_wkt("MULTILINESTRING((0 0,1 0))"), + "mlmldf-spikes-06" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((-1 0,0 0,-2 0),(11 0,10 0,12 0))"), + from_wkt("MULTILINESTRING((0 0,10 0))"), + "mlmldf-spikes-07" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((-1 -1,0 0,-2 -2),(11 1,10 0,12 2))"), + from_wkt("MULTILINESTRING((0 0,10 0))"), + "mlmldf-spikes-07a" + ); + +#if 0 + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(11 0,10 0,12 0),\ + (7 5,7 0,8 0,6.5 0,8.5 0,8.5 5))"), + from_wkt("MULTILINESTRING((0 0,1 0),(6 0,6.5 0),(8.5 0,10 0))"), + "mlmldf-spikes-08" + ); +#endif + + // now the first geometry has a spike + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(8 0,10 0,8 0))"), + "mlmldf-spikes-10" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0,4 0),(2 0,9 0,5 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0,9 0))"), + "mlmldf-spikes-11" + ); +} From d7c6c3918275e645f04140639ddc2c206bf204ac Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 30 Apr 2014 12:09:37 +0300 Subject: [PATCH 04/11] [test][difference L/L] add a couple more test cases of geometries with spikes --- test/algorithms/difference_linear_linear.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/test/algorithms/difference_linear_linear.cpp b/test/algorithms/difference_linear_linear.cpp index 4da8e4174..9044b5f88 100644 --- a/test/algorithms/difference_linear_linear.cpp +++ b/test/algorithms/difference_linear_linear.cpp @@ -1098,7 +1098,7 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) "mlmldf-spikes-07a" ); -#if 0 +#if 0 // get_turns has a bug for this one tester::apply (from_wkt("MULTILINESTRING((0 0,10 0))"), from_wkt("MULTILINESTRING((1 0,6 0,5 0),(11 0,10 0,12 0),\ @@ -1122,4 +1122,20 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0,9 0))"), "mlmldf-spikes-11" ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 1,10 0,12 2))"), + from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + "mlmldf-spikes-12" + ); + +#if 0 // get_turns has a bug for this one + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 0,10 0,12 0))"), + from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + "mlmldf-spikes-13" + ); +#endif } From a5056728b7e275f68f5b4b75184f149b27b4b398 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 30 Apr 2014 12:11:13 +0300 Subject: [PATCH 05/11] [copyright headers] unify the way they look --- .../algorithms/detail/overlay/intersection_insert.hpp | 4 ++-- include/boost/geometry/algorithms/union.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp index b3d3e80d8..173639e9a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/intersection_insert.hpp @@ -5,12 +5,12 @@ // This file was modified by Oracle on 2014. // Modifications copyright (c) 2014 Oracle and/or its affiliates. +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index ca9b8ff11..bfd0ab3ba 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -5,12 +5,12 @@ // This file was modified by Oracle on 2014. // Modifications copyright (c) 2014 Oracle and/or its affiliates. +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_UNION_HPP #define BOOST_GEOMETRY_ALGORITHMS_UNION_HPP From 65e111866945b8d7a3732f8b491d432143bd5a7c Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 30 Apr 2014 12:12:27 +0300 Subject: [PATCH 06/11] [algorithms][overlay] allow for spikes in output likestrings; this modifies the behavior of existing set ops and allows to support linear geometries with spikes; change copy_segments for linestrings to take a template parameter to control whether spikes are accepted or not; by default they are not accepted (but the follow code now explicitly allows for them in places where it wasn't; --- .../detail/overlay/copy_segments.hpp | 54 ++++++++++++++----- .../algorithms/detail/overlay/follow.hpp | 19 ++++--- .../detail/overlay/follow_linear_linear.hpp | 11 ++-- 3 files changed, 60 insertions(+), 24 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index f2306d4d9..626224563 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -1,6 +1,11 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. + +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -12,6 +17,7 @@ #include #include +#include #include #include @@ -28,6 +34,7 @@ #include #include +#include #include namespace boost { namespace geometry @@ -39,7 +46,7 @@ namespace detail { namespace copy_segments { -template +template struct copy_segments_ring { template @@ -102,9 +109,32 @@ struct copy_segments_ring } }; -template -struct copy_segments_linestring +template +class copy_segments_linestring { +private: + // remove spikes + template + static inline void append_to_output(RangeOut& current_output, + Point const& point, + RobustPolicy const& robust_policy, + boost::true_type const&) + { + detail::overlay::append_no_dups_or_spikes(current_output, point, + robust_policy); + } + + // keep spikes + template + static inline void append_to_output(RangeOut& current_output, + Point const& point, + RobustPolicy const&, + boost::false_type const&) + { + detail::overlay::append_no_duplicates(current_output, point); + } + +public: template < typename LineString, @@ -133,13 +163,13 @@ struct copy_segments_linestring for (size_type i = 0; i < count; ++i, ++it) { - detail::overlay::append_no_dups_or_spikes(current_output, *it, - robust_policy); + append_to_output(current_output, *it, robust_policy, + boost::integral_constant()); } } }; -template +template struct copy_segments_polygon { template @@ -168,7 +198,7 @@ struct copy_segments_polygon }; -template +template struct copy_segments_box { template @@ -224,24 +254,24 @@ struct copy_segments : not_implemented {}; -template +template struct copy_segments : detail::copy_segments::copy_segments_ring {}; -template +template struct copy_segments : detail::copy_segments::copy_segments_linestring {}; -template +template struct copy_segments : detail::copy_segments::copy_segments_polygon {}; -template +template struct copy_segments : detail::copy_segments::copy_segments_box {}; diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index 38dc05119..ea0263c47 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -5,12 +5,12 @@ // This file was modified by Oracle on 2014. // Modifications copyright (c) 2014 Oracle and/or its affiliates. +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle + // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_FOLLOW_HPP @@ -193,7 +193,10 @@ struct action_selector { // On leave, copy all segments from starting point, append the intersection point // and add the output piece - geometry::copy_segments(linestring, segment_id, index, robust_policy, current_piece); + detail::copy_segments::copy_segments_linestring + < + false, false // do not reverse; do not remove spikes + >::apply(linestring, segment_id, index, robust_policy, current_piece); detail::overlay::append_no_duplicates(current_piece, point); if (::boost::size(current_piece) > 1) { @@ -484,10 +487,12 @@ public : if (action::is_entered(entered)) { - geometry::copy_segments(linestring, current_segment_id, - boost::size(linestring) - 1, - robust_policy, - current_piece); + detail::copy_segments::copy_segments_linestring + < + false, false // do not reverse; do not remove spikes + >::apply(linestring, current_segment_id, + boost::size(linestring) - 1, robust_policy, + current_piece); } // Output the last one, if applicable diff --git a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp index c009df00d..beb8fa710 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -268,11 +268,12 @@ protected: // We don't rescale linear/linear detail::no_rescale_policy robust_policy; - geometry::copy_segments(linestring, - current_segment_id, - boost::size(linestring) - 1, - robust_policy, - current_piece); + detail::copy_segments::copy_segments_linestring + < + false, false // do not reverse; do not remove spikes + >::apply(linestring, current_segment_id, + boost::size(linestring) - 1, robust_policy, + current_piece); } // Output the last one, if applicable From 98e6dd3783ebb3b7758335da5ab195788b891bd7 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 30 Apr 2014 15:57:51 +0300 Subject: [PATCH 07/11] [overlay] add template parameter to follow and action_selector about removing spikes; the default behavior is to remove them; this is backward compatible with the code before the changes in copy_segments --- .../algorithms/detail/overlay/follow.hpp | 28 +++++++++++-------- .../detail/overlay/follow_linear_linear.hpp | 3 +- 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index ea0263c47..632f79f40 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -140,7 +140,7 @@ static inline bool was_entered(Turn const& turn, Operation const& op, bool first // Template specialization structure to call the right actions for the right type -template +template struct action_selector { // If you get here the overlay type is not intersection or difference @@ -148,8 +148,8 @@ struct action_selector }; // Specialization for intersection, containing the implementation -template<> -struct action_selector +template +struct action_selector { template < @@ -195,7 +195,7 @@ struct action_selector // and add the output piece detail::copy_segments::copy_segments_linestring < - false, false // do not reverse; do not remove spikes + false, RemoveSpikes >::apply(linestring, segment_id, index, robust_policy, current_piece); detail::overlay::append_no_duplicates(current_piece, point); if (::boost::size(current_piece) > 1) @@ -251,10 +251,10 @@ struct action_selector }; // Specialization for difference, which reverses these actions -template<> -struct action_selector +template +struct action_selector { - typedef action_selector normal_action; + typedef action_selector normal_action; template < @@ -346,12 +346,13 @@ template typename LineStringOut, typename LineString, typename Polygon, - overlay_type OverlayType + overlay_type OverlayType, + bool RemoveSpikes = true > class follow { - template + template struct sort_on_segment { // In case of turn point at the same location, we want to have continue/blocked LAST @@ -412,7 +413,10 @@ public : Geometry const& geometry, RobustPolicy const& robust_policy) { - return following::action_selector::included(point, geometry, robust_policy); + return following::action_selector + < + OverlayType, RemoveSpikes + >::included(point, geometry, robust_policy); } template @@ -434,7 +438,7 @@ public : typename turn_type::container_type >::type turn_operation_iterator_type; - typedef following::action_selector action; + typedef following::action_selector action; // Sort intersection points on segments-along-linestring, and distance // (like in enrich is done for poly/poly) @@ -489,7 +493,7 @@ public : { detail::copy_segments::copy_segments_linestring < - false, false // do not reverse; do not remove spikes + false, RemoveSpikes >::apply(linestring, current_segment_id, boost::size(linestring) - 1, robust_policy, current_piece); diff --git a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp index beb8fa710..131154f82 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -173,7 +173,8 @@ template class follow_linestring_linear_linestring { protected: - typedef following::action_selector action; + // allow spikes (false indicates: do not remove spikes) + typedef following::action_selector action; template < From 606295db4af1b6b82b6ecf5321be862d45691302 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 5 May 2014 12:08:36 +0300 Subject: [PATCH 08/11] [test][set ops L/L] add more test cases for difference and intersection of linear geometries; the geometries in these test cases have spikes --- test/algorithms/difference_linear_linear.cpp | 83 ++++- .../algorithms/intersection_linear_linear.cpp | 313 ++++++++++++++++++ 2 files changed, 392 insertions(+), 4 deletions(-) diff --git a/test/algorithms/difference_linear_linear.cpp b/test/algorithms/difference_linear_linear.cpp index 9044b5f88..cbd0d3698 100644 --- a/test/algorithms/difference_linear_linear.cpp +++ b/test/algorithms/difference_linear_linear.cpp @@ -401,6 +401,21 @@ BOOST_AUTO_TEST_CASE( test_difference_linestring_linestring ) from_wkt("MULTILINESTRING((0 0,1 0),(5 0,10 0))"), "lldf23" ); + + // the following two tests have been discussed with by Adam + tester::apply + (from_wkt("LINESTRING(1 0,1 1,2 1)"), + from_wkt("LINESTRING(2 1,1 1,1 0)"), + from_wkt("MULTILINESTRING()"), + "lldf24" + ); + + tester::apply + (from_wkt("LINESTRING(1 0,1 1,2 1)"), + from_wkt("LINESTRING(1 2,1 1,1 0)"), + from_wkt("MULTILINESTRING((1 1,2 1))"), + "lldf25" + ); } @@ -1098,7 +1113,6 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) "mlmldf-spikes-07a" ); -#if 0 // get_turns has a bug for this one tester::apply (from_wkt("MULTILINESTRING((0 0,10 0))"), from_wkt("MULTILINESTRING((1 0,6 0,5 0),(11 0,10 0,12 0),\ @@ -1106,9 +1120,36 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) from_wkt("MULTILINESTRING((0 0,1 0),(6 0,6.5 0),(8.5 0,10 0))"), "mlmldf-spikes-08" ); -#endif // now the first geometry has a spike + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(8 0,10 0))"), + "mlmldf-spikes-09" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,7 0,4 0,9 0))"), + "mlmldf-spikes-09a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(9 0,10 0))"), + from_wkt("MULTILINESTRING((5 0,7 0,5 0),(5 0,9 0))"), + "mlmldf-spikes-09b" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(6 0,10 0))"), + from_wkt("MULTILINESTRING((5 0,6 0),(6 0,5 0),(5 0,6 0))"), + "mlmldf-spikes-09c" + ); + tester::apply (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), from_wkt("MULTILINESTRING((1 0,8 0))"), @@ -1130,12 +1171,46 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) "mlmldf-spikes-12" ); -#if 0 // get_turns has a bug for this one + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 -1,10 0,12 -2))"), + from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + "mlmldf-spikes-12a" + ); + tester::apply (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), from_wkt("MULTILINESTRING((11 0,10 0,12 0))"), from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), "mlmldf-spikes-13" ); -#endif + + // the following three tests have been discussed with Adam + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((1 2,1 1,1 2))"), + from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + "mlmldf-spikes-14" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 0,0 0))"), + from_wkt("MULTILINESTRING((2 0,1 0,2 0))"), + from_wkt("MULTILINESTRING((0 0,1 0,0 0))"), + "mlmldf-spikes-15" + ); + + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((2 0,1 1,2 0))"), + from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + "mlmldf-spikes-16" + ); + + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((2 1,1 1,2 1))"), + from_wkt("MULTILINESTRING((1 0,1 1))"), + "mlmldf-spikes-17" + ); } diff --git a/test/algorithms/intersection_linear_linear.cpp b/test/algorithms/intersection_linear_linear.cpp index 5f5b9821b..f18a1e4b1 100644 --- a/test/algorithms/intersection_linear_linear.cpp +++ b/test/algorithms/intersection_linear_linear.cpp @@ -461,6 +461,21 @@ BOOST_AUTO_TEST_CASE( test_intersection_linestring_linestring ) from_wkt("MULTILINESTRING((1 0,4 0),(4 0,5 0))"), "lli23" ); + + // the following two tests have been discussed with by Adam + tester::apply + (from_wkt("LINESTRING(1 0,1 1,2 1)"), + from_wkt("LINESTRING(2 1,1 1,1 0)"), + from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + "lli24" + ); + + tester::apply + (from_wkt("LINESTRING(1 0,1 1,2 1)"), + from_wkt("LINESTRING(1 2,1 1,1 0)"), + from_wkt("MULTILINESTRING((1 0,1 1))"), + "lli25" + ); } @@ -700,8 +715,12 @@ BOOST_AUTO_TEST_CASE( test_intersection_l_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (4 0,4 10,4 10))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),(4 0),\ (5 0,18 0,19 0,20 0))"), +#endif "lmli20a" ); @@ -712,8 +731,12 @@ BOOST_AUTO_TEST_CASE( test_intersection_l_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (4 0,4 0,4 10,4 10))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),(4 0),\ (5 0,18 0,19 0,20 0))"), +#endif "lmli20b" ); @@ -724,8 +747,12 @@ BOOST_AUTO_TEST_CASE( test_intersection_l_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (30 0,30 0,30 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),\ (5 0,18 0,19 0,20 0),(30 0))"), +#endif "lmli20c" ); @@ -736,8 +763,12 @@ BOOST_AUTO_TEST_CASE( test_intersection_l_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (30 0,30 0,31 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),\ (5 0,18 0,19 0,20 0),(30 0))"), +#endif "lmli20d" ); } @@ -1126,10 +1157,15 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 1,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 10),\ (4 0,4 10),(5 5,5 5))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), + from_wkt("MULTILINESTRING((5 0,20 0))"), +#else from_wkt("MULTILINESTRING((5 5),(0 0),(1 0),(2 0),(3 0),\ (4 0),(5 0,18 0,19 0,20 0),(2 0),(4 10))"), from_wkt("MULTILINESTRING((5 0,20 0),(1 0),(2 0),(2 0),(3 0),\ (0 0),(4 0),(4 10),(5 5))"), +#endif "mlmli20a" ); @@ -1141,10 +1177,15 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (4 0,4 10,4 10),(5 5,5 5))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), + from_wkt("MULTILINESTRING((5 0,20 0))"), +#else from_wkt("MULTILINESTRING((5 5),(0 0),(1 0),(2 0),(3 0),(4 0),\ (5 0,18 0,19 0,20 0),(2 0),(4 10))"), from_wkt("MULTILINESTRING((5 0,20 0),(1 0),(2 0),(2 0),\ (3 0),(0 0),(4 0),(4 10),(5 5))"), +#endif "mlmli20aa" ); @@ -1156,10 +1197,15 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (4 0,4 0,4 10,4 10),(0 5,15 5))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), + from_wkt("MULTILINESTRING((5 0,20 0))"), +#else from_wkt("MULTILINESTRING((5 5),(0 0),(1 0),(2 0),(3 0),(4 0),\ (5 0,18 0,19 0,20 0))"), from_wkt("MULTILINESTRING((5 0,20 0),(1 0),(2 0),(3 0),\ (0 0),(4 0),(5 5))"), +#endif "mlmli20b" ); @@ -1171,10 +1217,15 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (30 0,30 0,30 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), + from_wkt("MULTILINESTRING((5 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),\ (5 0,18 0,19 0,20 0),(30 0))"), from_wkt("MULTILINESTRING((5 0,20 0),(1 0),(2 0),(3 0),\ (0 0),(30 0))"), +#endif "mlmli20c" ); @@ -1186,10 +1237,15 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 1,1 1,2 2,2 2),(1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (30 0,30 0,31 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,20 0))"), + from_wkt("MULTILINESTRING((5 0,20 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),\ (5 0,18 0,19 0,20 0),(30 0))"), from_wkt("MULTILINESTRING((5 0,20 0),(1 0),(2 0),(3 0),\ (0 0),(30 0))"), +#endif "mlmli20d" ); @@ -1200,11 +1256,268 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_degenerate ) (1 10,1 10,1 0,1 0,1 -10),\ (2 0,2 0),(3 0,3 0,3 0),(0 0,0 0,0 10,0 10),\ (30 0,30 0,31 0,31 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((5 0,18 0,19 0,30 0))"), + from_wkt("MULTILINESTRING((5 0,20 0,30 0))"), +#else from_wkt("MULTILINESTRING((0 0),(1 0),(2 0),(3 0),\ (5 0,18 0,19 0,30 0),(30 0))"), from_wkt("MULTILINESTRING((5 0,20 0,30 0),(1 0),(2 0),(3 0),\ (0 0),(30 0))"), +#endif "mlmli20e" ); } #endif // BOOST_GEOMETRY_TEST_NO_DEGENERATE + + + + +BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_spikes ) +{ +#ifdef GEOMETRY_TEST_DEBUG + std::cout << std::endl << std::endl << std::endl; + std::cout << "*** MULTILINESTRING / MULTILINESTRING INTERSECTION" + << " (WITH SPIKES) ***" + << std::endl; + std::cout << std::endl; +#endif + + typedef multi_linestring_type ML; + + typedef test_intersection_of_geometries tester; + + // the following test cases concern linestrings with spikes + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,9 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,5 0))"), + "mlmli-spikes-01" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((9 0,1 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,9 0))"), + from_wkt("MULTILINESTRING((9 0,1 0,5 0))"), + "mlmli-spikes-02" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,2 0,8 0,3 0,7 0,4 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,9 0))"), + from_wkt("MULTILINESTRING((1 0,9 0,2 0,8 0,3 0,7 0,4 0,5 0))"), + "mlmli-spikes-03" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,3 0,2 0,4 0,3 0,5 0,4 0,6 0,\ + 5 0,7 0,6 0,8 0,7 0,9 0))"), + from_wkt("MULTILINESTRING((1 0,9 0))"), + from_wkt("MULTILINESTRING((1 0,3 0,2 0,4 0,3 0,5 0,4 0,6 0,\ + 5 0,7 0,6 0,8 0,7 0,9 0))"), + "mlmli-spikes-04" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),\ + (9 1,9 0,9 2))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((1 0,6 0),(7 0,8 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0))"), +#else + from_wkt("MULTILINESTRING((1 0,6 0),(7 0,8 0),(9 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),(9 0))"), +#endif + "mlmli-spikes-05" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),\ + (9 0,9 2,9 1))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((1 0,6 0),(7 0,8 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0))"), +#else + from_wkt("MULTILINESTRING((1 0,6 0),(7 0,8 0),(9 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,7 0),(9 0))"), +#endif + "mlmli-spikes-05a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(9 0,6 0,8 0),\ + (11 0,8 0,12 0))"), + from_wkt("MULTILINESTRING((1 0,6 0),(6 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(9 0,6 0,8 0),\ + (10 0,8 0,10 0))"), + "mlmli-spikes-06" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((-1 0,0 0,-2 0),(11 0,10 0,12 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((0 0),(10 0))"), +#endif + "mlmli-spikes-07" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((-1 -1,0 0,-2 -2),(11 1,10 0,12 2))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((0 0),(10 0))"), +#endif + "mlmli-spikes-07a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(11 0,10 0,12 0),\ + (7 5,7 0,8 0,6.5 0,8.5 0,8.5 5))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING((1 0,6 0),(6.5 0,8.5 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,6.5 0,8.5 0))"), +#else + from_wkt("MULTILINESTRING((1 0,6 0),(6.5 0,8.5 0),(10 0))"), + from_wkt("MULTILINESTRING((1 0,6 0,5 0),(7 0,8 0,6.5 0,8.5 0),(10 0))"), +#endif + "mlmli-spikes-08" + ); + + // now the first geometry has a spike + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + from_wkt("MULTILINESTRING((1 0,7 0,4 0,8 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + "mlmli-spikes-09" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,1 0),(9 0,10 0))"), + "mlmli-spikes-09a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(9 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(5 0,4 0,5 0),(9 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(9 0,10 0))"), + "mlmli-spikes-09b" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,7 0,4 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(6 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(6 0,7 0,6 0),(5 0,4 0,5 0),\ + (6 0,10 0))"), + from_wkt("MULTILINESTRING((0 0,5 0),(6 0,10 0))"), + "mlmli-spikes-09c" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + from_wkt("MULTILINESTRING((1 0,8 0),(8 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0))"), + "mlmli-spikes-10" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0,4 0),(2 0,9 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,9 0),(9 0,5 0))"), + from_wkt("MULTILINESTRING((1 0,8 0,4 0),(2 0,9 0,5 0))"), + "mlmli-spikes-11" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 1,10 0,12 2))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((10 0))"), +#endif + "mlmli-spikes-12" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 -1,10 0,12 -2))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((10 0))"), +#endif + "mlmli-spikes-12a" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,10 0,5 0))"), + from_wkt("MULTILINESTRING((11 0,10 0,12 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((10 0))"), +#endif + "mlmli-spikes-13" + ); + + // the following three tests have been discussed with Adam + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((1 2,1 1,1 2))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((1 1))"), +#endif + "mlmli-spikes-14" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 0,0 0))"), + from_wkt("MULTILINESTRING((2 0,1 0,2 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((1 0))"), +#endif + "mlmli-spikes-15" + ); + + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((2 0,1 1,2 0))"), +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + from_wkt("MULTILINESTRING()"), +#else + from_wkt("MULTILINESTRING((1 1))"), +#endif + "mlmli-spikes-16" + ); + + tester::apply + (from_wkt("MULTILINESTRING((1 0,1 1,2 1))"), + from_wkt("MULTILINESTRING((2 1,1 1,2 1))"), + from_wkt("MULTILINESTRING((1 1,2 1))"), + from_wkt("MULTILINESTRING((2 1,1 1,2 1))"), + "mlmli-spikes-17" + ); +} From 826045c3a11ef087f8821b5e0c070320b848376f Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 5 May 2014 12:10:20 +0300 Subject: [PATCH 09/11] [set ops L/L] remove commented code in assign_policy; add template parameter to control the behavior of intersection wrt whether isolated points are followed or not; --- .../detail/overlay/linear_linear.hpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp index 3db50f589..db9e91fb6 100644 --- a/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/linear_linear.hpp @@ -125,7 +125,12 @@ template overlay_type OverlayType, bool EnableFilterContinueTurns = false, bool EnableRemoveDuplicateTurns = false, - bool EnableDegenerateTurns = true + bool EnableDegenerateTurns = true, +#ifdef BOOST_GEOMETRY_INTERSECTION_DO_NOT_INCLUDE_ISOLATED_POINTS + bool EnableFollowIsolatedPoints = false +#else + bool EnableFollowIsolatedPoints = true +#endif > class linear_linear_linestring { @@ -147,7 +152,6 @@ protected: static inline void apply(Info& , Point1 const& , Point2 const& , IntersectionInfo const& , DirInfo const& ) { - //calculate_distance_policy::apply(info, p1, p2, ii, di); } }; @@ -256,7 +260,9 @@ public: return sort_and_follow_turns < - OverlayType, OverlayType == overlay_intersection + OverlayType, + EnableFollowIsolatedPoints + && OverlayType == overlay_intersection >(turns, linear1, linear2, oit); } }; @@ -271,13 +277,14 @@ template typename LinestringOut, bool EnableFilterContinueTurns, bool EnableRemoveDuplicateTurns, - bool EnableDegenerateTurns + bool EnableDegenerateTurns, + bool EnableFollowIsolatedPoints > struct linear_linear_linestring < Linear1, Linear2, LinestringOut, overlay_union, EnableFilterContinueTurns, EnableRemoveDuplicateTurns, - EnableDegenerateTurns + EnableDegenerateTurns, EnableFollowIsolatedPoints > { template @@ -302,7 +309,7 @@ struct linear_linear_linestring < Linear2, Linear1, LinestringOut, overlay_difference, EnableFilterContinueTurns, EnableRemoveDuplicateTurns, - EnableDegenerateTurns + EnableDegenerateTurns, EnableFollowIsolatedPoints >::apply(linear2, linear1, robust_policy, oit, strategy); } }; From 321d12c56ac37c0c70a546cec9d64855b23a9ca3 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Mon, 5 May 2014 14:45:26 +0300 Subject: [PATCH 10/11] [test][set ops L/L] add two more test cases with spikes (examples sent by Adam on the BG mailing list) --- test/algorithms/difference_linear_linear.cpp | 15 +++++++++++++++ test/algorithms/intersection_linear_linear.cpp | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/test/algorithms/difference_linear_linear.cpp b/test/algorithms/difference_linear_linear.cpp index cbd0d3698..f46bcddf3 100644 --- a/test/algorithms/difference_linear_linear.cpp +++ b/test/algorithms/difference_linear_linear.cpp @@ -1213,4 +1213,19 @@ BOOST_AUTO_TEST_CASE( test_difference_ml_ml_spikes ) from_wkt("MULTILINESTRING((1 0,1 1))"), "mlmldf-spikes-17" ); + + // test cases sent by Adam on the mailing list (equal slikes) + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING()"), + "mlmldf-spikes-18" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((1 1,0 0,1 1))"), + from_wkt("MULTILINESTRING()"), + "mlmldf-spikes-19" + ); } diff --git a/test/algorithms/intersection_linear_linear.cpp b/test/algorithms/intersection_linear_linear.cpp index f18a1e4b1..33891571d 100644 --- a/test/algorithms/intersection_linear_linear.cpp +++ b/test/algorithms/intersection_linear_linear.cpp @@ -1520,4 +1520,20 @@ BOOST_AUTO_TEST_CASE( test_intersection_ml_ml_spikes ) from_wkt("MULTILINESTRING((2 1,1 1,2 1))"), "mlmli-spikes-17" ); + + // test cases sent by Adam on the mailing list (equal slikes) + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + "mlmli-spikes-18" + ); + + tester::apply + (from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((1 1,0 0,1 1))"), + from_wkt("MULTILINESTRING((0 0,1 1,0 0))"), + from_wkt("MULTILINESTRING((1 1,0 0,1 1))"), + "mlmli-spikes-19" + ); } From 793a6321c6f22c751d5fa89b0402da1f5abda104 Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Tue, 6 May 2014 21:51:15 +0300 Subject: [PATCH 11/11] [copy segments] replace generic #include of type traits by the specific one used (integral_constant) --- .../boost/geometry/algorithms/detail/overlay/copy_segments.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index 626224563..05b348a6d 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include