From 6e52b356e78fffdcad33d4896f44fb2852ecab9f Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 1 Oct 2014 09:26:46 +0300 Subject: [PATCH 01/44] [algorithms][for_each] fix bug in for_each_segment for open geometries without using the closeable_view (so that mutable geometries can also be supported) --- .../boost/geometry/algorithms/for_each.hpp | 55 ++++++++++++++----- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/include/boost/geometry/algorithms/for_each.hpp b/include/boost/geometry/algorithms/for_each.hpp index f23a42d21..c5c099b1a 100644 --- a/include/boost/geometry/algorithms/for_each.hpp +++ b/include/boost/geometry/algorithms/for_each.hpp @@ -41,8 +41,7 @@ #include #include - -#include +#include namespace boost { namespace geometry @@ -95,30 +94,23 @@ struct fe_range_per_point }; -struct fe_range_per_segment +template +struct fe_range_per_segment_with_closure { template static inline void apply(Range& range, Functor& f) { - typedef typename closeable_view - < - Range, closure::value - >::type view_type; - typedef typename add_const_if_c < is_const::value, typename point_type::type >::type point_type; - typedef typename boost::range_iterator::type - iterator_type; + typedef typename boost::range_iterator::type iterator_type; - view_type view(range); - - iterator_type it = boost::begin(view); + iterator_type it = boost::begin(range); iterator_type previous = it++; - while(it != boost::end(view)) + while(it != boost::end(range)) { model::referring_segment s(*previous, *it); f(s); @@ -128,6 +120,41 @@ struct fe_range_per_segment }; +template <> +struct fe_range_per_segment_with_closure +{ + template + static inline void apply(Range& range, Functor& f) + { + fe_range_per_segment_with_closure::apply(range, f); + + model::referring_segment + < + typename add_const_if_c + < + is_const::value, + typename point_type::type + >::type + > s(range::back(range), range::front(range)); + + f(s); + } +}; + + +struct fe_range_per_segment +{ + template + static inline void apply(Range& range, Functor& f) + { + fe_range_per_segment_with_closure + < + closure::value + >::apply(range, f); + } +}; + + struct fe_polygon_per_point { template From 03d505061af835d0c68566210d76f518b941dffe Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Wed, 1 Oct 2014 09:35:46 +0300 Subject: [PATCH 02/44] [test][algorithms][distance] add test case between linestring and open multipolygon where the distance is realized between the linestring and an implicit segment of the multipolygon --- test/algorithms/distance_linear_areal.cpp | 25 +++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/test/algorithms/distance_linear_areal.cpp b/test/algorithms/distance_linear_areal.cpp index 1665da019..b50b16853 100644 --- a/test/algorithms/distance_linear_areal.cpp +++ b/test/algorithms/distance_linear_areal.cpp @@ -28,6 +28,7 @@ typedef bg::model::multi_linestring multi_linestring_type; typedef bg::model::polygon polygon_type; typedef bg::model::polygon open_polygon_type; typedef bg::model::multi_polygon multi_polygon_type; +typedef bg::model::multi_polygon open_multipolygon_type; typedef bg::model::ring ring_type; typedef bg::model::box box_type; typedef bg::model::box int_box_type; @@ -212,6 +213,29 @@ void test_distance_linestring_multipolygon(Strategy const& strategy) //=========================================================================== +template +void test_distance_linestring_open_multipolygon(Strategy const& strategy) +{ +#ifdef BOOST_GEOMETRY_TEST_DEBUG + std::cout << std::endl; + std::cout << "linestring/open multipolygon distance tests" << std::endl; +#endif + typedef test_distance_of_geometries + < + linestring_type, open_multipolygon_type + > tester; + + tester::apply("linestring(-5 1,-2 1)", + "multipolygon(((0 0,10 0,10 10,0 10)))", + 2, 4, strategy, true); + + tester::apply("linestring(-5 1,-3 1)", + "multipolygon(((20 20,21 20,21 21,20 21)),((0 0,10 0,10 10,0 10)))", + 3, 9, strategy, true); +} + +//=========================================================================== + template void test_distance_multilinestring_multipolygon(Strategy const& strategy) { @@ -883,6 +907,7 @@ BOOST_AUTO_TEST_CASE( test_all_segment_multipolygon ) BOOST_AUTO_TEST_CASE( test_all_linestring_multipolygon ) { test_distance_linestring_multipolygon(point_segment_strategy()); + test_distance_linestring_open_multipolygon(point_segment_strategy()); } BOOST_AUTO_TEST_CASE( test_all_multilinestring_multipolygon ) From 1e968c3590d5ae078bc158717b238bd54bd03377 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 25 Sep 2014 12:00:13 +0200 Subject: [PATCH 03/44] [index] Add default template parameters in the implementation of is_valid. Remove MPL assert --- .../index/detail/algorithms/is_valid.hpp | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/include/boost/geometry/index/detail/algorithms/is_valid.hpp b/include/boost/geometry/index/detail/algorithms/is_valid.hpp index 0450f3b65..d85ac56d6 100644 --- a/include/boost/geometry/index/detail/algorithms/is_valid.hpp +++ b/include/boost/geometry/index/detail/algorithms/is_valid.hpp @@ -1,6 +1,6 @@ // Boost.Geometry Index // -// n-dimensional box's / point validity check +// n-dimensional Indexable validity check // // Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // @@ -11,20 +11,17 @@ #ifndef BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP #define BOOST_GEOMETRY_INDEX_DETAIL_ALGORITHMS_IS_VALID_HPP +#include +#include + namespace boost { namespace geometry { namespace index { namespace detail { namespace dispatch { -template +template ::value> struct is_valid_box { - BOOST_MPL_ASSERT_MSG( - (0 < dimension::value && - 0 < Dimension && - Dimension <= static_cast(dimension::value)), - INVALID_DIMENSION_PARAMETER, - (is_valid_box)); - static inline bool apply(Box const& b) { return is_valid_box::apply(b) && @@ -41,7 +38,8 @@ struct is_valid_box } }; -template +template ::type> struct is_valid { BOOST_MPL_ASSERT_MSG( @@ -64,7 +62,7 @@ struct is_valid { static inline bool apply(Indexable const& b) { - return dispatch::is_valid_box::value>::apply(b); + return dispatch::is_valid_box::apply(b); } }; @@ -82,7 +80,7 @@ struct is_valid template inline bool is_valid(Indexable const& b) { - return dispatch::is_valid::type>::apply(b); + return dispatch::is_valid::apply(b); } }}}} // namespace boost::geometry::index::detail From 39802e79236eaf1a1d212b9c10ec68e9cae6bed7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 1 Oct 2014 16:49:49 +0200 Subject: [PATCH 04/44] [core] Add MPL_ASSERT for coordinate dimension > 0 --- include/boost/geometry/core/coordinate_dimension.hpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/core/coordinate_dimension.hpp b/include/boost/geometry/core/coordinate_dimension.hpp index e11ff33af..85da6b424 100644 --- a/include/boost/geometry/core/coordinate_dimension.hpp +++ b/include/boost/geometry/core/coordinate_dimension.hpp @@ -58,7 +58,15 @@ template struct dimension : dimension::type> {}; template -struct dimension : traits::dimension::type> {}; +struct dimension + : traits::dimension::type> +{ + BOOST_MPL_ASSERT_MSG( + (traits::dimension::type>::value > 0), + INVALID_DIMENSION_VALUE, + (traits::dimension::type>) + ); +}; } // namespace core_dispatch #endif From add58fec8c34bfa10a17eac8d3610ff0d6a048df Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 1 Oct 2014 16:58:29 +0200 Subject: [PATCH 05/44] [iterators] Fix the description of closing_iterator<>. --- include/boost/geometry/iterators/closing_iterator.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index 7cd8fa015..a9f67d478 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -28,8 +28,9 @@ namespace boost { namespace geometry \brief Iterator which iterates through a range, but adds first element at end of the range \tparam Range range on which this class is based on \ingroup iterators -\note Use with "closing_iterator or "closing_iterator - to get non-const / const behaviour +\note It's const iterator treating the Range as one containing non-mutable elements. + For both "closing_iterator and "closing_iterator + const reference is always returned when dereferenced. \note This class is normally used from "closeable_view" if Close==true */ template From 8481591e5c09cdb897916ca837dcd4d2c488a6fe Mon Sep 17 00:00:00 2001 From: Menelaos Karavelas Date: Thu, 2 Oct 2014 12:52:56 +0300 Subject: [PATCH 06/44] [test][algorithms][for_each] add test cases for open geometries (open ring, open polygon, open multipolygon) --- test/algorithms/for_each.cpp | 25 ++++++++++++++++++++++++ test/multi/algorithms/multi_for_each.cpp | 15 ++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/test/algorithms/for_each.cpp b/test/algorithms/for_each.cpp index 2efe10f2c..09e94fa04 100644 --- a/test/algorithms/for_each.cpp +++ b/test/algorithms/for_each.cpp @@ -54,6 +54,18 @@ void test_all() , 4 * 3.0 , "POLYGON((10 1,10 4,4 4,4 1,1 1))" ); + test_geometry > // open ring + ( + "POLYGON((1 1,1 4,4 4,4 1))" + + , 10 + , "POLYGON((101 1,101 4,104 4,104 1))" + , "POLYGON((101 100,101 400,104 400,104 100))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1))" + , 4 * 3.0 + , "POLYGON((10 1,10 4,4 4,4 1))" + ); test_geometry > ( "POLYGON((1 1,1 4,4 4,4 1,1 1),(2 2,3 2,3 3,2 3,2 2))" @@ -67,6 +79,19 @@ void test_all() , 4 * 3.0 + 4 * 1.0 , "POLYGON((10 1,10 4,4 4,4 1,1 1,10 1),(2 2,3 2,3 3,2 3,2 2))" ); + test_geometry > // open polygon + ( + "POLYGON((1 1,1 4,4 4,4 1),(2 2,3 2,3 3,2 3))" + + , 20 + , "POLYGON((101 1,101 4,104 4,104 1,101 1),(102 2,103 2,103 3,102 3,102 2))" + , "POLYGON((101 100,101 400,104 400,104 100,101 100),(102 200,103 200,103 300,102 300,102 200))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1)) " + "((2, 2), (3, 2)) ((3, 2), (3, 3)) ((3, 3), (2, 3)) ((2, 3), (2, 2))" + , 4 * 3.0 + 4 * 1.0 + , "POLYGON((10 1,10 4,4 4,4 1,10 1),(2 2,3 2,3 3,2 3,2 2))" + ); } int test_main(int, char* []) diff --git a/test/multi/algorithms/multi_for_each.cpp b/test/multi/algorithms/multi_for_each.cpp index b16930dba..70165a44f 100644 --- a/test/multi/algorithms/multi_for_each.cpp +++ b/test/multi/algorithms/multi_for_each.cpp @@ -70,6 +70,21 @@ void test_all() , 4 * 3.0 , "MULTIPOLYGON(((10 1,10 4,4 4,4 1,1 1,10 1)))" ); + + // open multipolygon + typedef bg::model::multi_polygon > omp; + test_geometry + ( + "MULTIPOLYGON(((1 1,1 4,4 4,4 1)))" + + , 10 + , "MULTIPOLYGON(((101 1,101 4,104 4,104 1,101 1)))" + , "MULTIPOLYGON(((101 100,101 400,104 400,104 100,101 100)))" + + , "((1, 1), (1, 4)) ((1, 4), (4, 4)) ((4, 4), (4, 1)) ((4, 1), (1, 1))" + , 4 * 3.0 + , "MULTIPOLYGON(((10 1,10 4,4 4,4 1,10 1)))" + ); } int test_main( int , char* [] ) From b2dfd7f0c8c75f2edb45ee6d4bd61a10c48caedd Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 19:57:20 +0200 Subject: [PATCH 07/44] [index] Use default Dimension templ. params in content() and margin() algorithms. Replace traits::dimension<> with geometry::dimension<>. --- .../index/detail/algorithms/content.hpp | 16 ++++++----- .../index/detail/algorithms/margin.hpp | 28 ++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/include/boost/geometry/index/detail/algorithms/content.hpp b/include/boost/geometry/index/detail/algorithms/content.hpp index 1c4739d8e..028113e0e 100644 --- a/include/boost/geometry/index/detail/algorithms/content.hpp +++ b/include/boost/geometry/index/detail/algorithms/content.hpp @@ -2,7 +2,7 @@ // // n-dimensional content (hypervolume) - 2d area, 3d volume, ... // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -24,11 +24,11 @@ struct default_content_result namespace dispatch { -template +template ::value> struct content_box { BOOST_STATIC_ASSERT(0 < CurrentDimension); - //BOOST_STATIC_ASSERT(CurrentDimension <= traits::dimension::value); static inline typename detail::default_content_result::type apply(Box const& b) { @@ -66,7 +66,7 @@ struct content { static typename default_content_result::type apply(Indexable const& b) { - return dispatch::content_box::value>::apply(b); + return dispatch::content_box::apply(b); } }; @@ -75,9 +75,11 @@ struct content template typename default_content_result::type content(Indexable const& b) { - return dispatch::content::type - >::apply(b); + return dispatch::content + < + Indexable, + typename tag::type + >::apply(b); } }}}} // namespace boost::geometry::index::detail diff --git a/include/boost/geometry/index/detail/algorithms/margin.hpp b/include/boost/geometry/index/detail/algorithms/margin.hpp index 8e2685ab3..d4876600a 100644 --- a/include/boost/geometry/index/detail/algorithms/margin.hpp +++ b/include/boost/geometry/index/detail/algorithms/margin.hpp @@ -2,7 +2,7 @@ // // n-dimensional box's margin value (hypersurface), 2d perimeter, 3d surface, etc... // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -25,7 +25,9 @@ struct default_margin_result >::type type; }; -//template +//template ::value> //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -38,7 +40,7 @@ struct default_margin_result // } //}; // -//template +//template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -49,7 +51,7 @@ struct default_margin_result // } //}; // -//template +//template //struct margin_for_each_edge //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); @@ -69,16 +71,16 @@ struct default_margin_result // } //}; // -//template +//template ::value> //struct margin_for_each_dimension //{ // BOOST_STATIC_ASSERT(0 < CurrentDimension); -// BOOST_STATIC_ASSERT(CurrentDimension <= detail::traits::dimension::value); // // static inline typename default_margin_result::type apply(Box const& b) // { // return margin_for_each_dimension::apply(b) + -// margin_for_each_edge::value>::apply(b); +// margin_for_each_edge::apply(b); // } //}; // @@ -87,7 +89,7 @@ struct default_margin_result //{ // static inline typename default_margin_result::type apply(Box const& b) // { -// return margin_for_each_edge::value>::apply(b); +// return margin_for_each_edge::apply(b); // } //}; @@ -95,11 +97,11 @@ struct default_margin_result // Now it's sum of edges lengths // maybe margin_for_each_dimension should be used to get more or less hypersurface? -template +template ::value> struct simple_margin_for_each_dimension { BOOST_STATIC_ASSERT(0 < CurrentDimension); - //BOOST_STATIC_ASSERT(CurrentDimension <= dimension::value); static inline typename default_margin_result::type apply(Box const& b) { @@ -140,8 +142,8 @@ struct comparable_margin static inline result_type apply(Box const& g) { - //return detail::margin_for_each_dimension::value>::apply(g); - return detail::simple_margin_for_each_dimension::value>::apply(g); + //return detail::margin_for_each_dimension::apply(g); + return detail::simple_margin_for_each_dimension::apply(g); } }; @@ -159,7 +161,7 @@ typename default_margin_result::type comparable_margin(Geometry const& //template //typename default_margin_result::type margin(Box const& b) //{ -// return 2 * detail::margin_for_each_dimension::value>::apply(b); +// return 2 * detail::margin_for_each_dimension::apply(b); //} }}}} // namespace boost::geometry::index::detail From eabb17b7e45ab7950b5d7413c18c9adfa247419d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 20:06:02 +0200 Subject: [PATCH 08/44] [index] Replace uses of traits:xxx with geometry::xxx metafunctions. --- include/boost/geometry/index/detail/rtree/pack_create.hpp | 6 +++--- include/boost/geometry/index/detail/serialization.hpp | 4 ++-- include/boost/geometry/index/indexable.hpp | 6 +++++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/pack_create.hpp b/include/boost/geometry/index/detail/rtree/pack_create.hpp index e3ac16aef..46bf357fc 100644 --- a/include/boost/geometry/index/detail/rtree/pack_create.hpp +++ b/include/boost/geometry/index/detail/rtree/pack_create.hpp @@ -125,11 +125,11 @@ class pack typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::size_type size_type; - typedef typename traits::point_type::type point_type; - typedef typename traits::coordinate_type::type coordinate_type; + typedef typename geometry::point_type::type point_type; + typedef typename geometry::coordinate_type::type coordinate_type; typedef typename detail::default_content_result::type content_type; typedef typename Options::parameters_type parameters_type; - static const std::size_t dimension = traits::dimension::value; + static const std::size_t dimension = geometry::dimension::value; typedef typename rtree::container_from_elements_type< typename rtree::elements_type::type, diff --git a/include/boost/geometry/index/detail/serialization.hpp b/include/boost/geometry/index/detail/serialization.hpp index fd5e371d4..f518810f8 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -225,7 +225,7 @@ template void serialize(Archive &, boost::geometry::index::dynami // TODO - move to index/detail/serialization.hpp or maybe geometry/serialization.hpp namespace boost { namespace geometry { namespace index { namespace detail { -template ::value> +template ::value> struct serialize_point { template @@ -239,7 +239,7 @@ struct serialize_point template static inline void load(Archive & ar, P & p, unsigned int version) { - typename traits::coordinate_type

::type c; + typename geometry::coordinate_type

::type c; ar >> boost::serialization::make_nvp("c", c); set(p, c); serialize_point::load(ar, p, version); diff --git a/include/boost/geometry/index/indexable.hpp b/include/boost/geometry/index/indexable.hpp index 5270ca22e..391b544f3 100644 --- a/include/boost/geometry/index/indexable.hpp +++ b/include/boost/geometry/index/indexable.hpp @@ -29,7 +29,11 @@ template struct is_indexable { static const bool value = - is_indexable_impl::type>::value; + is_indexable_impl + < + Indexable, + typename geometry::tag::type + >::value; }; /*! From ff98b648ee0a86d59b16e7ff5911254606eae1bb Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 21:22:11 +0200 Subject: [PATCH 09/44] [index] Update copyrights info. --- include/boost/geometry/index/detail/serialization.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/geometry/index/detail/serialization.hpp b/include/boost/geometry/index/detail/serialization.hpp index f518810f8..34036e390 100644 --- a/include/boost/geometry/index/detail/serialization.hpp +++ b/include/boost/geometry/index/detail/serialization.hpp @@ -1,6 +1,6 @@ // Boost.Geometry Index // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at From d32066530c5312e4f636b7678e2d4d0b79ec194e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 21:22:32 +0200 Subject: [PATCH 10/44] [index] Support objects of type convertible to value_type in insert() and remove(). In previous implementation such objects was falling into the overload taking Range. --- include/boost/geometry/index/rtree.hpp | 119 ++++++++++++++++++++----- 1 file changed, 98 insertions(+), 21 deletions(-) diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 09f07ffe7..a66c74cae 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -590,9 +590,9 @@ public: } /*! - \brief Insert a range of values to the index. + \brief Insert an object of type convertible to value_type or a range of values to the index. - \param rng The range of values. + \param val_conv_or_rng An object of type convertible to value_type or a range of values. \par Throws \li If Value copy constructor or copy assignment throws. @@ -604,17 +604,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline void insert(Range const& rng) + template + inline void insert(ValueConvertibleOrRange const& val_conv_or_rng) { - BOOST_MPL_ASSERT_MSG((detail::is_range::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range)); + typedef boost::mpl::bool_ + < + boost::is_convertible::value + > is_conv_t; - if ( !m_members.root ) - this->raw_create(); - - typedef typename boost::range_const_iterator::type It; - for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) - this->raw_insert(*it); + this->insert_dispatch(val_conv_or_rng, is_conv_t()); } /*! @@ -675,13 +673,13 @@ public: } /*! - \brief Remove a range of values from the container. + \brief Remove an object of type convertible to value_type or a range of values from the container. In contrast to the \c std::set or std::map erase() method it removes values equal to these passed as a range. Furthermore, this method removes only one value for each one passed in the range, not all equal values. - \param rng The range of values. + \param val_conv_or_rng The object of type convertible to value_type or a range of values. \return The number of removed values. @@ -695,16 +693,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline size_type remove(Range const& rng) + template + inline size_type remove(ValueConvertibleOrRange const& val_conv_or_rng) { - BOOST_MPL_ASSERT_MSG((detail::is_range::value), PASSED_OBJECT_IS_NOT_A_RANGE, (Range)); + typedef boost::mpl::bool_ + < + boost::is_convertible::value + > is_conv_t; - size_type result = 0; - typedef typename boost::range_const_iterator::type It; - for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) - result += this->raw_remove(*it); - return result; + return this->remove_dispatch(val_conv_or_rng, is_conv_t()); } /*! @@ -1348,6 +1345,86 @@ private: dst.m_members.leafs_level = src.m_members.leafs_level; } + /*! + \brief Insert a value-convertible object into the index. + + \param val_conv The object convertible to value. + + \par Exception-safety + basic + */ + template + inline void insert_dispatch(ValueConvertible const& val_conv, + boost::mpl::bool_ const& /*is_convertible*/) + { + if ( !m_members.root ) + this->raw_create(); + + this->raw_insert(val_conv); + } + + /*! + \brief Insert a range of values into the index. + + \param rng The range of values. + + \par Exception-safety + basic + */ + template + inline void insert_dispatch(Range const& rng, + boost::mpl::bool_ const& /*is_convertible*/) + { + BOOST_MPL_ASSERT_MSG((detail::is_range::value), + PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE, + (Range)); + + if ( !m_members.root ) + this->raw_create(); + + typedef typename boost::range_const_iterator::type It; + for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) + this->raw_insert(*it); + } + + /*! + \brief Remove a value-convertible object from the index. + + \param val_conv The value which will be removed from the container. + + \par Exception-safety + basic + */ + template + inline size_type remove_dispatch(ValueConvertible const& val_conv, + boost::mpl::bool_ const& /*is_convertible*/) + { + return this->raw_remove(val_conv); + } + + /*! + \brief Remove a range of values from the index. + + \param rng The range of values which will be removed from the container. + + \par Exception-safety + basic + */ + template + inline size_type remove_dispatch(Range const& rng, + boost::mpl::bool_ const& /*is_convertible*/) + { + BOOST_MPL_ASSERT_MSG((detail::is_range::value), + PASSED_OBJECT_IS_NOT_CONVERTIBLE_TO_VALUE_NOR_A_RANGE, + (Range)); + + size_type result = 0; + typedef typename boost::range_const_iterator::type It; + for ( It it = boost::const_begin(rng); it != boost::const_end(rng) ; ++it ) + result += this->raw_remove(*it); + return result; + } + /*! \brief Return values meeting predicates. From 345869b88320b6712abb0d920a837a7b6c262805 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 21:25:33 +0200 Subject: [PATCH 11/44] [test][index] Add tests for insertion of objects of type convertible to value_type. --- index/test/rtree/Jamfile.v2 | 8 ++- index/test/rtree/rtree_values.cpp | 79 +++++++++++++++++++++++ index/test/rtree/rtree_values_invalid.cpp | 31 +++++++++ 3 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 index/test/rtree/rtree_values.cpp create mode 100644 index/test/rtree/rtree_values_invalid.cpp diff --git a/index/test/rtree/Jamfile.v2 b/index/test/rtree/Jamfile.v2 index d906c8880..463ccb3fa 100644 --- a/index/test/rtree/Jamfile.v2 +++ b/index/test/rtree/Jamfile.v2 @@ -1,6 +1,6 @@ # Boost.Geometry Index # -# Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +# Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. # # Use, modification and distribution is subject to the Boost Software License, # Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -9,3 +9,9 @@ build-project exceptions ; build-project interprocess ; build-project generated ; + +test-suite boost-geometry-index-rtree + : + [ run rtree_values.cpp ] + [ compile-fail rtree_values_invalid.cpp ] + ; diff --git a/index/test/rtree/rtree_values.cpp b/index/test/rtree/rtree_values.cpp new file mode 100644 index 000000000..eec52df49 --- /dev/null +++ b/index/test/rtree/rtree_values.cpp @@ -0,0 +1,79 @@ +// Boost.Geometry Index +// Unit Test + +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. + +// 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) + +#include + + +#include + +struct point +{ + point(double xx = 0, double yy = 0) : x(xx), y(yy) {} + double x, y; +}; + +BOOST_GEOMETRY_REGISTER_POINT_2D(point, double, bg::cs::cartesian, x, y) + + +template +void test_pair() +{ + typedef std::pair Value; + + typename boost::remove_const::type box; + bg::assign_zero(box); + + Value val(box, 0); + + // sanity check + std::vector vec; + vec.push_back(val); + vec.push_back(std::make_pair(box, 0)); + vec.push_back(std::make_pair(box, (unsigned short)0)); + + bgi::rtree rt; + rt.insert(val); + rt.insert(std::make_pair(box, 0)); + rt.insert(std::make_pair(box, (unsigned short)0)); + BOOST_CHECK( rt.size() == 3 ); + + BOOST_CHECK( rt.remove(val) == 1 ); + BOOST_CHECK( rt.remove(std::make_pair(box, 0)) == 1 ); + BOOST_CHECK( rt.remove(std::make_pair(box, (unsigned short)0)) == 1 ); + BOOST_CHECK( rt.size() == 0 ); +} + +template +void test_point() +{ + bgi::rtree rt; + + rt.insert(0.0); + BOOST_CHECK( rt.size() == 1 ); + BOOST_CHECK( rt.remove(0.0) == 1 ); +} + +int test_main(int, char* []) +{ + typedef bg::model::point Pt; + typedef bg::model::box Box; + + test_pair< Box, bgi::linear<16> >(); + test_pair< Box, bgi::quadratic<4> >(); + test_pair< Box, bgi::rstar<4> >(); + //test_rtree< Box const, bgi::linear<16> >(); + //test_rtree< Box const, bgi::quadratic<4> >(); + //test_rtree< Box const, bgi::rstar<4> >(); + + test_point< bgi::linear<16> >(); + test_point< bgi::quadratic<4> >(); + test_point< bgi::rstar<4> >(); + + return 0; +} diff --git a/index/test/rtree/rtree_values_invalid.cpp b/index/test/rtree/rtree_values_invalid.cpp new file mode 100644 index 000000000..d16861331 --- /dev/null +++ b/index/test/rtree/rtree_values_invalid.cpp @@ -0,0 +1,31 @@ +// Boost.Geometry Index +// Unit Test + +// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. + +// 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) + +#include + + +template +void test_rtree() +{ + bgi::rtree rt; + // coordinates aren't implicitly convertible to Point + rt.insert(1.0); + rt.remove(1.0); +} + +int test_main(int, char* []) +{ + typedef bg::model::point Pt; + + test_rtree >(); + test_rtree >(); + test_rtree >(); + + return 0; +} From d331bf262a222e790fb5725e21db309be95e2389 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 21:44:18 +0200 Subject: [PATCH 12/44] [index] Tweak type, variable names and description of member and free rtree insert() and remove() functions. --- include/boost/geometry/index/rtree.hpp | 83 +++++++++++++++----------- 1 file changed, 47 insertions(+), 36 deletions(-) diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index a66c74cae..6836d5b1d 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -590,9 +590,9 @@ public: } /*! - \brief Insert an object of type convertible to value_type or a range of values to the index. + \brief Insert a value created using convertible object or a range of values to the index. - \param val_conv_or_rng An object of type convertible to value_type or a range of values. + \param conv_or_rng An object of type convertible to value_type or a range of values. \par Throws \li If Value copy constructor or copy assignment throws. @@ -604,15 +604,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline void insert(ValueConvertibleOrRange const& val_conv_or_rng) + template + inline void insert(ConvertibleOrRange const& conv_or_rng) { typedef boost::mpl::bool_ < - boost::is_convertible::value + boost::is_convertible::value > is_conv_t; - this->insert_dispatch(val_conv_or_rng, is_conv_t()); + this->insert_dispatch(conv_or_rng, is_conv_t()); } /*! @@ -673,13 +673,13 @@ public: } /*! - \brief Remove an object of type convertible to value_type or a range of values from the container. + \brief Remove value corresponding to an object convertible to it or a range of values from the container. In contrast to the \c std::set or std::map erase() method it removes values equal to these passed as a range. Furthermore, this method removes only one value for each one passed in the range, not all equal values. - \param val_conv_or_rng The object of type convertible to value_type or a range of values. + \param conv_or_rng The object of type convertible to value_type or a range of values. \return The number of removed values. @@ -693,15 +693,15 @@ public: elements must not be inserted or removed. Other operations are allowed however some of them may return invalid data. */ - template - inline size_type remove(ValueConvertibleOrRange const& val_conv_or_rng) + template + inline size_type remove(ConvertibleOrRange const& conv_or_rng) { typedef boost::mpl::bool_ < - boost::is_convertible::value + boost::is_convertible::value > is_conv_t; - return this->remove_dispatch(val_conv_or_rng, is_conv_t()); + return this->remove_dispatch(conv_or_rng, is_conv_t()); } /*! @@ -1346,7 +1346,7 @@ private: } /*! - \brief Insert a value-convertible object into the index. + \brief Insert a value corresponding to convertible object into the index. \param val_conv The object convertible to value. @@ -1388,9 +1388,9 @@ private: } /*! - \brief Remove a value-convertible object from the index. + \brief Remove a value corresponding to convertible object from the index. - \param val_conv The value which will be removed from the container. + \param val_conv The object convertible to value. \par Exception-safety basic @@ -1533,7 +1533,8 @@ It calls rtree::insert(value_type const&). \param v The value which will be stored in the index. */ template -inline void insert(rtree & tree, Value const& v) +inline void insert(rtree & tree, + Value const& v) { tree.insert(v); } @@ -1549,26 +1550,30 @@ It calls rtree::insert(Iterator, Iterator). \param first The beginning of the range of values. \param last The end of the range of values. */ -template -inline void insert(rtree & tree, Iterator first, Iterator last) +template +inline void insert(rtree & tree, + Iterator first, Iterator last) { tree.insert(first, last); } /*! -\brief Insert a range of values to the index. +\brief Insert a value created using convertible object or a range of values to the index. -It calls rtree::insert(Range const&). +It calls rtree::insert(ConvertibleOrRange const&). \ingroup rtree_functions -\param tree The spatial index. -\param rng The range of values. +\param tree The spatial index. +\param conv_or_rng The object of type convertible to value_type or a range of values. */ -template -inline void insert(rtree & tree, Range const& rng) +template +inline void insert(rtree & tree, + ConvertibleOrRange const& conv_or_rng) { - tree.insert(rng); + tree.insert(conv_or_rng); } /*! @@ -1588,7 +1593,8 @@ It calls rtree::remove(value_type const&). */ template inline typename rtree::size_type -remove(rtree & tree, Value const& v) +remove(rtree & tree, + Value const& v) { return tree.remove(v); } @@ -1611,34 +1617,39 @@ It calls rtree::remove(Iterator, Iterator). \return The number of removed values. */ -template +template inline typename rtree::size_type -remove(rtree & tree, Iterator first, Iterator last) +remove(rtree & tree, + Iterator first, Iterator last) { return tree.remove(first, last); } /*! -\brief Remove a range of values from the container. +\brief Remove a value corresponding to an object convertible to it or a range of values from the container. -Remove a range of values from the container. In contrast to the \c std::set or std::map erase() method +Remove a value corresponding to an object convertible to it or a range of values from the container. +In contrast to the \c std::set or std::map erase() method it removes values equal to these passed as a range. Furthermore this method removes only one value for each one passed in the range, not all equal values. -It calls rtree::remove(Range const&). +It calls rtree::remove(ConvertibleOrRange const&). \ingroup rtree_functions -\param tree The spatial index. -\param rng The range of values. +\param tree The spatial index. +\param conv_or_rng The object of type convertible to value_type or the range of values. \return The number of removed values. */ -template +template inline typename rtree::size_type -remove(rtree & tree, Range const& rng) +remove(rtree & tree, + ConvertibleOrRange const& conv_or_rng) { - return tree.remove(rng); + return tree.remove(conv_or_rng); } /*! From 9aed1a0e4e1ac0f1b78ed2155c4c41eb0800c04f Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 21:49:43 +0200 Subject: [PATCH 13/44] [doc] Update reference matrix - new type names in rtree functions. --- doc/quickref.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/quickref.xml b/doc/quickref.xml index 232451723..38801566d 100644 --- a/doc/quickref.xml +++ b/doc/quickref.xml @@ -733,10 +733,10 @@ swap(rtree &) insert(value_type const &) insert(Iterator, Iterator) - insert(Range const &) + insert(ConvertibleOrRange const &) remove(value_type const &) remove(Iterator, Iterator) - remove(Range const &) + remove(ConvertibleOrRange const &) query(Predicates const &, OutIter) qbegin(Predicates const &) qend() @@ -756,10 +756,10 @@ insert(rtree<...> &, Value const &) insert(rtree<...> &, Iterator, Iterator) - insert(rtree<...> &, Range const &) + insert(rtree<...> &, ConvertibleOrRange const &) remove(rtree<...> &, Value const &) remove(rtree<...> &, Iterator, Iterator) - remove(rtree<...> &, Range const &) + remove(rtree<...> &, ConvertibleOrRange const &) query(rtree<...> const &, Predicates const &, OutIter) qbegin(rtree<...> const &, Predicates const &) qend(rtree<...> const &) From a9ac57dc8f42694f697874f988daa6bdaf2cc627 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 23:37:32 +0200 Subject: [PATCH 14/44] [index] Support objects of type convertible to value_type in rtree::count(). --- include/boost/geometry/index/rtree.hpp | 27 +++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/index/rtree.hpp b/include/boost/geometry/index/rtree.hpp index 6836d5b1d..503f47b89 100644 --- a/include/boost/geometry/index/rtree.hpp +++ b/include/boost/geometry/index/rtree.hpp @@ -1088,10 +1088,35 @@ public: template size_type count(ValueOrIndexable const& vori) const { + enum { as_val = 0, as_ind, dont_know }; + typedef boost::mpl::int_ + < + boost::is_same::value ? + as_val : + boost::is_same::value ? + as_ind : + boost::is_convertible::value ? + as_ind : + boost::is_convertible::value ? + as_val : + dont_know + > variant; + + BOOST_MPL_ASSERT_MSG((variant::value != dont_know), + PASSED_OBJECT_NOT_CONVERTIBLE_TO_VALUE_NOR_INDEXABLE_TYPE, + (ValueOrIndexable)); + + typedef typename boost::mpl::if_c + < + variant::value == as_val, + value_type, + indexable_type + >::type value_or_indexable; + if ( !m_members.root ) return 0; - detail::rtree::visitors::count + detail::rtree::visitors::count count_v(vori, m_members.translator()); detail::rtree::apply_visitor(count_v, *m_members.root); From 724f4d3792db59d5d34e220742127cf2629207e7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 23:38:53 +0200 Subject: [PATCH 15/44] [test][index] Add test for rtree::count() taking objects of type convertible to value_type. --- index/test/rtree/rtree_values.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/index/test/rtree/rtree_values.cpp b/index/test/rtree/rtree_values.cpp index eec52df49..2a9c3a0dd 100644 --- a/index/test/rtree/rtree_values.cpp +++ b/index/test/rtree/rtree_values.cpp @@ -43,6 +43,11 @@ void test_pair() rt.insert(std::make_pair(box, (unsigned short)0)); BOOST_CHECK( rt.size() == 3 ); + BOOST_CHECK( rt.count(val) == 3 ); + BOOST_CHECK( rt.count(std::make_pair(box, 0)) == 3 ); + BOOST_CHECK( rt.count(std::make_pair(box, (unsigned short)0)) == 3 ); + BOOST_CHECK( rt.count(box) == 3 ); + BOOST_CHECK( rt.remove(val) == 1 ); BOOST_CHECK( rt.remove(std::make_pair(box, 0)) == 1 ); BOOST_CHECK( rt.remove(std::make_pair(box, (unsigned short)0)) == 1 ); From fa7cd296d37531222363ad592b37265cd474bfec Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 2 Oct 2014 23:40:53 +0200 Subject: [PATCH 16/44] [index] Refactor count rtree visitor. Remove specialization of count visitor for value_type, don't duplicate the same algorithm in 2 places. Move Value/Indexable-aware parts into smaller helper struct and specialize it. --- .../index/detail/rtree/visitors/count.hpp | 97 ++++++++----------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/count.hpp b/include/boost/geometry/index/detail/rtree/visitors/count.hpp index f521944a4..7efd5b702 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/count.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/count.hpp @@ -15,7 +15,37 @@ namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { namespace visitors { -template +template +struct count_helper +{ + template + static inline typename Translator::result_type indexable(Indexable const& i, Translator const&) + { + return i; + } + template + static inline bool equals(Indexable const& i, Value const& v, Translator const& tr) + { + return geometry::equals(i, tr(v)); + } +}; + +template +struct count_helper +{ + template + static inline typename Translator::result_type indexable(Value const& v, Translator const& tr) + { + return tr(v); + } + template + static inline bool equals(Value const& v1, Value const& v2, Translator const& tr) + { + return tr.equals(v1, v2); + } +}; + +template struct count : public rtree::visitor::type { @@ -23,8 +53,10 @@ struct count typedef typename rtree::internal_node::type internal_node; typedef typename rtree::leaf::type leaf; - inline count(Indexable const& i, Translator const& t) - : indexable(i), tr(t), found_count(0) + typedef count_helper count_help; + + inline count(ValueOrIndexable const& vori, Translator const& t) + : value_or_indexable(vori), tr(t), found_count(0) {} inline void operator()(internal_node const& n) @@ -37,7 +69,8 @@ struct count it != elements.end(); ++it) { if ( geometry::covered_by( - return_ref_or_bounds(indexable), + return_ref_or_bounds( + count_help::indexable(value_or_indexable, tr)), it->first) ) { rtree::apply_visitor(*this, *it->second); @@ -55,66 +88,14 @@ struct count it != elements.end(); ++it) { // if value meets predicates - if ( geometry::equals(indexable, tr(*it)) ) + if ( count_help::equals(value_or_indexable, *it, tr) ) { ++found_count; } } } - Indexable const& indexable; - Translator const& tr; - typename Allocators::size_type found_count; -}; - -template -struct count - : public rtree::visitor::type -{ - typedef typename rtree::node::type node; - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; - - inline count(Value const& v, Translator const& t) - : value(v), tr(t), found_count(0) - {} - - inline void operator()(internal_node const& n) - { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); - - // traverse nodes meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) - { - if ( geometry::covered_by( - return_ref_or_bounds(tr(value)), - it->first) ) - { - rtree::apply_visitor(*this, *it->second); - } - } - } - - inline void operator()(leaf const& n) - { - typedef typename rtree::elements_type::type elements_type; - elements_type const& elements = rtree::elements(n); - - // get all values meeting predicates - for (typename elements_type::const_iterator it = elements.begin(); - it != elements.end(); ++it) - { - // if value meets predicates - if ( tr.equals(value, *it) ) - { - ++found_count; - } - } - } - - Value const& value; + ValueOrIndexable const& value_or_indexable; Translator const& tr; typename Allocators::size_type found_count; }; From 6b8aeabbdf189027d964bfa5a7a80c237b30be7e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 4 Oct 2014 00:06:21 +0200 Subject: [PATCH 17/44] [index] Cosmetic changes. Remove unneeded typedefs in nodes. Change the order of template parameters in bgidr::get(dynamic_node<>&) --- .../detail/rtree/node/dynamic_visitor.hpp | 2 +- .../detail/rtree/node/node_d_mem_dynamic.hpp | 32 +++++++++---------- .../detail/rtree/node/node_d_mem_static.hpp | 8 ----- .../detail/rtree/node/node_s_mem_dynamic.hpp | 32 +++++++++---------- .../detail/rtree/node/node_s_mem_static.hpp | 8 ----- 5 files changed, 33 insertions(+), 49 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp index 477d937db..1823b83c1 100644 --- a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp @@ -65,7 +65,7 @@ struct dynamic_visitor // nodes conversion -template +template inline Derived & get(dynamic_node & n) { BOOST_GEOMETRY_INDEX_ASSERT(dynamic_cast(&n), "can't cast to a Derived type"); diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp index 1e3cd58d5..c6b71f5ad 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp @@ -19,14 +19,14 @@ template : public dynamic_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - - typedef boost::container::vector< - rtree::ptr_pair, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + rtree::ptr_pair, + typename Allocators::leaf_allocator_type::template rebind + < + rtree::ptr_pair + >::other + > elements_type; template inline dynamic_internal_node(Al const& al) @@ -43,14 +43,14 @@ template : public dynamic_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - Value - >::other elements_allocator_type; - - typedef boost::container::vector< - Value, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + Value, + typename Allocators::leaf_allocator_type::template rebind + < + Value + >::other + > elements_type; template inline dynamic_leaf(Al const& al) diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp index 184c48e44..57447f463 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp @@ -19,10 +19,6 @@ template : public dynamic_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - typedef detail::varray< rtree::ptr_pair, Parameters::max_elements + 1 @@ -41,10 +37,6 @@ template : public dynamic_node { - typedef typename Allocators::leaf_allocator_type::template rebind< - Value - >::other elements_allocator_type; - typedef detail::varray< Value, Parameters::max_elements + 1 diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp index 8cf7c9c0d..ce55721bc 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp @@ -20,14 +20,14 @@ namespace detail { namespace rtree { template struct static_internal_node { - typedef typename Allocators::node_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - - typedef boost::container::vector< - rtree::ptr_pair, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + rtree::ptr_pair, + typename Allocators::node_allocator_type::template rebind + < + rtree::ptr_pair + >::other + > elements_type; template inline static_internal_node(Al const& al) @@ -40,14 +40,14 @@ struct static_internal_node template struct static_leaf { - typedef typename Allocators::node_allocator_type::template rebind< - Value - >::other elements_allocator_type; - - typedef boost::container::vector< - Value, - elements_allocator_type - > elements_type; + typedef boost::container::vector + < + Value, + typename Allocators::node_allocator_type::template rebind + < + Value + >::other + > elements_type; template inline static_leaf(Al const& al) diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp index 5df869c95..4abb95549 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp @@ -20,10 +20,6 @@ namespace detail { namespace rtree { template struct static_internal_node { - typedef typename Allocators::node_allocator_type::template rebind< - rtree::ptr_pair - >::other elements_allocator_type; - typedef detail::varray< rtree::ptr_pair, Parameters::max_elements + 1 @@ -38,10 +34,6 @@ struct static_internal_node struct static_leaf { - typedef typename Allocators::node_allocator_type::template rebind< - Value - >::other elements_allocator_type; - typedef detail::varray< Value, Parameters::max_elements + 1 From 1f1f663a12efd57621d869828579b6d1abbf390f Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 4 Oct 2014 00:59:06 +0200 Subject: [PATCH 18/44] [index] Replace size_t with proper size_types in rtree remove visitor. --- .../index/detail/rtree/visitors/remove.hpp | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp index 8e6255346..d4890a368 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/remove.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/remove.hpp @@ -32,13 +32,16 @@ class remove typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; + + typedef typename rtree::elements_type::type::size_type internal_size_type; //typedef typename Allocators::internal_node_pointer internal_node_pointer; typedef internal_node * internal_node_pointer; public: inline remove(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& value, parameters_type const& parameters, Translator const& translator, @@ -65,7 +68,7 @@ public: children_type & children = rtree::elements(n); // traverse children which boxes intersects value's box - size_t child_node_index = 0; + internal_size_type child_node_index = 0; for ( ; child_node_index < children.size() ; ++child_node_index ) { if ( geometry::covered_by( @@ -91,7 +94,7 @@ public: if ( m_is_underflow ) { element_iterator underfl_el_it = elements.begin() + child_node_index; - size_t relative_level = m_leafs_level - m_current_level; + size_type relative_level = m_leafs_level - m_current_level; // move node to the container - store node's relative level as well and return new underflow state m_is_underflow = store_underflowed_node(elements, underfl_el_it, relative_level); // MAY THROW (E: alloc, copy) @@ -170,14 +173,14 @@ public: private: - typedef std::vector< std::pair > UnderflowNodes; + typedef std::vector< std::pair > UnderflowNodes; - void traverse_apply_visitor(internal_node &n, size_t choosen_node_index) + void traverse_apply_visitor(internal_node &n, internal_size_type choosen_node_index) { // save previous traverse inputs and set new ones internal_node_pointer parent_bckup = m_parent; - size_t current_child_index_bckup = m_current_child_index; - size_t current_level_bckup = m_current_level; + internal_size_type current_child_index_bckup = m_current_child_index; + size_type current_level_bckup = m_current_level; m_parent = &n; m_current_child_index = choosen_node_index; @@ -195,7 +198,7 @@ private: bool store_underflowed_node( typename rtree::elements_type::type & elements, typename rtree::elements_type::type::iterator underfl_el_it, - size_t relative_level) + size_type relative_level) { // move node to the container - store node's relative level as well m_underflowed_nodes.push_back(std::make_pair(relative_level, underfl_el_it->second)); // MAY THROW (E: alloc, copy) @@ -263,7 +266,7 @@ private: } template - void reinsert_node_elements(Node &n, size_t node_relative_level) + void reinsert_node_elements(Node &n, size_type node_relative_level) { typedef typename rtree::elements_type::type elements_type; elements_type & elements = rtree::elements(n); @@ -302,15 +305,15 @@ private: Allocators & m_allocators; node_pointer & m_root_node; - size_t & m_leafs_level; + size_type & m_leafs_level; bool m_is_value_removed; UnderflowNodes m_underflowed_nodes; // traversing input parameters internal_node_pointer m_parent; - size_t m_current_child_index; - size_t m_current_level; + internal_size_type m_current_child_index; + size_type m_current_level; // traversing output parameters bool m_is_underflow; From 3069084c1587b052aede141a0addf411ece9d512 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 4 Oct 2014 01:29:04 +0200 Subject: [PATCH 19/44] [index] Replace levels type size_t with size_types in rtree insert visitor. --- .../index/detail/rtree/visitors/insert.hpp | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp index a5c16db8a..388b3193f 100644 --- a/include/boost/geometry/index/detail/rtree/visitors/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/visitors/insert.hpp @@ -178,17 +178,20 @@ public: namespace visitors { namespace detail { -template +template struct insert_traverse_data { typedef typename rtree::elements_type::type elements_type; typedef typename elements_type::value_type element_type; + typedef typename elements_type::size_type elements_size_type; + typedef SizeType size_type; insert_traverse_data() : parent(0), current_child_index(0), current_level(0) {} - void move_to_next_level(InternalNodePtr new_parent, size_t new_child_index) + void move_to_next_level(InternalNodePtr new_parent, + elements_size_type new_child_index) { parent = new_parent; current_child_index = new_child_index; @@ -213,8 +216,8 @@ struct insert_traverse_data } InternalNodePtr parent; - size_t current_child_index; - size_t current_level; + elements_size_type current_child_index; + size_type current_level; }; // Default insert visitor @@ -231,17 +234,18 @@ protected: typedef rtree::node_auto_ptr node_auto_ptr; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; //typedef typename Allocators::internal_node_pointer internal_node_pointer; typedef internal_node * internal_node_pointer; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : m_element(element) , m_parameters(parameters) @@ -298,7 +302,8 @@ protected: inline void traverse_apply_visitor(Visitor & visitor, internal_node &n, size_t choosen_node_index) { // save previous traverse inputs and set new ones - insert_traverse_data backup_traverse_data = m_traverse_data; + insert_traverse_data + backup_traverse_data = m_traverse_data; // calculate new traverse inputs m_traverse_data.move_to_next_level(&n, choosen_node_index); @@ -380,14 +385,14 @@ protected: Element const& m_element; parameters_type const& m_parameters; Translator const& m_translator; - const size_t m_relative_level; - const size_t m_level; + size_type const m_relative_level; + size_type const m_level; node_pointer & m_root_node; - size_t & m_leafs_level; + size_type & m_leafs_level; // traversing input parameters - insert_traverse_data m_traverse_data; + insert_traverse_data m_traverse_data; Allocators & m_allocators; }; @@ -414,14 +419,15 @@ public: typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; + typedef typename base::size_type size_type; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) {} @@ -478,14 +484,15 @@ public: typedef typename Options::parameters_type parameters_type; typedef typename base::node_pointer node_pointer; + typedef typename base::size_type size_type; inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& value, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0 + size_type relative_level = 0 ) : base(root, leafs_level, value, parameters, translator, allocators, relative_level) {} From 0db47437f219fbbd25ec9d18a7792abe1a36e907 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 4 Oct 2014 01:40:40 +0200 Subject: [PATCH 20/44] [index] Replace levels type size_t with size_types in R*-tree insert visitor. --- .../index/detail/rtree/rstar/insert.hpp | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp index c903d6ca2..e544d6dd1 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/insert.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/insert.hpp @@ -178,14 +178,15 @@ struct level_insert_base typedef typename Options::parameters_type parameters_type; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; inline level_insert_base(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level) + size_type relative_level) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) , result_relative_level(0) {} @@ -240,7 +241,7 @@ struct level_insert_base } } - size_t result_relative_level; + size_type result_relative_level; result_elements_type result_elements; }; @@ -256,14 +257,15 @@ struct level_insert typedef typename Options::parameters_type parameters_type; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; inline level_insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level) + size_type relative_level) : base(root, leafs_level, element, parameters, translator, allocators, relative_level) {} @@ -341,14 +343,15 @@ struct level_insert typedef typename Options::parameters_type parameters_type; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; inline level_insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Value const& v, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level) + size_type relative_level) : base(root, leafs_level, v, parameters, translator, allocators, relative_level) {} @@ -453,15 +457,16 @@ class insert::type leaf; typedef typename Allocators::node_pointer node_pointer; + typedef typename Allocators::size_type size_type; public: inline insert(node_pointer & root, - size_t & leafs_level, + size_type & leafs_level, Element const& element, parameters_type const& parameters, Translator const& translator, Allocators & allocators, - size_t relative_level = 0) + size_type relative_level = 0) : m_root(root), m_leafs_level(leafs_level), m_element(element) , m_parameters(parameters), m_translator(translator) , m_relative_level(relative_level), m_allocators(allocators) @@ -554,13 +559,13 @@ private: } node_pointer & m_root; - size_t & m_leafs_level; + size_type & m_leafs_level; Element const& m_element; parameters_type const& m_parameters; Translator const& m_translator; - size_t m_relative_level; + size_type m_relative_level; Allocators & m_allocators; }; From 5531315d9894b9e8ad2d9acfa05c8b64e822ece1 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 5 Oct 2014 12:29:28 +0200 Subject: [PATCH 21/44] [index] Move elements-access-related code to separate file, not mixing it with nodes definition. --- .../geometry/index/detail/rtree/node/node.hpp | 1 + .../detail/rtree/node/node_d_mem_dynamic.hpp | 62 ------------ .../detail/rtree/node/node_d_mem_static.hpp | 7 -- .../index/detail/rtree/node/node_elements.hpp | 95 +++++++++++++++++++ 4 files changed, 96 insertions(+), 69 deletions(-) create mode 100644 include/boost/geometry/index/detail/rtree/node/node_elements.hpp diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index d788cdc0d..fa2127b9c 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp index c6b71f5ad..a4c0ac77d 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp @@ -91,68 +91,6 @@ struct visitor type; }; -// element's indexable type - -template -struct element_indexable_type -{ - typedef typename indexable_type::type type; -}; - -template -struct element_indexable_type< - rtree::ptr_pair, - Translator -> -{ - typedef First type; -}; - -// element's indexable getter - -template -typename result_type::type -element_indexable(Element const& el, Translator const& tr) -{ - return tr(el); -} - -template -First const& -element_indexable(rtree::ptr_pair const& el, Translator const& /*tr*/) -{ - return el.first; -} - -// nodes elements - -template -struct elements_type -{ - typedef typename Node::elements_type type; -}; - -template -inline typename elements_type::type & -elements(Node & n) -{ - return n.elements; -} - -template -inline typename elements_type::type const& -elements(Node const& n) -{ - return n.elements; -} - -// elements derived type -template -struct container_from_elements_type -{ - typedef boost::container::vector type; -}; - // allocators template diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp index 57447f463..a729db973 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp @@ -77,13 +77,6 @@ struct visitor type; }; -// elements derived type -template -struct container_from_elements_type, NewValue> -{ - typedef detail::varray type; -}; - // allocators template diff --git a/include/boost/geometry/index/detail/rtree/node/node_elements.hpp b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp new file mode 100644 index 000000000..e3bfb701f --- /dev/null +++ b/include/boost/geometry/index/detail/rtree/node/node_elements.hpp @@ -0,0 +1,95 @@ +// Boost.Geometry Index +// +// R-tree node elements access +// +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// +// 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) + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP + +#include +#include +#include + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +// element's indexable type + +template +struct element_indexable_type +{ + typedef typename indexable_type::type type; +}; + +template +struct element_indexable_type< + rtree::ptr_pair, + Translator +> +{ + typedef First type; +}; + +// element's indexable getter + +template +typename result_type::type +element_indexable(Element const& el, Translator const& tr) +{ + return tr(el); +} + +template +First const& +element_indexable(rtree::ptr_pair const& el, Translator const& /*tr*/) +{ + return el.first; +} + +// nodes elements + +template +struct elements_type +{ + typedef typename Node::elements_type type; +}; + +template +inline typename elements_type::type & +elements(Node & n) +{ + return n.elements; +} + +template +inline typename elements_type::type const& +elements(Node const& n) +{ + return n.elements; +} + +// elements derived type + +template +struct container_from_elements_type +{ + typedef boost::container::vector type; +}; + +template +struct container_from_elements_type, NewValue> +{ + typedef detail::varray type; +}; + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_ELEMENTS_HPP From 22bd0ea747d7aa2c2f1353cb33f0bbdf4d974496 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 5 Oct 2014 14:40:43 +0200 Subject: [PATCH 22/44] [test][index] Change throwing nodes from polymorphic to variant-based. --- .../geometry/index/detail/rtree/node/node.hpp | 2 +- index/test/rtree/exceptions/test_throwing.hpp | 18 +- .../rtree/exceptions/test_throwing_node.hpp | 173 +++++++++--------- 3 files changed, 102 insertions(+), 91 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index fa2127b9c..741c29195 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -2,7 +2,7 @@ // // R-tree nodes // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at diff --git a/index/test/rtree/exceptions/test_throwing.hpp b/index/test/rtree/exceptions/test_throwing.hpp index dc621c0b3..3e080fea1 100644 --- a/index/test/rtree/exceptions/test_throwing.hpp +++ b/index/test/rtree/exceptions/test_throwing.hpp @@ -2,7 +2,7 @@ // // Throwing objects implementation // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -135,4 +135,20 @@ public: } }; +// elements derived type trait + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +template +struct container_from_elements_type, NewValue> +{ + typedef throwing_varray type; +}; + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + #endif // BOOST_GEOMETRY_INDEX_TEST_THROWING_HPP diff --git a/index/test/rtree/exceptions/test_throwing_node.hpp b/index/test/rtree/exceptions/test_throwing_node.hpp index cbbb3b76d..ee6534ed5 100644 --- a/index/test/rtree/exceptions/test_throwing_node.hpp +++ b/index/test/rtree/exceptions/test_throwing_node.hpp @@ -1,9 +1,9 @@ // Boost.Geometry Index // -// R-tree nodes based on runtime-polymorphism, storing static-size containers +// R-tree nodes storing static-size containers // test version throwing exceptions on creation // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -41,7 +41,7 @@ namespace detail { namespace rtree { // options implementation (from options.hpp) -struct node_throwing_d_mem_static_tag {}; +struct node_throwing_static_tag {}; template struct options_type< linear_throwing > @@ -49,7 +49,7 @@ struct options_type< linear_throwing > typedef options< linear_throwing, insert_default_tag, choose_by_content_diff_tag, split_default_tag, linear_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -59,7 +59,7 @@ struct options_type< quadratic_throwing > typedef options< quadratic_throwing, insert_default_tag, choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -69,7 +69,7 @@ struct options_type< rstar_throwing, insert_reinsert_tag, choose_by_overlap_diff_tag, split_default_tag, rstar_tag, - node_throwing_d_mem_static_tag + node_throwing_static_tag > type; }; @@ -80,98 +80,105 @@ struct options_type< rstar_throwing -struct dynamic_internal_node - : public dynamic_node +struct static_internal_node { typedef throwing_varray< rtree::ptr_pair, Parameters::max_elements + 1 > elements_type; - template - inline dynamic_internal_node(Dummy const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } - inline ~dynamic_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } + template + inline static_internal_node(Alloc const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } + inline ~static_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + // required because variants are initialized using node object + // temporary must be taken into account + inline static_internal_node(static_internal_node const& n) + : elements(n.elements) + { + throwing_nodes_stats::get_internal_nodes_counter_ref()++; + } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + inline static_internal_node(static_internal_node && n) + : elements(boost::move(n.elements)) + { + throwing_nodes_stats::get_internal_nodes_counter_ref()++; + } +#endif elements_type elements; private: - dynamic_internal_node(dynamic_internal_node const&); - dynamic_internal_node & operator=(dynamic_internal_node const&); + static_internal_node & operator=(static_internal_node const& n); }; template -struct dynamic_leaf - : public dynamic_node +struct static_leaf { typedef throwing_varray elements_type; - template - inline dynamic_leaf(Dummy const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } - inline ~dynamic_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } + template + inline static_leaf(Alloc const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } + inline ~static_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + // required because variants are initialized using node object + // temporary must be taken into account + inline static_leaf(static_leaf const& n) + : elements(n.elements) + { + throwing_nodes_stats::get_leafs_counter_ref()++; + } +#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES + inline static_leaf(static_leaf && n) + : elements(boost::move(n.elements)) + { + throwing_nodes_stats::get_leafs_counter_ref()++; + } +#endif elements_type elements; private: - dynamic_leaf(dynamic_leaf const&); - dynamic_leaf & operator=(dynamic_leaf const&); -}; - -// elements derived type -template -struct container_from_elements_type, NewValue> -{ - typedef throwing_varray type; + static_leaf & operator=(static_leaf const& n); }; // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef boost::variant< + static_leaf, + static_internal_node + > type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef static_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef static_leaf type; }; +// visitor traits + template -struct visitor +struct visitor { - typedef dynamic_visitor type; + typedef static_visitor<> type; }; // allocators template -class allocators +struct allocators : public Allocator::template rebind< - typename internal_node< - Value, Parameters, Box, - allocators, - node_throwing_d_mem_static_tag - >::type - >::other - , Allocator::template rebind< - typename leaf< - Value, Parameters, Box, - allocators, - node_throwing_d_mem_static_tag - >::type + typename node, node_throwing_static_tag>::type >::other { typedef typename Allocator::template rebind< @@ -190,69 +197,57 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type - >::other::pointer internal_node_pointer; +// typedef typename Allocator::template rebind< +// typename internal_node::type +// >::other::pointer internal_node_pointer; typedef typename Allocator::template rebind< - typename internal_node::type - >::other internal_node_allocator_type; - - typedef typename Allocator::template rebind< - typename leaf::type - >::other leaf_allocator_type; + typename node::type + >::other node_allocator_type; inline allocators() - : internal_node_allocator_type() - , leaf_allocator_type() + : node_allocator_type() {} template inline explicit allocators(Alloc const& alloc) - : internal_node_allocator_type(alloc) - , leaf_allocator_type(alloc) + : node_allocator_type(alloc) {} inline allocators(BOOST_FWD_REF(allocators) a) - : internal_node_allocator_type(boost::move(a.internal_node_allocator())) - , leaf_allocator_type(boost::move(a.leaf_allocator())) + : node_allocator_type(boost::move(a.node_allocator())) {} inline allocators & operator=(BOOST_FWD_REF(allocators) a) { - internal_node_allocator() = ::boost::move(a.internal_node_allocator()); - leaf_allocator() = ::boost::move(a.leaf_allocator()); + node_allocator() = boost::move(a.node_allocator()); return *this; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES inline allocators & operator=(allocators const& a) { - internal_node_allocator() = a.internal_node_allocator(); - leaf_allocator() = a.leaf_allocator(); + node_allocator() = a.node_allocator(); return *this; } #endif void swap(allocators & a) { - boost::swap(internal_node_allocator(), a.internal_node_allocator()); - boost::swap(leaf_allocator(), a.leaf_allocator()); + boost::swap(node_allocator(), a.node_allocator()); } - bool operator==(allocators const& a) const { return leaf_allocator() == a.leaf_allocator(); } + bool operator==(allocators const& a) const { return node_allocator() == a.node_allocator(); } template - bool operator==(Alloc const& a) const { return leaf_allocator() == leaf_allocator_type(a); } + bool operator==(Alloc const& a) const { return node_allocator() == node_allocator_type(a); } - Allocator allocator() const { return Allocator(leaf_allocator()); } + Allocator allocator() const { return Allocator(node_allocator()); } - internal_node_allocator_type & internal_node_allocator() { return *this; } - internal_node_allocator_type const& internal_node_allocator() const { return *this; } - leaf_allocator_type & leaf_allocator() { return *this; } - leaf_allocator_type const& leaf_allocator() const { return *this; } + node_allocator_type & node_allocator() { return *this; } + node_allocator_type const& node_allocator() const { return *this; } }; struct node_bad_alloc : public std::exception @@ -283,7 +278,7 @@ struct throwing_node_settings template struct create_node< Allocators, - dynamic_internal_node + static_internal_node > { static inline typename Allocators::node_pointer @@ -292,17 +287,17 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_dynamic_node< + return create_static_node< typename Allocators::node_pointer, - dynamic_internal_node - >::apply(allocators.internal_node_allocator()); + static_internal_node + >::apply(allocators.node_allocator()); } }; template struct create_node< Allocators, - dynamic_leaf + static_leaf > { static inline typename Allocators::node_pointer @@ -311,10 +306,10 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_dynamic_node< + return create_static_node< typename Allocators::node_pointer, - dynamic_leaf - >::apply(allocators.leaf_allocator()); + static_leaf + >::apply(allocators.node_allocator()); } }; From 9d7ed2962e7bec9e4a961da0e65b9f0690ebed0e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 5 Oct 2014 15:36:50 +0200 Subject: [PATCH 23/44] [index] Remove polymorphic nodes. Add the implementation of weak nodes, not included/used yet. The rationale to remove polymorphic nodes: 1. such nodes can't work properly if stored in shared memory due to the way how addresses are calculated (using offsets). 2. the rtree using Variant-based nodes has similar performance and takes less memory. 3. the rtree using newly added weak_nodes (not supported/enabled yet) will be even faster and smaller. This is the first step to entirely drop the support for polymorphic nodes. After this it should be not needed to explicitly specify the Nodes types in visitors, therefore it should be possible to dispatch the nodes types statically more conveniently, simplify templates by removal of unneeded parameters, write simpler and more maintainable code, etc. --- .../detail/rtree/node/dynamic_visitor.hpp | 69 +++++------- .../geometry/index/detail/rtree/node/node.hpp | 6 +- ...ode_d_mem_dynamic.hpp => weak_dynamic.hpp} | 102 +++++++++--------- ...{node_d_mem_static.hpp => weak_static.hpp} | 64 +++++------ .../index/detail/rtree/node/weak_visitor.hpp | 67 ++++++++++++ .../geometry/index/detail/rtree/options.hpp | 6 +- 6 files changed, 174 insertions(+), 140 deletions(-) rename include/boost/geometry/index/detail/rtree/node/{node_d_mem_dynamic.hpp => weak_dynamic.hpp} (65%) rename include/boost/geometry/index/detail/rtree/node/{node_d_mem_static.hpp => weak_static.hpp} (61%) create mode 100644 include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp diff --git a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp index 1823b83c1..43dff56bc 100644 --- a/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/dynamic_visitor.hpp @@ -1,84 +1,63 @@ // Boost.Geometry Index // -// R-tree nodes dynamic visitor and nodes base type +// R-tree nodes weak visitor and nodes base type // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -// visitor forward declaration +// empty visitor template -struct dynamic_visitor; +struct weak_visitor {}; // node template -struct dynamic_node -{ - virtual ~dynamic_node() {} - virtual void apply_visitor(dynamic_visitor &) = 0; - virtual void apply_visitor(dynamic_visitor &) const = 0; -}; +struct weak_node {}; // nodes variants forward declarations template -struct dynamic_internal_node; +struct weak_internal_node; template -struct dynamic_leaf; - -// visitor - -template -struct dynamic_visitor -{ - typedef dynamic_internal_node internal_node; - typedef dynamic_leaf leaf; - - virtual ~dynamic_visitor() {} - - virtual void operator()(internal_node const&) = 0; - virtual void operator()(leaf const&) = 0; -}; - -template -struct dynamic_visitor -{ - typedef dynamic_internal_node internal_node; - typedef dynamic_leaf leaf; - - virtual ~dynamic_visitor() {} - - virtual void operator()(internal_node &) = 0; - virtual void operator()(leaf &) = 0; -}; +struct weak_leaf; // nodes conversion template -inline Derived & get(dynamic_node & n) +inline Derived & get(weak_node & n) { - BOOST_GEOMETRY_INDEX_ASSERT(dynamic_cast(&n), "can't cast to a Derived type"); return static_cast(n); } // apply visitor -template -inline void apply_visitor(Visitor & v, Visitable & n) +template +inline void apply_visitor(Visitor & v, + raw_node & n, + bool is_internal_node) { BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr"); - n.apply_visitor(v); + if ( is_internal_node ) + { + typedef raw_internal_node internal_node; + v(get(n)); + } + else + { + typedef raw_leaf leaf; + v(get(n)); + } } }} // namespace detail::rtree diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index 741c29195..bc6a37baf 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -19,9 +19,9 @@ #include #include -#include -#include -#include +//#include +//#include +//#include #include #include diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp similarity index 65% rename from include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp rename to include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp index a4c0ac77d..b828b35f4 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_dynamic.hpp @@ -1,47 +1,44 @@ // Boost.Geometry Index // -// R-tree nodes based on run-time polymorphism, storing std::vectors +// R-tree nodes based on static conversion, storing dynamic-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { -template -struct dynamic_internal_node - : public dynamic_node +template +struct weak_internal_node + : public weak_node { typedef boost::container::vector < rtree::ptr_pair, - typename Allocators::leaf_allocator_type::template rebind + typename Allocators::internal_node_allocator_type::template rebind < rtree::ptr_pair >::other > elements_type; template - inline dynamic_internal_node(Al const& al) + inline weak_internal_node(Al const& al) : elements(al) {} - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } - elements_type elements; }; -template -struct dynamic_leaf - : public dynamic_node +template +struct weak_leaf + : public weak_node { typedef boost::container::vector < @@ -53,53 +50,58 @@ struct dynamic_leaf > elements_type; template - inline dynamic_leaf(Al const& al) + inline weak_leaf(Al const& al) : elements(al) {} - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } - elements_type elements; }; // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef weak_node type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef weak_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef weak_leaf type; }; // visitor traits template -struct visitor +struct visitor { - typedef dynamic_visitor type; + typedef weak_visitor type; }; // allocators template -class allocators +class allocators : public Allocator::template rebind< - typename internal_node, node_d_mem_dynamic_tag>::type + typename internal_node< + Value, Parameters, Box, + allocators, + node_weak_dynamic_tag + >::type >::other , public Allocator::template rebind< - typename leaf, node_d_mem_dynamic_tag>::type + typename leaf< + Value, Parameters, Box, + allocators, + node_weak_dynamic_tag + >::type >::other { typedef typename Allocator::template rebind< @@ -118,19 +120,15 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type + typename internal_node::type >::other internal_node_allocator_type; typedef typename Allocator::template rebind< - typename leaf::type + typename leaf::type >::other leaf_allocator_type; inline allocators() @@ -186,7 +184,7 @@ public: // create_node_impl template -struct create_dynamic_node +struct create_weak_node { template static inline BaseNodePtr apply(AllocNode & alloc_node) @@ -211,7 +209,7 @@ struct create_dynamic_node // destroy_node_impl template -struct destroy_dynamic_node +struct destroy_weak_node { template static inline void apply(AllocNode & alloc_node, BaseNodePtr n) @@ -230,15 +228,15 @@ struct destroy_dynamic_node template struct create_node< Allocators, - dynamic_internal_node + weak_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_dynamic_node< + return create_weak_node< typename Allocators::node_pointer, - dynamic_internal_node + weak_internal_node >::apply(allocators.internal_node_allocator()); } }; @@ -246,15 +244,15 @@ struct create_node< template struct create_node< Allocators, - dynamic_leaf + weak_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_dynamic_node< + return create_weak_node< typename Allocators::node_pointer, - dynamic_leaf + weak_leaf >::apply(allocators.leaf_allocator()); } }; @@ -264,13 +262,13 @@ struct create_node< template struct destroy_node< Allocators, - dynamic_internal_node + weak_internal_node > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_dynamic_node< - dynamic_internal_node + destroy_weak_node< + weak_internal_node >::apply(allocators.internal_node_allocator(), n); } }; @@ -278,13 +276,13 @@ struct destroy_node< template struct destroy_node< Allocators, - dynamic_leaf + weak_leaf > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_dynamic_node< - dynamic_leaf + destroy_weak_node< + weak_leaf >::apply(allocators.leaf_allocator(), n); } }; @@ -293,4 +291,4 @@ struct destroy_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_DYNAMIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp similarity index 61% rename from include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp rename to include/boost/geometry/index/detail/rtree/node/weak_static.hpp index a729db973..632e35678 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_d_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/weak_static.hpp @@ -1,23 +1,23 @@ // Boost.Geometry Index // -// R-tree nodes based on runtime-polymorphism, storing static-size containers +// R-tree nodes based on static conversion, storing static-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP namespace boost { namespace geometry { namespace index { namespace detail { namespace rtree { template -struct dynamic_internal_node - : public dynamic_node +struct weak_internal_node + : public weak_node { typedef detail::varray< rtree::ptr_pair, @@ -25,17 +25,14 @@ struct dynamic_internal_node elements_type; template - inline dynamic_internal_node(Alloc const&) {} - - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + inline weak_internal_node(Alloc const&) {} elements_type elements; }; template -struct dynamic_leaf - : public dynamic_node +struct weak_leaf + : public weak_node { typedef detail::varray< Value, @@ -43,10 +40,7 @@ struct dynamic_leaf > elements_type; template - inline dynamic_leaf(Alloc const&) {} - - void apply_visitor(dynamic_visitor & v) { v(*this); } - void apply_visitor(dynamic_visitor & v) const { v(*this); } + inline weak_leaf(Alloc const&) {} elements_type elements; }; @@ -54,45 +48,45 @@ struct dynamic_leaf // nodes traits template -struct node +struct node { - typedef dynamic_node type; + typedef weak_node type; }; template -struct internal_node +struct internal_node { - typedef dynamic_internal_node type; + typedef weak_internal_node type; }; template -struct leaf +struct leaf { - typedef dynamic_leaf type; + typedef weak_leaf type; }; template -struct visitor +struct visitor { - typedef dynamic_visitor type; + typedef weak_visitor type; }; // allocators template -class allocators +class allocators : public Allocator::template rebind< typename internal_node< Value, Parameters, Box, - allocators, - node_d_mem_static_tag + allocators, + node_weak_static_tag >::type >::other , public Allocator::template rebind< typename leaf< Value, Parameters, Box, - allocators, - node_d_mem_static_tag + allocators, + node_weak_static_tag >::type >::other { @@ -112,19 +106,15 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename internal_node::type + typename internal_node::type >::other internal_node_allocator_type; typedef typename Allocator::template rebind< - typename leaf::type + typename leaf::type >::other leaf_allocator_type; inline allocators() @@ -181,4 +171,4 @@ public: }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_STATIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp new file mode 100644 index 000000000..08d84778e --- /dev/null +++ b/include/boost/geometry/index/detail/rtree/node/weak_visitor.hpp @@ -0,0 +1,67 @@ +// Boost.Geometry Index +// +// R-tree nodes weak visitor and nodes base type +// +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// +// 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) + +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_WEAK_VISITOR_HPP + +namespace boost { namespace geometry { namespace index { + +namespace detail { namespace rtree { + +// empty visitor +template +struct weak_visitor {}; + +// node + +template +struct weak_node {}; + +// nodes variants forward declarations + +template +struct weak_internal_node; + +template +struct weak_leaf; + +// nodes conversion + +template +inline Derived & get(weak_node & n) +{ + return static_cast(n); +} + +// apply visitor + +template +inline void apply_visitor(Visitor & v, + weak_node & n, + bool is_internal_node) +{ + BOOST_GEOMETRY_INDEX_ASSERT(&n, "null ptr"); + if ( is_internal_node ) + { + typedef weak_internal_node internal_node; + v(get(n)); + } + else + { + typedef weak_leaf leaf; + v(get(n)); + } +} + +}} // namespace detail::rtree + +}}} // namespace boost::geometry::index + +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_DYNAMIC_VISITOR_HPP diff --git a/include/boost/geometry/index/detail/rtree/options.hpp b/include/boost/geometry/index/detail/rtree/options.hpp index b7947402c..5070fed70 100644 --- a/include/boost/geometry/index/detail/rtree/options.hpp +++ b/include/boost/geometry/index/detail/rtree/options.hpp @@ -2,7 +2,7 @@ // // R-tree options, algorithms, parameters // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -35,8 +35,8 @@ struct quadratic_tag {}; struct rstar_tag {}; // NodeTag -struct node_d_mem_dynamic_tag {}; -struct node_d_mem_static_tag {}; +struct node_weak_dynamic_tag {}; +struct node_weak_static_tag {}; struct node_s_mem_dynamic_tag {}; struct node_s_mem_static_tag {}; From 8e4bc68ed51750d238fcbf0197e29deaf50bbebf Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 5 Oct 2014 16:19:18 +0200 Subject: [PATCH 24/44] [index] Rename "static" nodes to "variant" nodes (it is more clear). --- .../geometry/index/detail/rtree/node/node.hpp | 6 +- ..._s_mem_dynamic.hpp => variant_dynamic.hpp} | 77 +++++++++---------- ...de_s_mem_static.hpp => variant_static.hpp} | 60 +++++++-------- ...static_visitor.hpp => variant_visitor.hpp} | 24 +++--- .../geometry/index/detail/rtree/options.hpp | 22 +++--- 5 files changed, 94 insertions(+), 95 deletions(-) rename include/boost/geometry/index/detail/rtree/node/{node_s_mem_dynamic.hpp => variant_dynamic.hpp} (71%) rename include/boost/geometry/index/detail/rtree/node/{node_s_mem_static.hpp => variant_static.hpp} (65%) rename include/boost/geometry/index/detail/rtree/node/{static_visitor.hpp => variant_visitor.hpp} (64%) diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index bc6a37baf..2b53efd53 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -23,9 +23,9 @@ //#include //#include -#include -#include -#include +#include +#include +#include #include diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp similarity index 71% rename from include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp index ce55721bc..f13dd1036 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_dynamic.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_dynamic.hpp @@ -1,15 +1,15 @@ // Boost.Geometry Index // -// R-tree nodes based on Boost.Variant, storing std::vectors +// R-tree nodes based on Boost.Variant, storing dynamic-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP namespace boost { namespace geometry { namespace index { @@ -18,7 +18,7 @@ namespace detail { namespace rtree { // nodes default types template -struct static_internal_node +struct variant_internal_node { typedef boost::container::vector < @@ -30,7 +30,7 @@ struct static_internal_node > elements_type; template - inline static_internal_node(Al const& al) + inline variant_internal_node(Al const& al) : elements(al) {} @@ -38,7 +38,7 @@ struct static_internal_node }; template -struct static_leaf +struct variant_leaf { typedef boost::container::vector < @@ -50,7 +50,7 @@ struct static_leaf > elements_type; template - inline static_leaf(Al const& al) + inline variant_leaf(Al const& al) : elements(al) {} @@ -60,30 +60,30 @@ struct static_leaf // nodes traits template -struct node +struct node { typedef boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > type; }; template -struct internal_node +struct internal_node { - typedef static_internal_node type; + typedef variant_internal_node type; }; template -struct leaf +struct leaf { - typedef static_leaf type; + typedef variant_leaf type; }; // visitor traits template -struct visitor +struct visitor { typedef static_visitor<> type; }; @@ -91,9 +91,12 @@ struct visitor -class allocators +class allocators : public Allocator::template rebind< - typename node, node_s_mem_dynamic_tag>::type + typename node< + Value, Parameters, Box, + allocators, + node_variant_dynamic_tag>::type >::other { typedef typename Allocator::template rebind< @@ -112,15 +115,11 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other node_allocator_type; inline allocators() @@ -168,7 +167,7 @@ public: // create_node_variant template -struct create_static_node +struct create_variant_node { template static inline VariantPtr apply(AllocNode & alloc_node) @@ -193,7 +192,7 @@ struct create_static_node // destroy_node_variant template -struct destroy_static_node +struct destroy_variant_node { template static inline void apply(AllocNode & alloc_node, VariantPtr n) @@ -210,15 +209,15 @@ struct destroy_static_node template struct create_node< Allocators, - static_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_internal_node + variant_internal_node >::apply(allocators.node_allocator()); } }; @@ -226,15 +225,15 @@ struct create_node< template struct create_node< Allocators, - static_leaf + variant_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_leaf + variant_leaf >::apply(allocators.node_allocator()); } }; @@ -244,13 +243,13 @@ struct create_node< template struct destroy_node< Allocators, - static_internal_node + variant_internal_node > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_static_node< - static_internal_node + destroy_variant_node< + variant_internal_node >::apply(allocators.node_allocator(), n); } }; @@ -258,13 +257,13 @@ struct destroy_node< template struct destroy_node< Allocators, - static_leaf + variant_leaf > { static inline void apply(Allocators & allocators, typename Allocators::node_pointer n) { - destroy_static_node< - static_leaf + destroy_variant_node< + variant_leaf >::apply(allocators.node_allocator(), n); } }; @@ -273,4 +272,4 @@ struct destroy_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_VARIANT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_DYNAMIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp similarity index 65% rename from include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_static.hpp index 4abb95549..f6e9761b2 100644 --- a/include/boost/geometry/index/detail/rtree/node/node_s_mem_static.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_static.hpp @@ -2,14 +2,14 @@ // // R-tree nodes based on Boost.Variant, storing static-size containers // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP namespace boost { namespace geometry { namespace index { @@ -18,7 +18,7 @@ namespace detail { namespace rtree { // nodes default types template -struct static_internal_node +struct variant_internal_node { typedef detail::varray< rtree::ptr_pair, @@ -26,13 +26,13 @@ struct static_internal_node elements_type; template - inline static_internal_node(Alloc const&) {} + inline variant_internal_node(Alloc const&) {} elements_type elements; }; template -struct static_leaf +struct variant_leaf { typedef detail::varray< Value, @@ -40,7 +40,7 @@ struct static_leaf > elements_type; template - inline static_leaf(Alloc const&) {} + inline variant_leaf(Alloc const&) {} elements_type elements; }; @@ -48,30 +48,30 @@ struct static_leaf // nodes traits template -struct node +struct node { typedef boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > type; }; template -struct internal_node +struct internal_node { - typedef static_internal_node type; + typedef variant_internal_node type; }; template -struct leaf +struct leaf { - typedef static_leaf type; + typedef variant_leaf type; }; // visitor traits template -struct visitor +struct visitor { typedef static_visitor<> type; }; @@ -79,9 +79,13 @@ struct visitor -struct allocators +struct allocators : public Allocator::template rebind< - typename node, node_s_mem_static_tag>::type + typename node< + Value, Parameters, Box, + allocators, + node_variant_static_tag + >::type >::other { typedef typename Allocator::template rebind< @@ -100,15 +104,11 @@ public: typedef typename value_allocator_type::const_pointer const_pointer; typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other::pointer node_pointer; -// typedef typename Allocator::template rebind< -// typename internal_node::type -// >::other::pointer internal_node_pointer; - typedef typename Allocator::template rebind< - typename node::type + typename node::type >::other node_allocator_type; inline allocators() @@ -158,15 +158,15 @@ public: template struct create_node< Allocators, - static_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_internal_node + variant_internal_node >::apply(allocators.node_allocator()); } }; @@ -174,15 +174,15 @@ struct create_node< template struct create_node< Allocators, - static_leaf + variant_leaf > { static inline typename Allocators::node_pointer apply(Allocators & allocators) { - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_leaf + variant_leaf >::apply(allocators.node_allocator()); } }; @@ -191,4 +191,4 @@ struct create_node< }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_NODE_DEFAULT_STATIC_VARIANT_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_STATIC_HPP diff --git a/include/boost/geometry/index/detail/rtree/node/static_visitor.hpp b/include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp similarity index 64% rename from include/boost/geometry/index/detail/rtree/node/static_visitor.hpp rename to include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp index 9b74b1e41..ffd67039d 100644 --- a/include/boost/geometry/index/detail/rtree/node/static_visitor.hpp +++ b/include/boost/geometry/index/detail/rtree/node/variant_visitor.hpp @@ -2,14 +2,14 @@ // // R-tree nodes static visitor related code // -// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. // // 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) -#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP -#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP +#ifndef BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP +#define BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP #include @@ -20,18 +20,18 @@ namespace detail { namespace rtree { // nodes variants forward declarations template -struct static_internal_node; +struct variant_internal_node; template -struct static_leaf; +struct variant_leaf; // nodes conversion template inline V & get( boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > & v) { return boost::get(v); @@ -42,8 +42,8 @@ inline V & get( template inline void apply_visitor(Visitor & v, boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > & n) { boost::apply_visitor(v, n); @@ -52,8 +52,8 @@ inline void apply_visitor(Visitor & v, template inline void apply_visitor(Visitor & v, boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > const& n) { boost::apply_visitor(v, n); @@ -63,4 +63,4 @@ inline void apply_visitor(Visitor & v, }}} // namespace boost::geometry::index -#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_STATIC_VISITOR_HPP +#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_NODE_VARIANT_VISITOR_HPP diff --git a/include/boost/geometry/index/detail/rtree/options.hpp b/include/boost/geometry/index/detail/rtree/options.hpp index 5070fed70..ff772834d 100644 --- a/include/boost/geometry/index/detail/rtree/options.hpp +++ b/include/boost/geometry/index/detail/rtree/options.hpp @@ -35,10 +35,10 @@ struct quadratic_tag {}; struct rstar_tag {}; // NodeTag -struct node_weak_dynamic_tag {}; -struct node_weak_static_tag {}; -struct node_s_mem_dynamic_tag {}; -struct node_s_mem_static_tag {}; +struct node_variant_dynamic_tag {}; +struct node_variant_static_tag {}; +//struct node_weak_dynamic_tag {}; +//struct node_weak_static_tag {}; template struct options @@ -66,7 +66,7 @@ struct options_type< index::linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_s_mem_static_tag + node_variant_static_tag > type; }; @@ -79,7 +79,7 @@ struct options_type< index::quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_s_mem_static_tag + node_variant_static_tag > type; }; @@ -92,7 +92,7 @@ struct options_type< index::rstar type; }; @@ -105,7 +105,7 @@ struct options_type< index::rstar type; //}; @@ -118,7 +118,7 @@ struct options_type< index::dynamic_linear > choose_by_content_diff_tag, split_default_tag, linear_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; @@ -131,7 +131,7 @@ struct options_type< index::dynamic_quadratic > choose_by_content_diff_tag, split_default_tag, quadratic_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; @@ -144,7 +144,7 @@ struct options_type< index::dynamic_rstar > choose_by_overlap_diff_tag, split_default_tag, rstar_tag, - node_s_mem_dynamic_tag + node_variant_dynamic_tag > type; }; From c57be3a0369c52bca523b601af934cb50db89b47 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 5 Oct 2014 16:20:09 +0200 Subject: [PATCH 25/44] [test][index] Use new names of variant nodes in the implementation of throwing nodes in exceptions tests. --- .../rtree/exceptions/test_throwing_node.hpp | 46 +++++++++---------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/index/test/rtree/exceptions/test_throwing_node.hpp b/index/test/rtree/exceptions/test_throwing_node.hpp index ee6534ed5..d32c6bcca 100644 --- a/index/test/rtree/exceptions/test_throwing_node.hpp +++ b/index/test/rtree/exceptions/test_throwing_node.hpp @@ -12,8 +12,6 @@ #ifndef BOOST_GEOMETRY_INDEX_TEST_RTREE_THROWING_NODE_HPP #define BOOST_GEOMETRY_INDEX_TEST_RTREE_THROWING_NODE_HPP -#include - #include struct throwing_nodes_stats @@ -80,7 +78,7 @@ struct options_type< rstar_throwing -struct static_internal_node +struct variant_internal_node { typedef throwing_varray< rtree::ptr_pair, @@ -88,18 +86,18 @@ struct static_internal_node elements_type; template - inline static_internal_node(Alloc const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } - inline ~static_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } + inline variant_internal_node(Alloc const&) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } + inline ~variant_internal_node() { throwing_nodes_stats::get_internal_nodes_counter_ref()--; } // required because variants are initialized using node object // temporary must be taken into account - inline static_internal_node(static_internal_node const& n) + inline variant_internal_node(variant_internal_node const& n) : elements(n.elements) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - inline static_internal_node(static_internal_node && n) + inline variant_internal_node(variant_internal_node && n) : elements(boost::move(n.elements)) { throwing_nodes_stats::get_internal_nodes_counter_ref()++; @@ -109,27 +107,27 @@ struct static_internal_node -struct static_leaf +struct variant_leaf { typedef throwing_varray elements_type; template - inline static_leaf(Alloc const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } - inline ~static_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } + inline variant_leaf(Alloc const&) { throwing_nodes_stats::get_leafs_counter_ref()++; } + inline ~variant_leaf() { throwing_nodes_stats::get_leafs_counter_ref()--; } // required because variants are initialized using node object // temporary must be taken into account - inline static_leaf(static_leaf const& n) + inline variant_leaf(variant_leaf const& n) : elements(n.elements) { throwing_nodes_stats::get_leafs_counter_ref()++; } #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES - inline static_leaf(static_leaf && n) + inline variant_leaf(variant_leaf && n) : elements(boost::move(n.elements)) { throwing_nodes_stats::get_leafs_counter_ref()++; @@ -139,7 +137,7 @@ struct static_leaf elements_type elements; private: - static_leaf & operator=(static_leaf const& n); + variant_leaf & operator=(variant_leaf const& n); }; // nodes traits @@ -148,21 +146,21 @@ template { typedef boost::variant< - static_leaf, - static_internal_node + variant_leaf, + variant_internal_node > type; }; template struct internal_node { - typedef static_internal_node type; + typedef variant_internal_node type; }; template struct leaf { - typedef static_leaf type; + typedef variant_leaf type; }; // visitor traits @@ -278,7 +276,7 @@ struct throwing_node_settings template struct create_node< Allocators, - static_internal_node + variant_internal_node > { static inline typename Allocators::node_pointer @@ -287,9 +285,9 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_internal_node + variant_internal_node >::apply(allocators.node_allocator()); } }; @@ -297,7 +295,7 @@ struct create_node< template struct create_node< Allocators, - static_leaf + variant_leaf > { static inline typename Allocators::node_pointer @@ -306,9 +304,9 @@ struct create_node< // throw if counter meets max count throwing_node_settings::throw_if_required(); - return create_static_node< + return create_variant_node< typename Allocators::node_pointer, - static_leaf + variant_leaf >::apply(allocators.node_allocator()); } }; From 38a5bffb0563957a31e6eb886029c005c0782e2a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 6 Oct 2014 12:59:30 +0200 Subject: [PATCH 26/44] [doc] Update release notes. --- doc/release_notes.qbk | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 40f4939be..52eda9e2a 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -21,8 +21,12 @@ [*Improvements] +* The rtree insert(), remove() and count() functions support parameters convertible to value_type + [*Solved tickets] +* [@https://svn.boost.org/trac/boost/ticket/9354 9354] Bug in winding strategy affecting within() and covered_by() for non-cartesian coordinate systems +* [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns [*Bugfixes] @@ -61,6 +65,7 @@ * [@https://svn.boost.org/trac/boost/ticket/9628 9628] Wrong result of within() due to the winding strategy not working correctly for nearly-horizontal segments * [@https://svn.boost.org/trac/boost/ticket/9828 9828] boost::geometry::union_(...) creates redundant closing point * [@https://svn.boost.org/trac/boost/ticket/9871 9871] Remove spike in polygon with only a spike +* [@https://svn.boost.org/trac/boost/ticket/9941 9941] Add support for touches(box, box) * [@https://svn.boost.org/trac/boost/ticket/9947 9947] Missing info about WKT in documentation * [@https://svn.boost.org/trac/boost/ticket/9759 9759] Invalid results of R-tree knn queries for non-cartesian coordinate systems * [@https://svn.boost.org/trac/boost/ticket/10019 10019] Difference of Linestring and Box returns their intersection From 7b1e4bd601234897c89dc0dfb1b6ed7a20744f21 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Oct 2014 14:52:08 +0200 Subject: [PATCH 27/44] [doc][index] Docs upgrade (mostly related to Range adaptors). Add a tip about usage of Boost.Range adaptors with the rtree. Add an example of usage of Boost.Range adaptors. Replace invalid main(void) with main() in examples. Fix MSVC type conversion warnings in examples. --- doc/index/imports.qbk | 1 + doc/index/rtree/creation.qbk | 14 +++- doc/index/rtree/examples.qbk | 8 +- doc/index/src/examples/rtree/Jamfile.v2 | 1 + .../src/examples/rtree/iterative_query.cpp | 2 +- ..._query.qbk => iterative_query_results.qbk} | 0 .../examples/rtree/polygons_shared_ptr.cpp | 2 +- .../src/examples/rtree/polygons_vector.cpp | 2 +- doc/index/src/examples/rtree/quick_start.cpp | 4 +- .../src/examples/rtree/range_adaptors.cpp | 79 +++++++++++++++++++ .../examples/rtree/range_adaptors_results.qbk | 11 +++ doc/index/src/examples/rtree/value_index.cpp | 4 +- .../src/examples/rtree/value_shared_ptr.cpp | 4 +- doc/index/src/examples/rtree/variants_map.cpp | 2 +- 14 files changed, 119 insertions(+), 15 deletions(-) rename doc/index/src/examples/rtree/{iterative_query.qbk => iterative_query_results.qbk} (100%) create mode 100644 doc/index/src/examples/rtree/range_adaptors.cpp create mode 100644 doc/index/src/examples/rtree/range_adaptors_results.qbk diff --git a/doc/index/imports.qbk b/doc/index/imports.qbk index 4502ee41c..535395091 100644 --- a/doc/index/imports.qbk +++ b/doc/index/imports.qbk @@ -14,6 +14,7 @@ [import src/examples/rtree/variants_map.cpp] [import src/examples/rtree/value_shared_ptr.cpp] [import src/examples/rtree/value_index.cpp] +[import src/examples/rtree/range_adaptors.cpp] [import src/examples/rtree/iterative_query.cpp] [import src/examples/rtree/interprocess.cpp] [import src/examples/rtree/mapped_file.cpp] diff --git a/doc/index/rtree/creation.qbk b/doc/index/rtree/creation.qbk index 6ea609b08..7f5f8290a 100644 --- a/doc/index/rtree/creation.qbk +++ b/doc/index/rtree/creation.qbk @@ -164,7 +164,7 @@ stored in another container. [h4 Additional interface] The __rtree__ allows creation, inserting and removing of Values from a range. The range may be passed as -[first, last) Iterators pair or as a Range. +`[first, last)` Iterators pair or as a Range adapted to one of the Boost.Range Concepts. namespace bgi = boost::geometry::index; typedef std::pair __value__; @@ -184,13 +184,13 @@ The __rtree__ allows creation, inserting and removing of Values from a range. Th // create R-tree with default constructor and insert values with insert(Range) RTree rt3; - rt3.insert(values); + rt3.insert(values_range); // create R-tree with constructor taking Iterators RTree rt4(values.begin(), values.end()); // create R-tree with constructor taking Range - RTree rt5(values); + RTree rt5(values_range); // remove values with remove(Value const&) BOOST_FOREACH(__value__ const& v, values) @@ -200,7 +200,13 @@ The __rtree__ allows creation, inserting and removing of Values from a range. Th rt2.remove(values.begin(), values.end()); // remove values with remove(Range) - rt3.remove(values); + rt3.remove(values_range); + +Furthermore, it's possible to pass a Range adapted by one of the Boost.Range adaptors into the rtree (more complete example can be found in the *Examples* section). + + // create Rtree containing `std::pair` from a container of Boxes on the fly. + RTree rt6(boxes | boost::adaptors::indexed() + | boost::adaptors::transformed(pair_maker())); [h4 Insert iterator] diff --git a/doc/index/rtree/examples.qbk b/doc/index/rtree/examples.qbk index ba82e88f0..37157caa5 100644 --- a/doc/index/rtree/examples.qbk +++ b/doc/index/rtree/examples.qbk @@ -46,10 +46,16 @@ [include ../src/examples/rtree/value_index_results.qbk] [endsect] +[section Range adaptors] +[rtree_range_adaptors] +[h4 Expected results] +[include ../src/examples/rtree/range_adaptors_results.qbk] +[endsect] + [section Iterative query] [rtree_iterative_query] [h4 Expected results] -[include ../src/examples/rtree/iterative_query.qbk] +[include ../src/examples/rtree/iterative_query_results.qbk] [endsect] [section Index stored in shared memory using Boost.Interprocess] diff --git a/doc/index/src/examples/rtree/Jamfile.v2 b/doc/index/src/examples/rtree/Jamfile.v2 index 3e03c6000..e28a6e07b 100644 --- a/doc/index/src/examples/rtree/Jamfile.v2 +++ b/doc/index/src/examples/rtree/Jamfile.v2 @@ -10,6 +10,7 @@ exe iterative_query : iterative_query.cpp ; exe polygons_shared_ptr : polygons_shared_ptr.cpp ; exe polygons_vector : polygons_vector.cpp ; exe quick_start : quick_start.cpp ; +exe range_adaptors : range_adaptors.cpp ; exe value_index : value_index.cpp ; exe value_shared_ptr : value_shared_ptr.cpp ; exe variants_map : variants_map.cpp ; diff --git a/doc/index/src/examples/rtree/iterative_query.cpp b/doc/index/src/examples/rtree/iterative_query.cpp index 32ce87606..1afb53ee5 100644 --- a/doc/index/src/examples/rtree/iterative_query.cpp +++ b/doc/index/src/examples/rtree/iterative_query.cpp @@ -22,7 +22,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef point value; diff --git a/doc/index/src/examples/rtree/iterative_query.qbk b/doc/index/src/examples/rtree/iterative_query_results.qbk similarity index 100% rename from doc/index/src/examples/rtree/iterative_query.qbk rename to doc/index/src/examples/rtree/iterative_query_results.qbk diff --git a/doc/index/src/examples/rtree/polygons_shared_ptr.cpp b/doc/index/src/examples/rtree/polygons_shared_ptr.cpp index 0d34e23fe..a97e78805 100644 --- a/doc/index/src/examples/rtree/polygons_shared_ptr.cpp +++ b/doc/index/src/examples/rtree/polygons_shared_ptr.cpp @@ -26,7 +26,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; diff --git a/doc/index/src/examples/rtree/polygons_vector.cpp b/doc/index/src/examples/rtree/polygons_vector.cpp index 7102862c6..28fc9c183 100644 --- a/doc/index/src/examples/rtree/polygons_vector.cpp +++ b/doc/index/src/examples/rtree/polygons_vector.cpp @@ -25,7 +25,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; diff --git a/doc/index/src/examples/rtree/quick_start.cpp b/doc/index/src/examples/rtree/quick_start.cpp index fd3834449..d95836cf5 100644 --- a/doc/index/src/examples/rtree/quick_start.cpp +++ b/doc/index/src/examples/rtree/quick_start.cpp @@ -29,7 +29,7 @@ namespace bg = boost::geometry; namespace bgi = boost::geometry::index; //] -int main(void) +int main() { //[rtree_quickstart_valuetype typedef bg::model::point point; @@ -47,7 +47,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // create a box - box b(point(i, i), point(i + 0.5f, i + 0.5f)); + box b(point(i + 0.0f, i + 0.0f), point(i + 0.5f, i + 0.5f)); // insert new value rtree.insert(std::make_pair(b, i)); } diff --git a/doc/index/src/examples/rtree/range_adaptors.cpp b/doc/index/src/examples/rtree/range_adaptors.cpp new file mode 100644 index 000000000..f01d978cf --- /dev/null +++ b/doc/index/src/examples/rtree/range_adaptors.cpp @@ -0,0 +1,79 @@ +// Boost.Geometry Index +// +// Quickbook Examples +// +// Copyright (c) 2011-2014 Adam Wulkiewicz, Lodz, Poland. +// +// 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) + +//[rtree_range_adaptors + +#include +#include +#include + +#include + +// Boost.Range +#include +// adaptors +#include +#include + +// a container +#include + +// just for output +#include + +namespace bg = boost::geometry; +namespace bgi = boost::geometry::index; + +// Define a function object converting a value_type of indexed Range into std::pair<>. +// This is a generic implementation but of course it'd be possible to use some +// specific types. One could also take Value as template parameter and access +// first_type and second_type members, etc. +template +struct pair_maker +{ + typedef std::pair result_type; + template + inline result_type operator()(T const& v) const + { + return result_type(v.value(), v.index()); + } +}; + +int main() +{ + typedef bg::model::point point; + typedef bg::model::box box; + + typedef std::vector container; + typedef container::size_type size_type; + + typedef std::pair value; + + // create a container of boxes + container boxes; + for ( size_type i = 0 ; i < 10 ; ++i ) + { + // add a box into the container + box b(point(i + 0.0f, i + 0.0f), point(i + 0.5f, i + 0.5f)); + boxes.push_back(b); + } + + // create the rtree using default constructor + bgi::rtree< value, bgi::quadratic<16> > + rtree(boxes | boost::adaptors::indexed() + | boost::adaptors::transformed(pair_maker())); + + // print the number of values using boxes[0] as indexable + std::cout << rtree.count(boxes[0]) << std::endl; + + return 0; +} + +//] diff --git a/doc/index/src/examples/rtree/range_adaptors_results.qbk b/doc/index/src/examples/rtree/range_adaptors_results.qbk new file mode 100644 index 000000000..a50537ae3 --- /dev/null +++ b/doc/index/src/examples/rtree/range_adaptors_results.qbk @@ -0,0 +1,11 @@ +[/============================================================================ + Boost.Geometry Index + + Copyright (c) 2011-2014 Adam Wulkiewicz. + + 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) +=============================================================================/] + + 1 diff --git a/doc/index/src/examples/rtree/value_index.cpp b/doc/index/src/examples/rtree/value_index.cpp index 6f245403b..f005c4d42 100644 --- a/doc/index/src/examples/rtree/value_index.cpp +++ b/doc/index/src/examples/rtree/value_index.cpp @@ -37,7 +37,7 @@ public: result_type operator()(size_t i) const { return container[i]; } }; -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; @@ -52,7 +52,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // add a box - boxes.push_back(box(point(i, i), point(i+0.5f, i+0.5f))); + boxes.push_back(box(point(i+0.0f, i+0.0f), point(i+0.5f, i+0.5f))); } // display boxes diff --git a/doc/index/src/examples/rtree/value_shared_ptr.cpp b/doc/index/src/examples/rtree/value_shared_ptr.cpp index bf20646fe..33701e09f 100644 --- a/doc/index/src/examples/rtree/value_shared_ptr.cpp +++ b/doc/index/src/examples/rtree/value_shared_ptr.cpp @@ -38,7 +38,7 @@ struct indexable< boost::shared_ptr > }}} // namespace boost::geometry::index -int main(void) +int main() { typedef bg::model::point point; typedef bg::model::box box; @@ -54,7 +54,7 @@ int main(void) for ( unsigned i = 0 ; i < 10 ; ++i ) { // create a box - shp b(new box(point(i, i), point(i+0.5f, i+0.5f))); + shp b(new box(point(i+0.0f, i+0.0f), point(i+0.5f, i+0.5f))); // display new box std::cout << bg::wkt(*b) << std::endl; diff --git a/doc/index/src/examples/rtree/variants_map.cpp b/doc/index/src/examples/rtree/variants_map.cpp index efc043e3d..24ffe899e 100644 --- a/doc/index/src/examples/rtree/variants_map.cpp +++ b/doc/index/src/examples/rtree/variants_map.cpp @@ -65,7 +65,7 @@ struct envelope_visitor : public boost::static_visitor }; -int main(void) +int main() { // geometries container map geometries; From 7de377e170541c72be37a34256416c7556616b28 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Oct 2014 15:01:18 +0200 Subject: [PATCH 28/44] [doc] Update release notes. --- doc/release_notes.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 52eda9e2a..3ec75fe2c 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -21,13 +21,14 @@ [*Improvements] -* The rtree insert(), remove() and count() functions support parameters convertible to value_type +* The support of parameters convertible to value_type in rtree insert(), remove() and count() functions [*Solved tickets] * [@https://svn.boost.org/trac/boost/ticket/9354 9354] Bug in winding strategy affecting within() and covered_by() for non-cartesian coordinate systems * [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns +* [@https://svn.boost.org/trac/boost/ticket/10615 10615] Rtree constructor feature request [*Bugfixes] From b98df446e4a8199b032e4a4180cdc3a510a87de4 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Oct 2014 23:04:58 +0200 Subject: [PATCH 29/44] [index] Use in-memory (std::allocator) temporary containers in redistribute_elements. --- .../rtree/linear/redistribute_elements.hpp | 10 ++-- .../geometry/index/detail/rtree/node/node.hpp | 46 ++++++++++--------- .../rtree/quadratic/redistribute_elements.hpp | 16 ++++--- .../rtree/rstar/redistribute_elements.hpp | 11 +++-- 4 files changed, 46 insertions(+), 37 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index bfe603001..8f85c3e43 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -337,15 +337,17 @@ struct redistribute_elements::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) // calculate initial seeds size_t seed1 = 0; size_t seed2 = 0; linear::pick_seeds< - elements_type, + container_type, parameters_type, Translator >::apply(elements_copy, parameters, translator, seed1, seed2); diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index 2b53efd53..60ac7420f 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -85,29 +85,31 @@ struct destroy_element template struct destroy_elements { - typedef typename Options::parameters_type parameters_type; - - typedef typename rtree::internal_node::type internal_node; - typedef typename rtree::leaf::type leaf; - - typedef rtree::node_auto_ptr node_auto_ptr; - - inline static void apply(typename internal_node::elements_type & elements, Allocators & allocators) + template + inline static void apply(Range & elements, Allocators & allocators) { - for ( size_t i = 0 ; i < elements.size() ; ++i ) - { - node_auto_ptr dummy(elements[i].second, allocators); - elements[i].second = 0; - } + apply(boost::begin(elements), boost::end(elements), allocators); } - inline static void apply(typename leaf::elements_type &, Allocators &) - {} - - inline static void apply(typename internal_node::elements_type::iterator first, - typename internal_node::elements_type::iterator last, - Allocators & allocators) + template + inline static void apply(It first, It last, Allocators & allocators) { + typedef boost::mpl::bool_< + boost::is_same< + Value, typename std::iterator_traits::value_type + >::value + > is_range_of_values; + + apply_dispatch(first, last, allocators, is_range_of_values()); + } + +private: + template + inline static void apply_dispatch(It first, It last, Allocators & allocators, + boost::mpl::bool_ const& /*is_range_of_values*/) + { + typedef rtree::node_auto_ptr node_auto_ptr; + for ( ; first != last ; ++first ) { node_auto_ptr dummy(first->second, allocators); @@ -115,9 +117,9 @@ struct destroy_elements } } - inline static void apply(typename leaf::elements_type::iterator /*first*/, - typename leaf::elements_type::iterator /*last*/, - Allocators & /*allocators*/) + template + inline static void apply_dispatch(It first, It last, Allocators & allocators, + boost::mpl::bool_ const& /*is_range_of_values*/) {} }; diff --git a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp index c7e948a05..9cb76a376 100644 --- a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp @@ -114,16 +114,18 @@ struct redistribute_elements::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) + container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG (alloc, copy) // calculate initial seeds size_t seed1 = 0; size_t seed2 = 0; quadratic::pick_seeds< - elements_type, + container_type, parameters_type, Translator, Box @@ -170,7 +172,7 @@ struct redistribute_elements::type elements_type; + typedef typename elements_type::value_type element_type; elements_type & elements1 = rtree::elements(n); elements_type & elements2 = rtree::elements(second_node); - // copy original elements - // TODO: use container_from_elements_type for std::allocator - elements_type elements_copy(elements1); // MAY THROW, STRONG - elements_type elements_backup(elements1); // MAY THROW, STRONG + // copy original elements - use in-memory storage (std::allocator) + // TODO: move if noexcept + typedef typename rtree::container_from_elements_type::type + container_type; + container_type elements_copy(elements1.begin(), elements1.end()); // MAY THROW, STRONG + container_type elements_backup(elements1.begin(), elements1.end()); // MAY THROW, STRONG size_t split_axis = 0; size_t split_corner = 0; From 7ee87715d0efba81dea1defee6aae14e0cc9320d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Oct 2014 23:07:45 +0200 Subject: [PATCH 30/44] [test][index] Add ctor to throwing_varray required by the new implementation of redistribute_elements. --- index/test/rtree/exceptions/test_throwing.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index/test/rtree/exceptions/test_throwing.hpp b/index/test/rtree/exceptions/test_throwing.hpp index 3e080fea1..5fc682ce5 100644 --- a/index/test/rtree/exceptions/test_throwing.hpp +++ b/index/test/rtree/exceptions/test_throwing.hpp @@ -116,6 +116,13 @@ public: typedef typename container::reference reference; typedef typename container::const_reference const_reference; + inline throwing_varray() {} + + template + inline throwing_varray(It first, It last) + : container(first, last) + {} + inline void resize(size_type s) { throwing_varray_settings::throw_if_required(); From 4c192c76ae51207128ec9fd675717ec290649130 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Tue, 7 Oct 2014 23:37:09 +0200 Subject: [PATCH 31/44] [index] Increase readability of redistribute_elements-related code. Convert struct to functions templates (pick_seeds() functions). Move template parameters from struct level to method level. Both for automatic type deduction. --- .../rtree/linear/redistribute_elements.hpp | 33 +++----- .../rtree/quadratic/redistribute_elements.hpp | 81 +++++++++---------- .../rtree/rstar/redistribute_elements.hpp | 73 ++++++++--------- 3 files changed, 83 insertions(+), 104 deletions(-) diff --git a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp index 8f85c3e43..b5ba1cf91 100644 --- a/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/linear/redistribute_elements.hpp @@ -222,7 +222,6 @@ struct pick_seeds_impl typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; typedef find_greatest_normalized_separation< Elements, Parameters, Translator, @@ -282,26 +281,24 @@ struct pick_seeds_impl // from void linear_pick_seeds(node_pointer const& n, unsigned int &seed1, unsigned int &seed2) const template -struct pick_seeds +inline void pick_seeds(Elements const& elements, + Parameters const& parameters, + Translator const& tr, + size_t & seed1, + size_t & seed2) { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; - static const size_t dimension = geometry::dimension::value; - - typedef pick_seeds_impl impl; + typedef pick_seeds_impl + < + Elements, Parameters, Translator, + geometry::dimension::value + > impl; typedef typename impl::separation_type separation_type; - static inline void apply(Elements const& elements, - Parameters const& parameters, - Translator const& tr, - size_t & seed1, - size_t & seed2) - { - separation_type separation = 0; - pick_seeds_impl::apply(elements, parameters, tr, separation, seed1, seed2); - } + separation_type separation = 0; + impl::apply(elements, parameters, tr, separation, seed1, seed2); }; } // namespace linear @@ -346,11 +343,7 @@ struct redistribute_elements::apply(elements_copy, parameters, translator, seed1, seed2); + linear::pick_seeds(elements_copy, parameters, translator, seed1, seed2); // prepare nodes' elements containers elements1.clear(); diff --git a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp index 9cb76a376..634d87986 100644 --- a/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/quadratic/redistribute_elements.hpp @@ -28,60 +28,56 @@ namespace detail { namespace rtree { namespace quadratic { -template -struct pick_seeds +template +inline void pick_seeds(Elements const& elements, + Parameters const& parameters, + Translator const& tr, + size_t & seed1, + size_t & seed2) { typedef typename Elements::value_type element_type; typedef typename rtree::element_indexable_type::type indexable_type; - typedef typename coordinate_type::type coordinate_type; typedef Box box_type; typedef typename index::detail::default_content_result::type content_type; typedef index::detail::bounded_view bounded_indexable_view; - static inline void apply(Elements const& elements, - Parameters const& parameters, - Translator const& tr, - size_t & seed1, - size_t & seed2) + const size_t elements_count = parameters.get_max_elements() + 1; + BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements"); + BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); + + content_type greatest_free_content = 0; + seed1 = 0; + seed2 = 1; + + for ( size_t i = 0 ; i < elements_count - 1 ; ++i ) { - const size_t elements_count = parameters.get_max_elements() + 1; - BOOST_GEOMETRY_INDEX_ASSERT(elements.size() == elements_count, "wrong number of elements"); - BOOST_GEOMETRY_INDEX_ASSERT(2 <= elements_count, "unexpected number of elements"); - - content_type greatest_free_content = 0; - seed1 = 0; - seed2 = 1; - - for ( size_t i = 0 ; i < elements_count - 1 ; ++i ) + for ( size_t j = i + 1 ; j < elements_count ; ++j ) { - for ( size_t j = i + 1 ; j < elements_count ; ++j ) - { - indexable_type const& ind1 = rtree::element_indexable(elements[i], tr); - indexable_type const& ind2 = rtree::element_indexable(elements[j], tr); + indexable_type const& ind1 = rtree::element_indexable(elements[i], tr); + indexable_type const& ind2 = rtree::element_indexable(elements[j], tr); - box_type enlarged_box; - //geometry::convert(ind1, enlarged_box); - detail::bounds(ind1, enlarged_box); - geometry::expand(enlarged_box, ind2); + box_type enlarged_box; + //geometry::convert(ind1, enlarged_box); + detail::bounds(ind1, enlarged_box); + geometry::expand(enlarged_box, ind2); - bounded_indexable_view bounded_ind1(ind1); - bounded_indexable_view bounded_ind2(ind2); - content_type free_content = ( index::detail::content(enlarged_box) - - index::detail::content(bounded_ind1) ) - - index::detail::content(bounded_ind2); + bounded_indexable_view bounded_ind1(ind1); + bounded_indexable_view bounded_ind2(ind2); + content_type free_content = ( index::detail::content(enlarged_box) + - index::detail::content(bounded_ind1) ) + - index::detail::content(bounded_ind2); - if ( greatest_free_content < free_content ) - { - greatest_free_content = free_content; - seed1 = i; - seed2 = j; - } + if ( greatest_free_content < free_content ) + { + greatest_free_content = free_content; + seed1 = i; + seed2 = j; } } - - ::boost::ignore_unused_variable_warning(parameters); } -}; + + ::boost::ignore_unused_variable_warning(parameters); +} } // namespace quadratic @@ -124,12 +120,7 @@ struct redistribute_elements::apply(elements_copy, parameters, translator, seed1, seed2); + quadratic::pick_seeds(elements_copy, parameters, translator, seed1, seed2); // prepare nodes' elements containers elements1.clear(); diff --git a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp index 3d212406f..8f270537f 100644 --- a/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp +++ b/include/boost/geometry/index/detail/rtree/rstar/redistribute_elements.hpp @@ -89,13 +89,13 @@ private: Translator const& m_tr; }; -template +template struct choose_split_axis_and_index_for_corner { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_index, margin_type & sum_of_margins, @@ -160,19 +160,19 @@ struct choose_split_axis_and_index_for_corner } }; -//template +//template //struct choose_split_axis_and_index_for_axis //{ // BOOST_MPL_ASSERT_MSG(false, NOT_IMPLEMENTED_FOR_THIS_TAG, (ElementIndexableTag)); //}; -template +template struct choose_split_axis_and_index_for_axis { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_corner, size_t & choosen_index, @@ -187,20 +187,20 @@ struct choose_split_axis_and_index_for_axis content_type ovl1 = (std::numeric_limits::max)(); content_type con1 = (std::numeric_limits::max)(); - choose_split_axis_and_index_for_corner:: - apply(elements, index1, - som1, ovl1, con1, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, index1, + som1, ovl1, con1, + parameters, translator); // MAY THROW, STRONG size_t index2 = 0; margin_type som2 = 0; content_type ovl2 = (std::numeric_limits::max)(); content_type con2 = (std::numeric_limits::max)(); - choose_split_axis_and_index_for_corner:: - apply(elements, index2, - som2, ovl2, con2, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, index2, + som2, ovl2, con2, + parameters, translator); // MAY THROW, STRONG sum_of_margins = som1 + som2; @@ -221,13 +221,13 @@ struct choose_split_axis_and_index_for_axis } }; -template -struct choose_split_axis_and_index_for_axis +template +struct choose_split_axis_and_index_for_axis { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_corner, size_t & choosen_index, @@ -237,16 +237,16 @@ struct choose_split_axis_and_index_for_axis:: - apply(elements, choosen_index, - sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index_for_corner + ::apply(elements, choosen_index, + sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG choosen_corner = min_corner; } }; -template +template struct choose_split_axis_and_index { BOOST_STATIC_ASSERT(0 < Dimension); @@ -254,7 +254,7 @@ struct choose_split_axis_and_index typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_axis, size_t & choosen_corner, @@ -267,10 +267,10 @@ struct choose_split_axis_and_index { typedef typename rtree::element_indexable_type::type element_indexable_type; - choose_split_axis_and_index:: - apply(elements, choosen_axis, choosen_corner, choosen_index, - smallest_sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + choose_split_axis_and_index + ::apply(elements, choosen_axis, choosen_corner, choosen_index, + smallest_sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG margin_type sum_of_margins = 0; @@ -281,7 +281,6 @@ struct choose_split_axis_and_index content_type content_val = (std::numeric_limits::max)(); choose_split_axis_and_index_for_axis< - Parameters, Box, Dimension - 1, typename tag::type @@ -299,13 +298,13 @@ struct choose_split_axis_and_index } }; -template -struct choose_split_axis_and_index +template +struct choose_split_axis_and_index { typedef typename index::detail::default_margin_result::type margin_type; typedef typename index::detail::default_content_result::type content_type; - template + template static inline void apply(Elements const& elements, size_t & choosen_axis, size_t & choosen_corner, @@ -321,7 +320,6 @@ struct choose_split_axis_and_index choosen_axis = 0; choose_split_axis_and_index_for_axis< - Parameters, Box, 0, typename tag::type @@ -415,14 +413,11 @@ struct redistribute_elements::apply(elements_copy, - split_axis, split_corner, split_index, - smallest_sum_of_margins, smallest_overlap, smallest_content, - parameters, translator); // MAY THROW, STRONG + rstar::choose_split_axis_and_index + ::apply(elements_copy, + split_axis, split_corner, split_index, + smallest_sum_of_margins, smallest_overlap, smallest_content, + parameters, translator); // MAY THROW, STRONG // TODO: awulkiew - get rid of following static_casts? BOOST_GEOMETRY_INDEX_ASSERT(split_axis < dimension, "unexpected value"); From 795bda6abe6b676c71585d767168f4057bc6a828 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 8 Oct 2014 00:08:40 +0200 Subject: [PATCH 32/44] [index] Fix unused parameters warnings. --- include/boost/geometry/index/detail/rtree/node/node.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/geometry/index/detail/rtree/node/node.hpp b/include/boost/geometry/index/detail/rtree/node/node.hpp index 60ac7420f..a632ece66 100644 --- a/include/boost/geometry/index/detail/rtree/node/node.hpp +++ b/include/boost/geometry/index/detail/rtree/node/node.hpp @@ -118,7 +118,7 @@ private: } template - inline static void apply_dispatch(It first, It last, Allocators & allocators, + inline static void apply_dispatch(It /*first*/, It /*last*/, Allocators & /*allocators*/, boost::mpl::bool_ const& /*is_range_of_values*/) {} }; From 296f137d85ae1b49c4b0636cad9408f93a2105eb Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 8 Oct 2014 20:23:42 +0200 Subject: [PATCH 33/44] [overlay][relate][is_valid][buffer] Remove other_id from turn_operation. --- .../detail/buffer/get_piece_turns.hpp | 4 - .../algorithms/detail/is_simple/linear.hpp | 2 +- .../detail/is_valid/debug_print_turns.hpp | 4 +- .../detail/is_valid/is_acceptable_turn.hpp | 4 +- .../detail/is_valid/multipolygon.hpp | 4 +- .../algorithms/detail/is_valid/polygon.hpp | 10 +- .../algorithms/detail/overlay/get_turns.hpp | 15 ++- .../algorithms/detail/overlay/turn_info.hpp | 1 - .../algorithms/detail/relate/areal_areal.hpp | 4 +- .../algorithms/detail/relate/linear_areal.hpp | 4 +- .../detail/relate/linear_linear.hpp | 6 +- .../algorithms/detail/relate/turns.hpp | 101 +++++++++++------- .../algorithms/detail/turns/compare_turns.hpp | 34 +++--- .../algorithms/detail/turns/print_turns.hpp | 8 -- .../detail/turns/remove_duplicate_turns.hpp | 2 +- 15 files changed, 108 insertions(+), 95 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp index 23b09e1c8..395921cca 100644 --- a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp @@ -135,10 +135,6 @@ class piece_turn_visitor it2 != it2_last; prev2 = it2++, the_model.operations[1].seg_id.segment_index++) { - // Revert (this is used more often - should be common function TODO) - the_model.operations[0].other_id = the_model.operations[1].seg_id; - the_model.operations[1].other_id = the_model.operations[0].seg_id; - iterator next2 = next_point(ring2, it2); // TODO: internally get_turn_info calculates robust points. diff --git a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp index 18c33bfc3..f2efcb309 100644 --- a/include/boost/geometry/algorithms/detail/is_simple/linear.hpp +++ b/include/boost/geometry/algorithms/detail/is_simple/linear.hpp @@ -128,7 +128,7 @@ private: linestring const& ls2 = range::at(m_multilinestring, - turn.operations[0].other_id.multi_index); + turn.operations[1].seg_id.multi_index); return is_boundary_point_of(turn.point, ls1) diff --git a/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp b/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp index b14355639..6824921b6 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/debug_print_turns.hpp @@ -40,11 +40,11 @@ inline void debug_print_turns(TurnIterator first, TurnIterator beyond) << " {" << tit->operations[0].seg_id.multi_index << ", " - << tit->operations[0].other_id.multi_index + << tit->operations[1].seg_id.multi_index << "} {" << tit->operations[0].seg_id.ring_index << ", " - << tit->operations[0].other_id.ring_index + << tit->operations[1].seg_id.ring_index << "} " << geometry::dsv(tit->point) << "]"; diff --git a/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp b/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp index 9841aafd2..f9d926770 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp @@ -94,7 +94,7 @@ public: using namespace detail::overlay; if ( turn.operations[0].seg_id.ring_index - == turn.operations[0].other_id.ring_index ) + == turn.operations[1].seg_id.ring_index ) { return false; } @@ -122,7 +122,7 @@ public: using namespace detail::overlay; if ( turn.operations[0].seg_id.multi_index - == turn.operations[0].other_id.multi_index ) + == turn.operations[1].seg_id.multi_index ) { return base::apply(turn); } diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index 3934d1ba4..569156bb5 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -80,7 +80,7 @@ private: for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { multi_indices.insert(tit->operations[0].seg_id.multi_index); - multi_indices.insert(tit->operations[0].other_id.multi_index); + multi_indices.insert(tit->operations[1].seg_id.multi_index); } // put polygon iterators without turns in a vector @@ -120,7 +120,7 @@ private: inline bool operator()(Turn const& turn) const { return turn.operations[0].seg_id.multi_index == m_multi_index - && turn.operations[0].other_id.multi_index == m_multi_index; + && turn.operations[1].seg_id.multi_index == m_multi_index; } private: diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 6df9b2c3d..babdfb61b 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -180,10 +180,10 @@ protected: { if ( tit->operations[0].seg_id.ring_index == -1 ) { - BOOST_ASSERT( tit->operations[0].other_id.ring_index != -1 ); - ring_indices.insert(tit->operations[0].other_id.ring_index); + BOOST_ASSERT( tit->operations[1].seg_id.ring_index != -1 ); + ring_indices.insert(tit->operations[1].seg_id.ring_index); } - else if ( tit->operations[0].other_id.ring_index == -1 ) + else if ( tit->operations[1].seg_id.ring_index == -1 ) { BOOST_ASSERT( tit->operations[0].seg_id.ring_index != -1 ); ring_indices.insert(tit->operations[0].seg_id.ring_index); @@ -207,7 +207,7 @@ protected: for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { ring_indices.insert(tit->operations[0].seg_id.ring_index); - ring_indices.insert(tit->operations[0].other_id.ring_index); + ring_indices.insert(tit->operations[1].seg_id.ring_index); } // put iterators for interior rings without turns in a vector @@ -290,7 +290,7 @@ protected: typename graph::vertex_handle v1 = g.add_vertex ( tit->operations[0].seg_id.ring_index + 1 ); typename graph::vertex_handle v2 = g.add_vertex - ( tit->operations[0].other_id.ring_index + 1 ); + ( tit->operations[1].seg_id.ring_index + 1 ); typename graph::vertex_handle vip = g.add_vertex(tit->point); g.add_edge(v1, vip); diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index 513bfd372..a96538c43 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -278,13 +278,12 @@ public : typedef typename boost::range_value::type turn_info; turn_info ti; - ti.operations[0].seg_id = segment_identifier(source_id1, - sec1.ring_id.multi_index, sec1.ring_id.ring_index, index1), - ti.operations[1].seg_id = segment_identifier(source_id2, - sec2.ring_id.multi_index, sec2.ring_id.ring_index, index2), - - ti.operations[0].other_id = ti.operations[1].seg_id; - ti.operations[1].other_id = ti.operations[0].seg_id; + ti.operations[0].seg_id + = segment_identifier(source_id1, sec1.ring_id.multi_index, + sec1.ring_id.ring_index, index1); + ti.operations[1].seg_id + = segment_identifier(source_id2, sec2.ring_id.multi_index, + sec2.ring_id.ring_index, index2); std::size_t const size_before = boost::size(turns); @@ -678,8 +677,6 @@ private: turn_info ti; ti.operations[0].seg_id = seg_id; - ti.operations[0].other_id = ti.operations[1].seg_id; - ti.operations[1].other_id = seg_id; ti.operations[1].seg_id = segment_identifier(source_id2, -1, -1, 0); TurnPolicy::apply(rp0, rp1, rp2, bp0, bp1, bp2, diff --git a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp index 91a133789..26669a4b1 100644 --- a/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/turn_info.hpp @@ -59,7 +59,6 @@ struct turn_operation { operation_type operation; segment_identifier seg_id; - segment_identifier other_id; SegmentRatio fraction; inline turn_operation() diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index 1896b0ffa..31d206ac9 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -230,7 +230,7 @@ struct areal_areal || may_update(result) ) { // sort turns - typedef turns::less<0, turns::less_op_areal_areal> less; + typedef turns::less<0, turns::less_op_areal_areal<0> > less; std::sort(turns.begin(), turns.end(), less()); /*if ( may_update(result) @@ -269,7 +269,7 @@ struct areal_areal || may_update(result) ) { // sort turns - typedef turns::less<1, turns::less_op_areal_areal> less; + typedef turns::less<1, turns::less_op_areal_areal<1> > less; std::sort(turns.begin(), turns.end(), less()); /*if ( may_update(result) diff --git a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp index b1f341eb0..3159ab329 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_areal.hpp @@ -244,7 +244,7 @@ struct linear_areal { // for different multi or same ring id: x, u, i, c // for same multi and different ring id: c, i, u, x - typedef turns::less<0, turns::less_op_linear_areal> less; + typedef turns::less<0, turns::less_op_linear_areal<0> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -341,7 +341,7 @@ struct linear_areal else { // u, c - typedef turns::less<1, turns::less_op_areal_linear> less; + typedef turns::less<1, turns::less_op_areal_linear<1> > less; std::sort(it, next, less()); // analyse diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index f7ac7f5ed..263c82de5 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -161,7 +161,7 @@ struct linear_linear || may_update(result) || may_update(result) ) { - typedef turns::less<0, turns::less_op_linear_linear> less; + typedef turns::less<0, turns::less_op_linear_linear<0> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -181,7 +181,7 @@ struct linear_linear || may_update(result) || may_update(result) ) { - typedef turns::less<1, turns::less_op_linear_linear> less; + typedef turns::less<1, turns::less_op_linear_linear<1> > less; std::sort(turns.begin(), turns.end(), less()); turns_analyser analyser; @@ -626,7 +626,7 @@ struct linear_linear typename detail::single_geometry_return_type::type ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id); typename detail::single_geometry_return_type::type - ls2_ref = detail::single_geometry(other_geometry, turn.operations[op_id].other_id); + ls2_ref = detail::single_geometry(other_geometry, turn.operations[other_op_id].seg_id); // only one of those should be true: diff --git a/include/boost/geometry/algorithms/detail/relate/turns.hpp b/include/boost/geometry/algorithms/detail/relate/turns.hpp index b8c292bee..cef9b81ef 100644 --- a/include/boost/geometry/algorithms/detail/relate/turns.hpp +++ b/include/boost/geometry/algorithms/detail/relate/turns.hpp @@ -92,8 +92,8 @@ struct get_turns template struct op_to_int { - template - inline int operator()(Op const& op) const + template + inline int operator()(detail::overlay::turn_operation const& op) const { switch(op.operation) { @@ -108,85 +108,111 @@ struct op_to_int } }; -template +template struct less_op_xxx_linear { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { static OpToInt op_to_int; - return op_to_int(left) < op_to_int(right); + return op_to_int(left.operations[OpId]) < op_to_int(right.operations[OpId]); } }; +template struct less_op_linear_linear - : less_op_xxx_linear< op_to_int<0,2,3,1,4,0> > + : less_op_xxx_linear< OpId, op_to_int<0,2,3,1,4,0> > {}; +template struct less_op_linear_areal { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { + static const std::size_t other_op_id = (OpId + 1) % 2; static turns::op_to_int<0,2,3,1,4,0> op_to_int_xuic; static turns::op_to_int<0,3,2,1,4,0> op_to_int_xiuc; - if ( left.other_id.multi_index == right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index ) { - if ( left.other_id.ring_index == right.other_id.ring_index ) - return op_to_int_xuic(left) < op_to_int_xuic(right); + typedef typename Turn::turn_operation_type operation_type; + operation_type const& left_operation = left.operations[OpId]; + operation_type const& right_operation = right.operations[OpId]; + + if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index ) + { + return op_to_int_xuic(left_operation) + < op_to_int_xuic(right_operation); + } else - return op_to_int_xiuc(left) < op_to_int_xiuc(right); + { + return op_to_int_xiuc(left_operation) + < op_to_int_xiuc(right_operation); + } } else { - //return op_to_int_xuic(left) < op_to_int_xuic(right); - return left.other_id.multi_index < right.other_id.multi_index; + //return op_to_int_xuic(left.operations[OpId]) < op_to_int_xuic(right.operations[OpId]); + return left_other_seg_id.multi_index < right_other_seg_id.multi_index; } } }; +template struct less_op_areal_linear - : less_op_xxx_linear< op_to_int<0,1,0,0,2,0> > + : less_op_xxx_linear< OpId, op_to_int<0,1,0,0,2,0> > {}; +template struct less_op_areal_areal { - template - inline bool operator()(Op const& left, Op const& right) + template + inline bool operator()(Turn const& left, Turn const& right) const { + static const std::size_t other_op_id = (OpId + 1) % 2; static op_to_int<0, 1, 2, 3, 4, 0> op_to_int_uixc; static op_to_int<0, 2, 1, 3, 4, 0> op_to_int_iuxc; - if ( left.other_id.multi_index == right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + typedef typename Turn::turn_operation_type operation_type; + operation_type const& left_operation = left.operations[OpId]; + operation_type const& right_operation = right.operations[OpId]; + + if ( left_other_seg_id.multi_index == right_other_seg_id.multi_index ) { - if ( left.other_id.ring_index == right.other_id.ring_index ) + if ( left_other_seg_id.ring_index == right_other_seg_id.ring_index ) { - return op_to_int_uixc(left) < op_to_int_uixc(right); + return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation); } else { - if ( left.other_id.ring_index == -1 ) + if ( left_other_seg_id.ring_index == -1 ) { - if ( left.operation == overlay::operation_union ) + if ( left_operation.operation == overlay::operation_union ) return false; - else if ( left.operation == overlay::operation_intersection ) + else if ( left_operation.operation == overlay::operation_intersection ) return true; } - else if ( right.other_id.ring_index == -1 ) + else if ( right_other_seg_id.ring_index == -1 ) { - if ( right.operation == overlay::operation_union ) + if ( right_operation.operation == overlay::operation_union ) return true; - else if ( right.operation == overlay::operation_intersection ) + else if ( right_operation.operation == overlay::operation_intersection ) return false; } - return op_to_int_iuxc(left) < op_to_int_iuxc(right); + return op_to_int_iuxc(left_operation) < op_to_int_iuxc(right_operation); } } else { - return op_to_int_uixc(left) < op_to_int_uixc(right); + return op_to_int_uixc(left_operation) < op_to_int_uixc(right_operation); } } }; @@ -194,20 +220,19 @@ struct less_op_areal_areal // sort turns by G1 - source_index == 0 by: // seg_id -> distance -> operation template > > + typename LessOp = less_op_xxx_linear< OpId, op_to_int<> > > struct less { BOOST_STATIC_ASSERT(OpId < 2); - template static inline - bool use_fraction(Op const& left, Op const& right) + template + static inline bool use_fraction(Turn const& left, Turn const& right) { - static LessOp less_op; + static const LessOp less_op; - if ( left.fraction == right.fraction ) - return less_op(left, right); - else - return left.fraction < right.fraction; + return left.operations[OpId].fraction < right.operations[OpId].fraction + || ( left.operations[OpId].fraction == right.operations[OpId].fraction + && less_op(left, right) ); } template @@ -216,7 +241,7 @@ struct less segment_identifier const& sl = left.operations[OpId].seg_id; segment_identifier const& sr = right.operations[OpId].seg_id; - return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) ); + return sl < sr || ( sl == sr && use_fraction(left, right) ); } }; diff --git a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp index 7e21c654e..cdc9213f6 100644 --- a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp @@ -37,6 +37,7 @@ template struct less_seg_fraction_other_op { BOOST_STATIC_ASSERT(OpId < 2); + static const std::size_t other_op_id = (OpId + 1) % 2; template static inline int order_op(Op const& op) @@ -59,30 +60,33 @@ struct less_seg_fraction_other_op return order_op(left) < order_op(right); } - template - static inline bool use_other_id(Op const& left, Op const& right) + template + static inline bool use_other_id(Turn const& left, Turn const& right) { - if ( left.other_id.multi_index != right.other_id.multi_index ) + segment_identifier const& left_other_seg_id = left.operations[other_op_id].seg_id; + segment_identifier const& right_other_seg_id = right.operations[other_op_id].seg_id; + + if ( left_other_seg_id.multi_index != right_other_seg_id.multi_index ) { - return left.other_id.multi_index < right.other_id.multi_index; + return left_other_seg_id.multi_index < right_other_seg_id.multi_index; } - if ( left.other_id.ring_index != right.other_id.ring_index ) + if ( left_other_seg_id.ring_index != right_other_seg_id.ring_index ) { - return left.other_id.ring_index != right.other_id.ring_index; + return left_other_seg_id.ring_index != right_other_seg_id.ring_index; } - if ( left.other_id.segment_index != right.other_id.segment_index ) + if ( left_other_seg_id.segment_index != right_other_seg_id.segment_index ) { - return IdLess()(left.other_id.segment_index, - right.other_id.segment_index); + return IdLess()(left_other_seg_id.segment_index, + right_other_seg_id.segment_index); } - return use_operation(left, right); + return use_operation(left.operations[OpId], right.operations[OpId]); } - template - static inline bool use_fraction(Op const& left, Op const& right) + template + static inline bool use_fraction(Turn const& left, Turn const& right) { - return left.fraction < right.fraction - || ( geometry::math::equals(left.fraction, right.fraction) + return left.operations[OpId].fraction < right.operations[OpId].fraction + || ( geometry::math::equals(left.operations[OpId].fraction, right.operations[OpId].fraction) && use_other_id(left, right) ); } @@ -93,7 +97,7 @@ struct less_seg_fraction_other_op segment_identifier const& sl = left.operations[OpId].seg_id; segment_identifier const& sr = right.operations[OpId].seg_id; - return sl < sr || ( sl == sr && use_fraction(left.operations[OpId], right.operations[OpId]) ); + return sl < sr || ( sl == sr && use_fraction(left, right) ); } }; diff --git a/include/boost/geometry/algorithms/detail/turns/print_turns.hpp b/include/boost/geometry/algorithms/detail/turns/print_turns.hpp index 8b42a0ce9..b339e11c9 100644 --- a/include/boost/geometry/algorithms/detail/turns/print_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/print_turns.hpp @@ -62,10 +62,6 @@ static inline void print_turns(Geometry1 const& g1, << ", m: " << turn.operations[0].seg_id.multi_index << ", r: " << turn.operations[0].seg_id.ring_index << ", s: " << turn.operations[0].seg_id.segment_index << ", "; - out << "other: " << turn.operations[0].other_id.source_index - << ", m: " << turn.operations[0].other_id.multi_index - << ", r: " << turn.operations[0].other_id.ring_index - << ", s: " << turn.operations[0].other_id.segment_index; out << ", fr: " << fraction[0]; out << ", col?: " << turn.operations[0].is_collinear; out << ' ' << geometry::dsv(turn.point) << ' '; @@ -80,10 +76,6 @@ static inline void print_turns(Geometry1 const& g1, << ", m: " << turn.operations[1].seg_id.multi_index << ", r: " << turn.operations[1].seg_id.ring_index << ", s: " << turn.operations[1].seg_id.segment_index << ", "; - out << "other: " << turn.operations[1].other_id.source_index - << ", m: " << turn.operations[1].other_id.multi_index - << ", r: " << turn.operations[1].other_id.ring_index - << ", s: " << turn.operations[1].other_id.segment_index; out << ", fr: " << fraction[1]; out << ", col?: " << turn.operations[1].is_collinear; out << ' ' << geometry::dsv(turn.point) << ' '; diff --git a/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp index d48736c8f..ccb19efb7 100644 --- a/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/remove_duplicate_turns.hpp @@ -39,7 +39,7 @@ private: { return geometry::equals(t1.point, t2.point) && t1.operations[0].seg_id == t2.operations[0].seg_id - && t1.operations[0].other_id == t2.operations[0].other_id; + && t1.operations[1].seg_id == t2.operations[1].seg_id; } }; From 7cf47bb1e5b753e333a47d69a0adbb1c9fd46ca7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 8 Oct 2014 23:50:16 +0200 Subject: [PATCH 34/44] [overlay][is_valid] Replace int with signed_index_type for segments indexes. --- .../detail/is_valid/complement_graph.hpp | 12 ++--- .../detail/is_valid/multipolygon.hpp | 10 ++--- .../algorithms/detail/is_valid/polygon.hpp | 4 +- .../detail/overlay/copy_segment_point.hpp | 4 +- .../detail/overlay/copy_segments.hpp | 45 ++++++++++--------- .../detail/overlay/enrichment_info.hpp | 2 +- .../algorithms/detail/overlay/follow.hpp | 14 +++--- .../detail/overlay/follow_linear_linear.hpp | 12 ++--- .../algorithms/detail/overlay/overlay.hpp | 6 +-- .../detail/overlay/segment_identifier.hpp | 23 +++++++--- .../algorithms/detail/overlay/traverse.hpp | 6 ++- .../algorithms/detail/ring_identifier.hpp | 10 +++-- .../algorithms/detail/turns/compare_turns.hpp | 2 +- .../test_get_turns_ll_invariance.hpp | 4 +- 14 files changed, 86 insertions(+), 68 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp index 2272bbf32..c59139a92 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/complement_graph.hpp @@ -104,12 +104,12 @@ private: , m_parent_id(num_nodes, -1) {} - inline int parent_id(vertex_handle v) const + inline signed_index_type parent_id(vertex_handle v) const { return m_parent_id[v->id()]; } - inline void set_parent_id(vertex_handle v, int id) + inline void set_parent_id(vertex_handle v, signed_index_type id) { m_parent_id[v->id()] = id; } @@ -125,7 +125,7 @@ private: } private: std::vector m_visited; - std::vector m_parent_id; + std::vector m_parent_id; }; @@ -145,7 +145,7 @@ private: = m_neighbors[v->id()].begin(); nit != m_neighbors[v->id()].end(); ++nit) { - if ( static_cast((*nit)->id()) != data.parent_id(v) ) + if ( static_cast((*nit)->id()) != data.parent_id(v) ) { if ( data.visited(*nit) ) { @@ -153,7 +153,7 @@ private: } else { - data.set_parent_id(*nit, static_cast(v->id())); + data.set_parent_id(*nit, static_cast(v->id())); stack.push(*nit); } } @@ -173,7 +173,7 @@ public: // inserts a ring vertex in the graph and returns its handle // ring id's are zero-based (so the first interior ring has id 1) - inline vertex_handle add_vertex(int id) + inline vertex_handle add_vertex(signed_index_type id) { return m_vertices.insert(vertex(static_cast(id))).first; } diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index 569156bb5..3d0ebb5f8 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -76,7 +76,7 @@ private: TurnIterator turns_beyond) { // collect all polygons that have turns - std::set multi_indices; + std::set multi_indices; for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { multi_indices.insert(tit->operations[0].seg_id.multi_index); @@ -85,7 +85,7 @@ private: // put polygon iterators without turns in a vector std::vector polygon_iterators; - int multi_index = 0; + signed_index_type multi_index = 0; for (PolygonIterator it = polygons_first; it != polygons_beyond; ++it, ++multi_index) { @@ -112,7 +112,7 @@ private: class has_multi_index { public: - has_multi_index(int multi_index) + has_multi_index(signed_index_type multi_index) : m_multi_index(multi_index) {} @@ -124,7 +124,7 @@ private: } private: - int const m_multi_index; + signed_index_type const m_multi_index; }; @@ -138,7 +138,7 @@ private: TurnIterator turns_first, TurnIterator turns_beyond) { - int multi_index = 0; + signed_index_type multi_index = 0; for (PolygonIterator it = polygons_first; it != polygons_beyond; ++it, ++multi_index) { diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index babdfb61b..3a9199920 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -175,7 +175,7 @@ protected: { // collect the interior ring indices that have turns with the // exterior ring - std::set ring_indices; + std::set ring_indices; for (TurnIterator tit = turns_first; tit != turns_beyond; ++tit) { if ( tit->operations[0].seg_id.ring_index == -1 ) @@ -190,7 +190,7 @@ protected: } } - int ring_index = 0; + signed_index_type ring_index = 0; for (RingIterator it = rings_first; it != rings_beyond; ++it, ++ring_index) { diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp index 5ee9b031e..20a6d7f48 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segment_point.hpp @@ -53,7 +53,7 @@ struct copy_segment_point_range SegmentIdentifier const& seg_id, bool second, PointOut& point) { - int index = seg_id.segment_index; + signed_index_type index = seg_id.segment_index; if (second) { index++; @@ -112,7 +112,7 @@ struct copy_segment_point_box SegmentIdentifier const& seg_id, bool second, PointOut& point) { - int index = seg_id.segment_index; + signed_index_type index = seg_id.segment_index; if (second) { index++; diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index 5aae862ce..ceeb1a3b8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -63,7 +63,8 @@ struct copy_segments_ring typename RangeOut > static inline void apply(Ring const& ring, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -92,10 +93,10 @@ struct copy_segments_ring // So we use the ever-circling iterator and determine when to step out - int const from_index = seg_id.segment_index + 1; + signed_index_type const from_index = seg_id.segment_index + 1; // Sanity check - BOOST_ASSERT(from_index < int(boost::size(view))); + BOOST_ASSERT(from_index < static_cast(boost::size(view))); ec_iterator it(boost::begin(view), boost::end(view), boost::begin(view) + from_index); @@ -103,12 +104,12 @@ struct copy_segments_ring // [2..4] -> 4 - 2 + 1 = 3 -> {2,3,4} -> OK // [4..2],size=6 -> 6 - 4 + 2 + 1 = 5 -> {4,5,0,1,2} -> OK // [1..1], travel the whole ring round - typedef typename boost::range_difference::type size_type; - size_type const count = from_index <= to_index + signed_index_type const count = from_index <= to_index ? to_index - from_index + 1 - : int(boost::size(view)) - from_index + to_index + 1; + : static_cast(boost::size(view)) + - from_index + to_index + 1; - for (size_type i = 0; i < count; ++i, ++it) + for (signed_index_type i = 0; i < count; ++i, ++it) { detail::overlay::append_no_dups_or_spikes(current_output, *it, robust_policy); } @@ -149,27 +150,27 @@ public: typename RangeOut > static inline void apply(LineString const& ls, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { - int const from_index = seg_id.segment_index + 1; + signed_index_type const from_index = seg_id.segment_index + 1; // Sanity check if ( from_index > to_index || from_index < 0 - || to_index >= static_cast(boost::size(ls)) ) + || to_index >= static_cast(boost::size(ls)) ) { return; } - typedef typename boost::range_difference::type diff_t; - diff_t const count = to_index - from_index + 1; + signed_index_type const count = to_index - from_index + 1; typename boost::range_iterator::type it = boost::begin(ls) + from_index; - for (diff_t i = 0; i < count; ++i, ++it) + for (signed_index_type i = 0; i < count; ++i, ++it) { append_to_output(current_output, *it, robust_policy, boost::integral_constant()); @@ -188,7 +189,8 @@ struct copy_segments_polygon typename RangeOut > static inline void apply(Polygon const& polygon, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -217,14 +219,15 @@ struct copy_segments_box typename RangeOut > static inline void apply(Box const& box, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { - int index = seg_id.segment_index + 1; + signed_index_type index = seg_id.segment_index + 1; BOOST_ASSERT(index < 5); - int const count = index <= to_index + signed_index_type const count = index <= to_index ? to_index - index + 1 : 5 - index + to_index + 1; @@ -235,7 +238,7 @@ struct copy_segments_box // (possibly cyclic) copy to output // (see comments in ring-version) - for (int i = 0; i < count; i++, index++) + for (signed_index_type i = 0; i < count; i++, index++) { detail::overlay::append_no_dups_or_spikes(current_output, bp[index % 5], robust_policy); @@ -256,7 +259,8 @@ struct copy_segments_multi typename RangeOut > static inline void apply(MultiGeometry const& multi_geometry, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& current_output) { @@ -343,7 +347,8 @@ template typename RangeOut > inline void copy_segments(Geometry const& geometry, - SegmentIdentifier const& seg_id, int to_index, + SegmentIdentifier const& seg_id, + signed_index_type to_index, RobustPolicy const& robust_policy, RangeOut& range_out) { diff --git a/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp b/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp index 6668c9924..ef32edeef 100644 --- a/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/enrichment_info.hpp @@ -37,7 +37,7 @@ struct enrichment_info // vertex to which is free travel after this IP, // so from "segment_index+1" to "travels_to_vertex_index", without IP-s, // can be -1 - int travels_to_vertex_index; + signed_index_type travels_to_vertex_index; // same but now IP index, so "next IP index" but not on THIS segment int travels_to_ip_index; diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index 83aa4ce6e..acf38d09a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -163,7 +163,7 @@ struct action_selector static inline void enter(LineStringOut& current_piece, LineString const& , segment_identifier& segment_id, - int , Point const& point, + signed_index_type , Point const& point, Operation const& operation, RobustPolicy const& , OutputIterator& ) @@ -186,7 +186,7 @@ struct action_selector static inline void leave(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& , RobustPolicy const& robust_policy, OutputIterator& out) @@ -217,7 +217,7 @@ struct action_selector static inline void isolated_point(LineStringOut&, LineString const&, segment_identifier&, - int, Point const& point, + signed_index_type, Point const& point, Operation const& , OutputIterator& out) { LineStringOut isolated_point_ls; @@ -268,7 +268,7 @@ struct action_selector static inline void enter(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& operation, RobustPolicy const& robust_policy, OutputIterator& out) @@ -289,7 +289,7 @@ struct action_selector static inline void leave(LineStringOut& current_piece, LineString const& linestring, segment_identifier& segment_id, - int index, Point const& point, + signed_index_type index, Point const& point, Operation const& operation, RobustPolicy const& robust_policy, OutputIterator& out) @@ -309,7 +309,7 @@ struct action_selector static inline void isolated_point(LineStringOut&, LineString const&, segment_identifier&, - int, Point const&, + signed_index_type, Point const&, Operation const&, OutputIterator&) { } @@ -496,7 +496,7 @@ public : false, RemoveSpikes >::apply(linestring, current_segment_id, - static_cast(boost::size(linestring) - 1), + static_cast(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 2954921a0..85378e08b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow_linear_linear.hpp @@ -265,7 +265,7 @@ protected: false, false // do not reverse; do not remove spikes >::apply(linestring, current_segment_id, - static_cast(boost::size(linestring) - 1), + static_cast(boost::size(linestring) - 1), robust_policy, current_piece); } @@ -380,7 +380,7 @@ protected: }; template - static inline int get_multi_index(TurnIterator it) + static inline signed_index_type get_multi_index(TurnIterator it) { return boost::begin(it->operations)->seg_id.multi_index; } @@ -388,10 +388,10 @@ protected: class has_other_multi_id { private: - int m_multi_id; + signed_index_type m_multi_id; public: - has_other_multi_id(int multi_id) + has_other_multi_id(signed_index_type multi_id) : m_multi_id(multi_id) {} template @@ -422,7 +422,7 @@ public: // Iterate through all intersection points (they are // ordered along the each linestring) - int current_multi_id = get_multi_index(first); + signed_index_type current_multi_id = get_multi_index(first); oit = copy_linestrings::apply(ls_first, ls_first + current_multi_id, @@ -439,7 +439,7 @@ public: oit = Base::apply(*(ls_first + current_multi_id), linear, per_ls_current, per_ls_next, oit); - int next_multi_id(-1); + signed_index_type next_multi_id(-1); linestring_iterator ls_next = ls_beyond; if ( per_ls_next != beyond ) { diff --git a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp index 29e0dad0c..44b5a0df3 100644 --- a/include/boost/geometry/algorithms/detail/overlay/overlay.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @@ -74,19 +74,17 @@ inline void map_turns(Map& map, TurnPoints const& turn_points) typedef typename boost::range_value::type turn_point_type; typedef typename turn_point_type::container_type container_type; - int index = 0; for (typename boost::range_iterator::type it = boost::begin(turn_points); it != boost::end(turn_points); - ++it, ++index) + ++it) { if (! skip(*it)) { - int op_index = 0; for (typename boost::range_iterator::type op_it = boost::begin(it->operations); op_it != boost::end(it->operations); - ++op_it, ++op_index) + ++op_it) { ring_identifier ring_id ( diff --git a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp index e510b5bf9..23eae54e0 100644 --- a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp @@ -14,9 +14,13 @@ # define BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER #endif +#if defined(BOOST_GEOMETRY_DEBUG_SEGMENT_IDENTIFIER) +#include +#endif -#include +#include +#include #include #include @@ -27,6 +31,10 @@ namespace boost { namespace geometry { +typedef boost::make_signed::type signed_index_type; +//typedef std::ptrdiff_t signed_index_type; + + // Internal struct to uniquely identify a segment // on a linestring,ring // or polygon (needs ring_index) @@ -40,7 +48,10 @@ struct segment_identifier , segment_index(-1) {} - inline segment_identifier(int src, int mul, int rin, int seg) + inline segment_identifier(signed_index_type src, + signed_index_type mul, + signed_index_type rin, + signed_index_type seg) : source_index(src) , multi_index(mul) , ring_index(rin) @@ -78,10 +89,10 @@ struct segment_identifier } #endif - int source_index; - int multi_index; - int ring_index; - int segment_index; + signed_index_type source_index; + signed_index_type multi_index; + signed_index_type ring_index; + signed_index_type segment_index; }; diff --git a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp index bde86b4d7..59d2ba703 100644 --- a/include/boost/geometry/algorithms/detail/overlay/traverse.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/traverse.hpp @@ -149,7 +149,9 @@ inline bool assign_next_ip(G1 const& g1, G2 const& g2, } -inline bool select_source(operation_type operation, int source1, int source2) +inline bool select_source(operation_type operation, + signed_index_type source1, + signed_index_type source2) { return (operation == operation_intersection && source1 != source2) || (operation == operation_union && source1 == source2) @@ -324,7 +326,7 @@ public : detail::overlay::debug_traverse(*current, *current_iit, "Selected "); - unsigned int i = 0; + typename boost::range_size::type i = 0; while (current_iit != iit && state.good()) { diff --git a/include/boost/geometry/algorithms/detail/ring_identifier.hpp b/include/boost/geometry/algorithms/detail/ring_identifier.hpp index 9209ee030..d1022afc2 100644 --- a/include/boost/geometry/algorithms/detail/ring_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/ring_identifier.hpp @@ -24,7 +24,9 @@ struct ring_identifier , ring_index(-1) {} - inline ring_identifier(int src, int mul, int rin) + inline ring_identifier(signed_index_type src, + signed_index_type mul, + signed_index_type rin) : source_index(src) , multi_index(mul) , ring_index(rin) @@ -58,9 +60,9 @@ struct ring_identifier #endif - int source_index; - int multi_index; - int ring_index; + signed_index_type source_index; + signed_index_type multi_index; + signed_index_type ring_index; }; diff --git a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp index cdc9213f6..c29d5863b 100644 --- a/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp +++ b/include/boost/geometry/algorithms/detail/turns/compare_turns.hpp @@ -30,7 +30,7 @@ namespace detail { namespace turns // seg_id -> fraction -> other_id -> operation template < - typename IdLess = std::less, + 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 > diff --git a/test/algorithms/test_get_turns_ll_invariance.hpp b/test/algorithms/test_get_turns_ll_invariance.hpp index 1492df4c8..5d47570d6 100644 --- a/test/algorithms/test_get_turns_ll_invariance.hpp +++ b/test/algorithms/test_get_turns_ll_invariance.hpp @@ -128,10 +128,10 @@ public: bg_turns::less_seg_fraction_other_op<>()); std::sort(boost::begin(rturns_all), boost::end(rturns_all), - bg_turns::less_seg_fraction_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_fraction_other_op >()); + bg_turns::less_seg_fraction_other_op >()); remove_duplicate_turns::apply(turns_all); remove_duplicate_turns::apply(turns_wo_cont); From e539a0927850a082bc5d637dace34209209f06d9 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 9 Oct 2014 01:07:14 +0200 Subject: [PATCH 35/44] [overlay] Move signed_index_type to separate file. Clean headers in ring_ and segment_identifier.hpp. --- .../detail/overlay/segment_identifier.hpp | 10 +------ .../algorithms/detail/ring_identifier.hpp | 8 +++++ .../algorithms/detail/signed_index_type.hpp | 29 +++++++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 include/boost/geometry/algorithms/detail/signed_index_type.hpp diff --git a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp index 23eae54e0..516ec349e 100644 --- a/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/segment_identifier.hpp @@ -19,21 +19,13 @@ #endif -#include -#include - -#include -#include - +#include namespace boost { namespace geometry { -typedef boost::make_signed::type signed_index_type; -//typedef std::ptrdiff_t signed_index_type; - // Internal struct to uniquely identify a segment // on a linestring,ring diff --git a/include/boost/geometry/algorithms/detail/ring_identifier.hpp b/include/boost/geometry/algorithms/detail/ring_identifier.hpp index d1022afc2..bc3fe1fef 100644 --- a/include/boost/geometry/algorithms/detail/ring_identifier.hpp +++ b/include/boost/geometry/algorithms/detail/ring_identifier.hpp @@ -10,6 +10,14 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RING_IDENTIFIER_HPP +#if defined(BOOST_GEOMETRY_DEBUG_IDENTIFIER) +#include +#endif + + +#include + + namespace boost { namespace geometry { diff --git a/include/boost/geometry/algorithms/detail/signed_index_type.hpp b/include/boost/geometry/algorithms/detail/signed_index_type.hpp new file mode 100644 index 000000000..36dcf4de4 --- /dev/null +++ b/include/boost/geometry/algorithms/detail/signed_index_type.hpp @@ -0,0 +1,29 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2014, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, 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) + +#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP +#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP + + +#include +#include + + +namespace boost { namespace geometry +{ + + +typedef boost::make_signed::type signed_index_type; +//typedef std::ptrdiff_t signed_index_type; + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_SIGNED_INDEX_TYPE_HPP From 326d267f9dc639fc682cab910511359955f3fa88 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Thu, 9 Oct 2014 01:41:43 +0200 Subject: [PATCH 36/44] [test][setops] Fix invalid namespace in test_get_turns_ll_invariance. --- test/algorithms/test_get_turns_ll_invariance.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/algorithms/test_get_turns_ll_invariance.hpp b/test/algorithms/test_get_turns_ll_invariance.hpp index 5d47570d6..c0a59c1c4 100644 --- a/test/algorithms/test_get_turns_ll_invariance.hpp +++ b/test/algorithms/test_get_turns_ll_invariance.hpp @@ -128,10 +128,10 @@ public: bg_turns::less_seg_fraction_other_op<>()); std::sort(boost::begin(rturns_all), boost::end(rturns_all), - bg_turns::less_seg_fraction_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_fraction_other_op >()); + bg_turns::less_seg_fraction_other_op >()); remove_duplicate_turns::apply(turns_all); remove_duplicate_turns::apply(turns_wo_cont); From 776cc4c7316c57dc152e9f71a2721abfe50f76ae Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 13:04:20 +0200 Subject: [PATCH 37/44] [point_on_surface] Use arithmetic mean instead of centroid(bashein-detmer). --- .../geometry/algorithms/point_on_surface.hpp | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/algorithms/point_on_surface.hpp b/include/boost/geometry/algorithms/point_on_surface.hpp index a6f7ed71d..01f012308 100644 --- a/include/boost/geometry/algorithms/point_on_surface.hpp +++ b/include/boost/geometry/algorithms/point_on_surface.hpp @@ -142,6 +142,30 @@ struct min_of_intruder } }; + +template +inline void calculate_average(Point& point, std::vector

const& points) +{ + typedef typename geometry::coordinate_type::type coordinate_type; + typedef typename std::vector

::const_iterator iterator_type; + typedef typename std::vector

::size_type size_type; + + coordinate_type x = 0; + coordinate_type y = 0; + + iterator_type end = points.end(); + for ( iterator_type it = points.begin() ; it != end ; ++it) + { + x += geometry::get<0>(*it); + y += geometry::get<1>(*it); + } + + size_type const count = points.size(); + geometry::set<0>(point, x / count); + geometry::set<1>(point, y / count); +} + + template inline void calculate_centroid(Point& point, Segments const& segments) { @@ -305,7 +329,8 @@ inline bool calculate_point_on_surface(Geometry const& geometry, Point& point) } // Now calculate the centroid of the (possibly adapted) extremes - calculate_centroid(point, extremes); + calculate_average(point, extremes); + //calculate_centroid(point, extremes); return true; } From 5ea7bcc5a78458161b983743a12c9fa5c6bf4d6b Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 13:05:40 +0200 Subject: [PATCH 38/44] [test][point_on_surface] Add test for Polygon using big coordinates (ticket 10643) --- test/algorithms/point_on_surface.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index b393a35b8..1234754a4 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -51,7 +51,7 @@ #endif template -void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x, double expected_y) +void test_geometry(std::string const& case_id, std::string const& wkt, double /*expected_x*/ = 0, double /*expected_y*/ = 0) { //std::cout << case_id << std::endl; typedef typename bg::point_type::type point_type; @@ -152,6 +152,10 @@ void test_all() test_geometry("disjoint_simplex0", disjoint_simplex[0], 0, 0); test_geometry("disjoint_simplex1", disjoint_simplex[1], 0, 0); + test_geometry("ticket_10643", "POLYGON((1074699.93 703064.65, 1074703.90 703064.58, 1074704.53 703061.40, 1074702.10 703054.62, 1074699.93 703064.65))"); + test_geometry("ticket_10643_2", "POLYGON((699.93 64.65, 703.90 64.58, 704.53 61.40, 702.10 54.62, 699.93 64.65))"); + + #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI) { typedef bg::model::multi_polygon multi_polygon; From 9a01219429b62a9df504e6b984db3e72d1277cf8 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 16:21:36 +0200 Subject: [PATCH 39/44] [test][point_on_surface] Add test for Polygon containing non-uniformly distributed points. --- test/algorithms/point_on_surface.cpp | 33 +++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index 1234754a4..bd8be5676 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -51,15 +51,11 @@ #endif template -void test_geometry(std::string const& case_id, std::string const& wkt, double /*expected_x*/ = 0, double /*expected_y*/ = 0) +void test_geometry(std::string const& case_id, Geometry const& geometry, double /*expected_x*/ = 0, double /*expected_y*/ = 0) { //std::cout << case_id << std::endl; typedef typename bg::point_type::type point_type; - Geometry geometry; - bg::read_wkt(wkt, geometry); - bg::correct(geometry); - point_type point; bg::point_on_surface(geometry, point); @@ -125,6 +121,15 @@ void test_geometry(std::string const& case_id, std::string const& wkt, double /* } +template +void test_geometry(std::string const& case_id, std::string const& wkt, double expected_x = 0, double expected_y = 0) +{ + Geometry geometry; + bg::read_wkt(wkt, geometry); + bg::correct(geometry); + test_geometry(case_id, geometry, expected_x, expected_y); +} + template void test_all() { @@ -155,7 +160,6 @@ void test_all() test_geometry("ticket_10643", "POLYGON((1074699.93 703064.65, 1074703.90 703064.58, 1074704.53 703061.40, 1074702.10 703054.62, 1074699.93 703064.65))"); test_geometry("ticket_10643_2", "POLYGON((699.93 64.65, 703.90 64.58, 704.53 61.40, 702.10 54.62, 699.93 64.65))"); - #if defined(BOOST_GEOMETRY_UNIT_TEST_MULTI) { typedef bg::model::multi_polygon multi_polygon; @@ -307,12 +311,29 @@ void test_all() test_geometry("ticket_8254", ticket_8254[0], 0, 0); } +template +void test_dense(std::string const& case_id, double size) +{ + typedef bg::model::polygon polygon; + polygon poly; + double thres = 3.14158 / 8; + for ( double a = thres ; a > -thres ; a -= 0.01 ) + { + bg::append(poly, Point(size * ::cos(a), size * ::sin(a))); + } + bg::append(poly, Point(-size, 0)); + + test_geometry(case_id, poly); +} int test_main(int, char* []) { test_all >(); + test_dense >("dense1", 100); + test_dense >("dense2", 1000000); + return 0; } From 45029d6cb5f9ce845b4708e95c7ec86f9ec50e8e Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 20:38:17 +0200 Subject: [PATCH 40/44] [point_on_surface] Remove unneeded function. --- .../geometry/algorithms/point_on_surface.hpp | 65 ++----------------- 1 file changed, 6 insertions(+), 59 deletions(-) diff --git a/include/boost/geometry/algorithms/point_on_surface.hpp b/include/boost/geometry/algorithms/point_on_surface.hpp index 01f012308..3fa83bfe6 100644 --- a/include/boost/geometry/algorithms/point_on_surface.hpp +++ b/include/boost/geometry/algorithms/point_on_surface.hpp @@ -5,6 +5,11 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, 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) @@ -166,63 +171,6 @@ inline void calculate_average(Point& point, std::vector

const& points) } -template -inline void calculate_centroid(Point& point, Segments const& segments) -{ - if (segments.size() == 3) - { - // In almost all cases, the segments do have 3 values. In that case we use another - // centroid calculation, which should be slightly faster - // and is more precise (case #geos_1_test_overlay => normal centroid is outside! TODO) - - typedef typename geometry::coordinate_type::type coordinate_type; - coordinate_type const three = 3.0; - coordinate_type const sx = geometry::get<0>(segments[0]) + geometry::get<0>(segments[1]) + geometry::get<0>(segments[2]); - coordinate_type const sy = geometry::get<1>(segments[0]) + geometry::get<1>(segments[1]) + geometry::get<1>(segments[2]); - geometry::set<0>(point, sx / three); - geometry::set<1>(point, sy / three); - return; - } - - // For 4 or more segments, we use normal centroid calculation - - // Specify centroid, it should have "areal_tag" to have correct calculation - typedef typename strategy::centroid::services::default_strategy - < - typename cs_tag::type, - areal_tag, - dimension::type::value, - Point, - Point - >::type strategy_type; - - strategy_type strategy; - - - // Ignore warning (because using static method sometimes) on strategy - boost::ignore_unused_variable_warning(strategy); - - - typename strategy_type::state_type state; - - typedef typename boost::range_iterator::type iterator_type; - - iterator_type begin = boost::begin(segments); - iterator_type end = boost::end(segments); - iterator_type it = begin; - iterator_type previous = it++; - for (; it != end; ++previous, ++it) - { - strategy.apply(*previous, *it, state); - } - // Close it explicitly: - strategy.apply(*previous, *begin, state); - - strategy.result(state, point); -} - - - template inline void replace_extremes_for_self_tangencies(Extremes& extremes, Intruders& intruders, CoordinateType const& max_intruder) { @@ -328,9 +276,8 @@ inline bool calculate_point_on_surface(Geometry const& geometry, Point& point) } } - // Now calculate the centroid of the (possibly adapted) extremes + // Now calculate the average/centroid of the (possibly adapted) extremes calculate_average(point, extremes); - //calculate_centroid(point, extremes); return true; } From d5f8b1c5fc7fe6740d7539d196108d56e6c21108 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 20:38:44 +0200 Subject: [PATCH 41/44] [test][point_on_surface] Add missing closing Point in on of the tests. --- test/algorithms/point_on_surface.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/algorithms/point_on_surface.cpp b/test/algorithms/point_on_surface.cpp index bd8be5676..0af85c7a4 100644 --- a/test/algorithms/point_on_surface.cpp +++ b/test/algorithms/point_on_surface.cpp @@ -6,6 +6,11 @@ // Copyright (c) 2009-2013 Mateusz Loskot, London, UK. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. +// This file was modified by Oracle on 2014. +// Modifications copyright (c) 2014 Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -316,11 +321,15 @@ void test_dense(std::string const& case_id, double size) { typedef bg::model::polygon polygon; polygon poly; + + bg::append(poly, Point(-size, 0)); + double thres = 3.14158 / 8; for ( double a = thres ; a > -thres ; a -= 0.01 ) { bg::append(poly, Point(size * ::cos(a), size * ::sin(a))); } + bg::append(poly, Point(-size, 0)); test_geometry(case_id, poly); From 99ceace25bd6e92c8bbfde417883524db2ae7d1d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 20:41:11 +0200 Subject: [PATCH 42/44] [doc] Update release notes. --- doc/release_notes.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index 3ec75fe2c..bac5584bb 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -29,6 +29,7 @@ * [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns * [@https://svn.boost.org/trac/boost/ticket/10615 10615] Rtree constructor feature request +* [@https://svn.boost.org/trac/boost/ticket/10643 10643] Invalid point_on_surface() result for big coordinates [*Bugfixes] From b36d2f1a1e936c83813dd1783742fffd39f7f071 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 10 Oct 2014 20:47:39 +0200 Subject: [PATCH 43/44] [doc] Update release notes. --- doc/release_notes.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/release_notes.qbk b/doc/release_notes.qbk index bac5584bb..7fd40cdd0 100644 --- a/doc/release_notes.qbk +++ b/doc/release_notes.qbk @@ -25,6 +25,7 @@ [*Solved tickets] +* [@https://svn.boost.org/trac/boost/ticket/8402 8402] Implicit casts warnings * [@https://svn.boost.org/trac/boost/ticket/9354 9354] Bug in winding strategy affecting within() and covered_by() for non-cartesian coordinate systems * [@https://svn.boost.org/trac/boost/ticket/10177 10177] Missing include * [@https://svn.boost.org/trac/boost/ticket/10398 10398] Wrong neighbour check in buffer, calculating turns From ee7dc28b651b055eb85b34c28149df794ea56dd8 Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Wed, 15 Oct 2014 12:08:11 +0200 Subject: [PATCH 44/44] [test] fix creation of SVG for intersection, the SVG block was placed in the wrong function when splitting the original function --- test/algorithms/test_intersection.hpp | 97 +++++++++++++-------------- 1 file changed, 48 insertions(+), 49 deletions(-) diff --git a/test/algorithms/test_intersection.hpp b/test/algorithms/test_intersection.hpp index 36c4c1154..4a7cc645c 100644 --- a/test/algorithms/test_intersection.hpp +++ b/test/algorithms/test_intersection.hpp @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -47,10 +46,6 @@ check_result( { bool const is_line = bg::geometry_id::type::value == 2; - typedef typename bg::coordinate_type::type coordinate_type; - typedef typename bg::point_type::type point_type; - boost::ignore_unused(); - typename bg::default_area_result::type length_or_area = 0; int n = 0; for (typename std::vector::const_iterator it = intersection_output.begin(); @@ -100,50 +95,6 @@ check_result( BOOST_CHECK_CLOSE(detected_length_or_area, expected_length_or_area, percentage); #endif -#if defined(TEST_WITH_SVG) - { - bool const ccw = - bg::point_order::value == bg::counterclockwise - || bg::point_order::value == bg::counterclockwise; - bool const open = - bg::closure::value == bg::open - || bg::closure::value == bg::open; - - std::ostringstream filename; - filename << "intersection_" - << caseid << "_" - << string_from_type::name() - << string_from_type::name() - << (ccw ? "_ccw" : "") - << (open ? "_open" : "") -#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS) - << "_no_rob" -#endif - << ".svg"; - - std::ofstream svg(filename.str().c_str()); - - bg::svg_mapper mapper(svg, 500, 500); - - mapper.add(g1); - mapper.add(g2); - - mapper.map(g1, is_line - ? "opacity:0.6;stroke:rgb(0,255,0);stroke-width:5" - : "fill-opacity:0.5;fill:rgb(153,204,0);" - "stroke:rgb(153,204,0);stroke-width:3"); - mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" - "stroke:rgb(51,51,153);stroke-width:3"); - - for (typename std::vector::const_iterator it = intersection_output.begin(); - it != intersection_output.end(); ++it) - { - mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);" - "stroke:rgb(255,0,255);stroke-width:8"); - } - } -#endif - return length_or_area; } @@ -207,6 +158,54 @@ typename bg::default_area_result::type test_intersection(std::string const& check_result(intersection_output, caseid, expected_count, expected_point_count, expected_length_or_area, percentage, debug); +#if defined(TEST_WITH_SVG) + { + bool const is_line = bg::geometry_id::type::value == 2; + typedef typename bg::coordinate_type::type coordinate_type; + + bool const ccw = + bg::point_order::value == bg::counterclockwise + || bg::point_order::value == bg::counterclockwise; + bool const open = + bg::closure::value == bg::open + || bg::closure::value == bg::open; + + std::ostringstream filename; + filename << "intersection_" + << caseid << "_" + << string_from_type::name() + << string_from_type::name() + << (ccw ? "_ccw" : "") + << (open ? "_open" : "") +#if defined(BOOST_GEOMETRY_NO_ROBUSTNESS) + << "_no_rob" +#endif + << ".svg"; + + std::ofstream svg(filename.str().c_str()); + + bg::svg_mapper mapper(svg, 500, 500); + + mapper.add(g1); + mapper.add(g2); + + mapper.map(g1, is_line + ? "opacity:0.6;stroke:rgb(0,255,0);stroke-width:5" + : "fill-opacity:0.5;fill:rgb(153,204,0);" + "stroke:rgb(153,204,0);stroke-width:3"); + mapper.map(g2, "fill-opacity:0.3;fill:rgb(51,51,153);" + "stroke:rgb(51,51,153);stroke-width:3"); + + for (typename std::vector::const_iterator it = intersection_output.begin(); + it != intersection_output.end(); ++it) + { + mapper.map(*it, "fill-opacity:0.2;stroke-opacity:0.4;fill:rgb(255,0,0);" + "stroke:rgb(255,0,255);stroke-width:8"); + } + } +#endif + + if (debug) { std::cout << "end case " << caseid << std::endl;