From 43538e5f240f04c2e37cb5bb0dcbc8b94c26e3c2 Mon Sep 17 00:00:00 2001 From: Phillip Palk Date: Thu, 7 Jun 2018 10:07:33 +1000 Subject: [PATCH 01/11] [test][iterators] add test case that demonstrates SEGFAULT when using closing_iterator and ever_circling_iterator with transformed ranges. --- test/iterators/closing_iterator.cpp | 33 ++++++++++++++ test/iterators/ever_circling_iterator.cpp | 54 +++++++++++++++++++++-- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/test/iterators/closing_iterator.cpp b/test/iterators/closing_iterator.cpp index 1221eb257..9ac43634b 100644 --- a/test/iterators/closing_iterator.cpp +++ b/test/iterators/closing_iterator.cpp @@ -26,6 +26,8 @@ #include #include +#include + // The closing iterator should also work on normal std:: containers void test_empty_non_geometry() @@ -73,6 +75,36 @@ void test_non_geometry() BOOST_CHECK_EQUAL(out.str(), "1231"); } +void test_transformed_non_geometry() +{ + std::vector v; + v.push_back(-1); + v.push_back(-2); + v.push_back(-3); + + typedef boost::transformed_range + < + std::negate, + std::vector + > transformed_range; + + typedef bg::closing_iterator + < + transformed_range const + > closing_iterator; + + transformed_range v2 = v | boost::adaptors::transformed(std::negate()); + closing_iterator it(v2); + closing_iterator end(v2, true); + + std::ostringstream out; + for (; it != end; ++it) + { + out << *it; + } + BOOST_CHECK_EQUAL(out.str(), "1231"); +} + @@ -129,6 +161,7 @@ void test_all() { test_empty_non_geometry(); test_non_geometry(); + test_transformed_non_geometry(); test_geometry >("POLYGON((1 1,1 4,4 4,4 1))"); } diff --git a/test/iterators/ever_circling_iterator.cpp b/test/iterators/ever_circling_iterator.cpp index 1e4c254fd..9789794ec 100644 --- a/test/iterators/ever_circling_iterator.cpp +++ b/test/iterators/ever_circling_iterator.cpp @@ -23,12 +23,14 @@ #include #include #include +#include + +#include + template -void test_geometry(std::string const& wkt) +void test_geometry(G const& geo) { - G geo; - bg::read_wkt(wkt, geo); typedef typename boost::range_iterator::type iterator_type; @@ -74,7 +76,7 @@ void test_geometry(std::string const& wkt) // Check the range_iterator-one { std::ostringstream out; - bg::ever_circling_range_iterator it(geo); + bg::ever_circling_range_iterator it(geo); for (std::size_t i = 0; i < n; ++i, ++it) { out << bg::get<0>(*it); @@ -83,10 +85,54 @@ void test_geometry(std::string const& wkt) } } +template +void test_geometry(std::string const& wkt) +{ + G geo; + bg::read_wkt(wkt, geo); + test_geometry(geo); +} + + +template +P transform_point(P const& p) +{ + P result; + bg::set<0>(result, bg::get<0>(p) + 1); + bg::set<1>(result, bg::get<1>(p) + 1); + return result; +} + +template +struct transformed_geometry_type +{ + typedef typename bg::point_type::type point_type; + typedef boost::transformed_range type; +}; + +template +void test_transformed_geometry(G const& geo) +{ + typedef typename bg::point_type::type point_type; + test_geometry(geo | boost::adaptors::transformed(&transform_point)); +} + +template +void test_transformed_geometry(std::string const& wkt) +{ + G geo; + bg::read_wkt(wkt, geo); + test_transformed_geometry(geo); +} + + +BOOST_GEOMETRY_REGISTER_LINESTRING(typename transformed_geometry_type< bg::model::linestring< bg::model::d2::point_xy > >::type) + template void test_all() { test_geometry >("linestring(1 1,2 2,3 3,4 4,5 5)"); + test_transformed_geometry >("linestring(0 0,1 1,2 2,3 3,4 4)"); } int test_main(int, char* []) From 1d7a38fbee98df430f60595bdd9be7ea802cc0a2 Mon Sep 17 00:00:00 2001 From: Phillip Palk Date: Thu, 7 Jun 2018 10:07:48 +1000 Subject: [PATCH 02/11] [iterators] fix return of a reference to a temporary object when using closing_iterator and ever_circling_iterator with transformed ranges. --- include/boost/geometry/iterators/closing_iterator.hpp | 7 +++++-- .../boost/geometry/iterators/ever_circling_iterator.hpp | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index a0ec6a5c9..f77c9342b 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -38,9 +38,12 @@ struct closing_iterator < closing_iterator, typename boost::range_value::type const, - boost::random_access_traversal_tag + boost::random_access_traversal_tag, + typename boost::range_reference::type const, + typename boost::range_difference::type > { + typedef typename boost::range_reference::type const reference_type; typedef typename boost::range_difference::type difference_type; /// Constructor including the range it is based on @@ -71,7 +74,7 @@ struct closing_iterator private: friend class boost::iterator_core_access; - inline typename boost::range_value::type const& dereference() const + inline reference_type dereference() const { return *m_iterator; } diff --git a/include/boost/geometry/iterators/ever_circling_iterator.hpp b/include/boost/geometry/iterators/ever_circling_iterator.hpp index 569688aac..f164250fd 100644 --- a/include/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/include/boost/geometry/iterators/ever_circling_iterator.hpp @@ -100,7 +100,9 @@ struct ever_circling_range_iterator < ever_circling_range_iterator, typename boost::range_value::type const, - boost::random_access_traversal_tag + boost::random_access_traversal_tag, + typename boost::range_reference::type const, + typename boost::range_difference::type > { /// Constructor including the range it is based on @@ -118,12 +120,13 @@ struct ever_circling_range_iterator , m_index(0) {} - typedef std::ptrdiff_t difference_type; + typedef typename boost::range_reference::type const reference_type; + typedef typename boost::range_difference::type difference_type; private: friend class boost::iterator_core_access; - inline typename boost::range_value::type const& dereference() const + inline reference_type dereference() const { return *m_iterator; } From 61679f4adcf2f43e07a8a14c0a3b0ad01fc8af25 Mon Sep 17 00:00:00 2001 From: Phillip Palk Date: Fri, 8 Jun 2018 08:18:01 +1000 Subject: [PATCH 03/11] [iterators] use the base type (iterator_facade) for the reference and difference_type typedefs inside closing_iterator and ever_circling_iterator. Also, fixed reference_type type name to be reference. --- .../geometry/iterators/closing_iterator.hpp | 17 ++++++++++++++--- .../iterators/ever_circling_iterator.hpp | 17 ++++++++++++++--- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index f77c9342b..fb6ea8a70 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -43,8 +43,19 @@ struct closing_iterator typename boost::range_difference::type > { - typedef typename boost::range_reference::type const reference_type; - typedef typename boost::range_difference::type difference_type; +private: + typedef boost::iterator_facade + < + closing_iterator, + typename boost::range_value::type const, + boost::random_access_traversal_tag, + typename boost::range_reference::type const, + typename boost::range_difference::type + > base_type; + +public: + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; /// Constructor including the range it is based on explicit inline closing_iterator(Range& range) @@ -74,7 +85,7 @@ struct closing_iterator private: friend class boost::iterator_core_access; - inline reference_type dereference() const + inline reference dereference() const { return *m_iterator; } diff --git a/include/boost/geometry/iterators/ever_circling_iterator.hpp b/include/boost/geometry/iterators/ever_circling_iterator.hpp index f164250fd..469432bd2 100644 --- a/include/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/include/boost/geometry/iterators/ever_circling_iterator.hpp @@ -105,6 +105,17 @@ struct ever_circling_range_iterator typename boost::range_difference::type > { +private: + typedef boost::iterator_facade + < + ever_circling_range_iterator, + typename boost::range_value::type const, + boost::random_access_traversal_tag, + typename boost::range_reference::type const, + typename boost::range_difference::type + > base_type; + +public: /// Constructor including the range it is based on explicit inline ever_circling_range_iterator(Range& range) : m_range(&range) @@ -120,13 +131,13 @@ struct ever_circling_range_iterator , m_index(0) {} - typedef typename boost::range_reference::type const reference_type; - typedef typename boost::range_difference::type difference_type; + typedef typename base_type::reference reference; + typedef typename base_type::difference_type difference_type; private: friend class boost::iterator_core_access; - inline reference_type dereference() const + inline reference dereference() const { return *m_iterator; } From 38c77cf4359b087f7059f296c15f4103b1eaaf1d Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Wed, 4 Jul 2018 14:52:41 +0300 Subject: [PATCH 04/11] [algorithms] Avoid normalization for boxes created by make_inverse --- .../algorithms/detail/envelope/box.hpp | 15 +- .../detail/envelope/range_of_boxes.hpp | 9 ++ .../algorithms/detail/expand/point.hpp | 147 ++++++++++-------- .../envelope_expand/expand_on_spheroid.cpp | 73 +++++++-- 4 files changed, 167 insertions(+), 77 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/envelope/box.hpp b/include/boost/geometry/algorithms/detail/envelope/box.hpp index 33b43da25..8f7110592 100644 --- a/include/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/box.hpp @@ -124,7 +124,20 @@ struct envelope_box_on_spheroid BoxOut& mbr, Strategy const&) { - BoxIn box_in_normalized = detail::return_normalized(box_in); + BoxIn box_in_normalized = box_in; + + typedef typename point_type::type point_type; + typedef typename coordinate_type::type bound_type; + + // normalize input box (except from special boxes come from make_inverse) + bound_type high = boost::numeric::bounds::highest(); + bound_type low = boost::numeric::bounds::lowest(); + + if (geometry::get<0, 0>(box_in) != high || geometry::get<0, 1>(box_in) != high + || geometry::get<1, 0>(box_in) != low || geometry::get<1, 1>(box_in) != low) + { + box_in_normalized = detail::return_normalized(box_in); + } envelope_indexed_box_on_spheroid < diff --git a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 9b9e2f85d..77fb87630 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -272,6 +272,15 @@ struct envelope_range_of_boxes it != boost::end(range_of_boxes); ++it) { + coordinate_type high = boost::numeric::bounds::highest(); + coordinate_type low = boost::numeric::bounds::lowest(); + + if (geometry::get<0, 0>(*it) == high && geometry::get<0, 1>(*it) == high + && geometry::get<1, 0>(*it) == low && geometry::get<1, 1>(*it) == low) + { + continue; + } + coordinate_type lat_min = geometry::get(*it); coordinate_type lat_max = geometry::get(*it); if (math::equals(lat_min, constants::max_latitude()) diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index 2d8b0feff..81592d146 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -43,6 +43,7 @@ #include +#include namespace boost { namespace geometry { @@ -112,95 +113,113 @@ struct point_loop_on_spheroid // normalize input point and input box Point p_normalized = detail::return_normalized(point); - detail::normalize(box, box); // transform input point to be of the same type as the box point box_point_type box_point; detail::envelope::transform_units(p_normalized, box_point); - box_coordinate_type p_lon = geometry::get<0>(box_point); - box_coordinate_type p_lat = geometry::get<1>(box_point); + // normalize input box (except from special boxes come from make_inverse) + box_coordinate_type high = boost::numeric::bounds::highest(); + box_coordinate_type low = boost::numeric::bounds::lowest(); - typename coordinate_type::type - b_lon_min = geometry::get(box), - b_lat_min = geometry::get(box), - b_lon_max = geometry::get(box), - b_lat_max = geometry::get(box); - - if (math::is_latitude_pole(p_lat)) + if (math::equals(geometry::get<0, 0>(box), high) + && math::equals(geometry::get<0, 1>(box), high) + && math::equals(geometry::get<1, 0>(box), low) + && math::equals(geometry::get<1, 1>(box), low)) { - // the point of expansion is the either the north or the - // south pole; the only important coordinate here is the - // pole's latitude, as the longitude can be anything; - // we, thus, take into account the point's latitude only and return - geometry::set(box, (std::min)(p_lat, b_lat_min)); - geometry::set(box, (std::max)(p_lat, b_lat_max)); - return; - } + geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); + geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); + geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); + geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); - if (math::equals(b_lat_min, b_lat_max) - && math::is_latitude_pole(b_lat_min)) - { - // the box degenerates to either the north or the south pole; - // the only important coordinate here is the pole's latitude, - // as the longitude can be anything; - // we thus take into account the box's latitude only and return - geometry::set(box, p_lon); - geometry::set(box, (std::min)(p_lat, b_lat_min)); - geometry::set(box, p_lon); - geometry::set(box, (std::max)(p_lat, b_lat_max)); - return; - } + } else { - // update latitudes - b_lat_min = (std::min)(b_lat_min, p_lat); - b_lat_max = (std::max)(b_lat_max, p_lat); + detail::normalize(box, box); - // update longitudes - if (math::smaller(p_lon, b_lon_min)) - { - box_coordinate_type p_lon_shifted = p_lon + constants::period(); + box_coordinate_type p_lon = geometry::get<0>(box_point); + box_coordinate_type p_lat = geometry::get<1>(box_point); - if (math::larger(p_lon_shifted, b_lon_max)) + typename coordinate_type::type + b_lon_min = geometry::get(box), + b_lat_min = geometry::get(box), + b_lon_max = geometry::get(box), + b_lat_max = geometry::get(box); + + if (math::is_latitude_pole(p_lat)) { - // here we could check using: ! math::larger(.., ..) - if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max)) + // the point of expansion is the either the north or the + // south pole; the only important coordinate here is the + // pole's latitude, as the longitude can be anything; + // we, thus, take into account the point's latitude only and return + geometry::set(box, (std::min)(p_lat, b_lat_min)); + geometry::set(box, (std::max)(p_lat, b_lat_max)); + return; + } + + if (math::equals(b_lat_min, b_lat_max) + && math::is_latitude_pole(b_lat_min)) + { + // the box degenerates to either the north or the south pole; + // the only important coordinate here is the pole's latitude, + // as the longitude can be anything; + // we thus take into account the box's latitude only and return + geometry::set(box, p_lon); + geometry::set(box, (std::min)(p_lat, b_lat_min)); + geometry::set(box, p_lon); + geometry::set(box, (std::max)(p_lat, b_lat_max)); + return; + } + + // update latitudes + b_lat_min = (std::min)(b_lat_min, p_lat); + b_lat_max = (std::max)(b_lat_max, p_lat); + + // update longitudes + if (math::smaller(p_lon, b_lon_min)) + { + box_coordinate_type p_lon_shifted = p_lon + constants::period(); + + if (math::larger(p_lon_shifted, b_lon_max)) + { + // here we could check using: ! math::larger(.., ..) + if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max)) + { + b_lon_min = p_lon; + } + else + { + b_lon_max = p_lon_shifted; + } + } + } + else if (math::larger(p_lon, b_lon_max)) + { + // in this case, and since p_lon is normalized in the range + // (-180, 180], we must have that b_lon_max <= 180 + if (b_lon_min < 0 + && math::larger(p_lon - b_lon_max, + constants::period() - p_lon + b_lon_min)) { b_lon_min = p_lon; + b_lon_max += constants::period(); } else { - b_lon_max = p_lon_shifted; + b_lon_max = p_lon; } } - } - else if (math::larger(p_lon, b_lon_max)) - { - // in this case, and since p_lon is normalized in the range - // (-180, 180], we must have that b_lon_max <= 180 - if (b_lon_min < 0 - && math::larger(p_lon - b_lon_max, - constants::period() - p_lon + b_lon_min)) - { - b_lon_min = p_lon; - b_lon_max += constants::period(); - } - else - { - b_lon_max = p_lon; - } - } - geometry::set(box, b_lon_min); - geometry::set(box, b_lat_min); - geometry::set(box, b_lon_max); - geometry::set(box, b_lat_max); + geometry::set(box, b_lon_min); + geometry::set(box, b_lat_min); + geometry::set(box, b_lon_max); + geometry::set(box, b_lat_max); + } point_loop < 2, DimensionCount >::apply(box, point, strategy); - } + } }; diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index 1c535aa87..1f19f3d15 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -241,20 +241,36 @@ private: tolerance); other_mbr_type other_box; - bg::detail::indexed_point_view p_min(box); - bg::detail::indexed_point_view p_max(box); - bg::detail::indexed_point_view - < - other_mbr_type, 0 - > other_min(other_box); - bg::detail::indexed_point_view - < - other_mbr_type, 1 - > other_max(other_box); + //if the input box is the special one made from make_inverse + //do not convert coordinates + double high = boost::numeric::bounds::highest(); + double low = boost::numeric::bounds::lowest(); - bg::transform(p_min, other_min); - bg::transform(p_max, other_max); + if (bg::get<0, 0>(box) != high || bg::get<0, 1>(box) != high + || bg::get<1, 0>(box) != low || bg::get<1, 1>(box) != low) + { + bg::detail::indexed_point_view p_min(box); + bg::detail::indexed_point_view p_max(box); + + bg::detail::indexed_point_view + < + other_mbr_type, 0 + > other_min(other_box); + + bg::detail::indexed_point_view + < + other_mbr_type, 1 + > other_max(other_box); + + bg::transform(p_min, other_min); + bg::transform(p_max, other_max); + } else { + bg::set(other_box, bg::get<0, 0>(box)); + bg::set(other_box, bg::get<0, 1>(box)); + bg::set(other_box, bg::get<1, 0>(box)); + bg::set(other_box, bg::get<1, 1>(box)); + } base_test(case_id, other_box, geometry, other::convert(lon_min1), @@ -1043,6 +1059,39 @@ BOOST_AUTO_TEST_CASE( expand_box ) test_expand_box >(); } +template +void test_expand_make_inverse() +{ + typedef bg::model::point point_type; + typedef bg::model::box box_type; + typedef bg::model::segment segment_type; + typedef test_expand_on_spheroid tester; + + box_type box = boost::geometry::make_inverse(); + + tester::apply("bi01", + box, + from_wkt("BOX(10 10,20 20)"), + 10, 10, 20, 20); + tester::apply("bi02", + box, + from_wkt("POINT(0 0)"), + 0, 0, 0, 0); + tester::apply("bi03", + box, + from_wkt("POINT(5 0)"), + 5, 0, 5, 0); + tester::apply("bi04", + box, + from_wkt("SEGMENT(5 0,0 5)"), + 0, 0, 5, 5); +} + +BOOST_AUTO_TEST_CASE( expand_make_inverse ) +{ + test_expand_make_inverse >(); + test_expand_make_inverse >(); +} template void test_expand_box_with_height() From 5a0964886a2170b9e83155260a86341e353ee829 Mon Sep 17 00:00:00 2001 From: Phillip Palk Date: Thu, 5 Jul 2018 23:07:36 +1000 Subject: [PATCH 05/11] [iterators] fix calculation of range's const reference type inside closing_iterator and ever_circling_iterator. --- include/boost/geometry/iterators/closing_iterator.hpp | 4 ++-- include/boost/geometry/iterators/ever_circling_iterator.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/iterators/closing_iterator.hpp b/include/boost/geometry/iterators/closing_iterator.hpp index fb6ea8a70..1477ea6e2 100644 --- a/include/boost/geometry/iterators/closing_iterator.hpp +++ b/include/boost/geometry/iterators/closing_iterator.hpp @@ -39,7 +39,7 @@ struct closing_iterator closing_iterator, typename boost::range_value::type const, boost::random_access_traversal_tag, - typename boost::range_reference::type const, + typename boost::range_reference::type, typename boost::range_difference::type > { @@ -49,7 +49,7 @@ private: closing_iterator, typename boost::range_value::type const, boost::random_access_traversal_tag, - typename boost::range_reference::type const, + typename boost::range_reference::type, typename boost::range_difference::type > base_type; diff --git a/include/boost/geometry/iterators/ever_circling_iterator.hpp b/include/boost/geometry/iterators/ever_circling_iterator.hpp index 469432bd2..4d72bed2c 100644 --- a/include/boost/geometry/iterators/ever_circling_iterator.hpp +++ b/include/boost/geometry/iterators/ever_circling_iterator.hpp @@ -101,7 +101,7 @@ struct ever_circling_range_iterator ever_circling_range_iterator, typename boost::range_value::type const, boost::random_access_traversal_tag, - typename boost::range_reference::type const, + typename boost::range_reference::type, typename boost::range_difference::type > { @@ -111,7 +111,7 @@ private: ever_circling_range_iterator, typename boost::range_value::type const, boost::random_access_traversal_tag, - typename boost::range_reference::type const, + typename boost::range_reference::type, typename boost::range_difference::type > base_type; From 7072ef0212110db835a6f9c094b6bff053a18b75 Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Fri, 6 Jul 2018 16:03:56 +0300 Subject: [PATCH 06/11] [util] Use is_inverse utility to detect inverse boxes --- .../algorithms/detail/assign_values.hpp | 5 ++- .../algorithms/detail/envelope/box.hpp | 10 +---- .../detail/envelope/range_of_boxes.hpp | 6 +-- .../algorithms/detail/expand/point.hpp | 10 +---- include/boost/geometry/util/is_inverse.hpp | 43 +++++++++++++++++++ .../envelope_expand/expand_on_spheroid.cpp | 6 +-- 6 files changed, 51 insertions(+), 29 deletions(-) create mode 100644 include/boost/geometry/util/is_inverse.hpp diff --git a/include/boost/geometry/algorithms/detail/assign_values.hpp b/include/boost/geometry/algorithms/detail/assign_values.hpp index ef5691e97..85cd2d15c 100644 --- a/include/boost/geometry/algorithms/detail/assign_values.hpp +++ b/include/boost/geometry/algorithms/detail/assign_values.hpp @@ -34,6 +34,7 @@ #include +#include #include @@ -86,10 +87,10 @@ struct assign_inverse_box_or_segment typedef typename coordinate_type::type bound_type; initialize<0, 0, dimension::type::value>::apply( - geometry, boost::numeric::bounds::highest() + geometry, geometry::bounds::highest() ); initialize<1, 0, dimension::type::value>::apply( - geometry, boost::numeric::bounds::lowest() + geometry, geometry::bounds::lowest() ); } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/box.hpp b/include/boost/geometry/algorithms/detail/envelope/box.hpp index 8f7110592..8fb49043a 100644 --- a/include/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/box.hpp @@ -126,15 +126,7 @@ struct envelope_box_on_spheroid { BoxIn box_in_normalized = box_in; - typedef typename point_type::type point_type; - typedef typename coordinate_type::type bound_type; - - // normalize input box (except from special boxes come from make_inverse) - bound_type high = boost::numeric::bounds::highest(); - bound_type low = boost::numeric::bounds::lowest(); - - if (geometry::get<0, 0>(box_in) != high || geometry::get<0, 1>(box_in) != high - || geometry::get<1, 0>(box_in) != low || geometry::get<1, 1>(box_in) != low) + if (!is_inverse(box_in)) { box_in_normalized = detail::return_normalized(box_in); } diff --git a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 77fb87630..907f1a0bc 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -272,11 +272,7 @@ struct envelope_range_of_boxes it != boost::end(range_of_boxes); ++it) { - coordinate_type high = boost::numeric::bounds::highest(); - coordinate_type low = boost::numeric::bounds::lowest(); - - if (geometry::get<0, 0>(*it) == high && geometry::get<0, 1>(*it) == high - && geometry::get<1, 0>(*it) == low && geometry::get<1, 1>(*it) == low) + if (is_inverse(*it)) { continue; } diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index 81592d146..5e57dc1a0 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -35,6 +35,7 @@ #include #include +#include #include #include @@ -118,14 +119,7 @@ struct point_loop_on_spheroid box_point_type box_point; detail::envelope::transform_units(p_normalized, box_point); - // normalize input box (except from special boxes come from make_inverse) - box_coordinate_type high = boost::numeric::bounds::highest(); - box_coordinate_type low = boost::numeric::bounds::lowest(); - - if (math::equals(geometry::get<0, 0>(box), high) - && math::equals(geometry::get<0, 1>(box), high) - && math::equals(geometry::get<1, 0>(box), low) - && math::equals(geometry::get<1, 1>(box), low)) + if (is_inverse(box)) { geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); diff --git a/include/boost/geometry/util/is_inverse.hpp b/include/boost/geometry/util/is_inverse.hpp new file mode 100644 index 000000000..3b1fed91c --- /dev/null +++ b/include/boost/geometry/util/is_inverse.hpp @@ -0,0 +1,43 @@ +// Boost.Geometry + +// Copyright (c) 2018 Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, 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_UTIL_IS_INVERSE_HPP +#define BOOST_GEOMETRY_UTIL_IS_INVERSE_HPP + +#include + +namespace boost { namespace geometry +{ + +template +struct bounds +{ + static CT lowest () { return boost::numeric::bounds::lowest(); } + static CT highest () { return boost::numeric::bounds::highest(); } +}; + +template +bool is_inverse(Box const& box) +{ + typedef typename point_type::type point_type; + typedef typename coordinate_type::type bound_type; + + bound_type high = bounds::highest(); + bound_type low = bounds::lowest(); + + return math::equals(geometry::get<0, 0>(box), high) && + math::equals(geometry::get<0, 1>(box), high) && + math::equals(geometry::get<1, 0>(box), low) && + math::equals(geometry::get<1, 1>(box), low); +} + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_UTIL_IS_INVERSE_HPP diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index 1f19f3d15..d80579c32 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -244,11 +244,7 @@ private: //if the input box is the special one made from make_inverse //do not convert coordinates - double high = boost::numeric::bounds::highest(); - double low = boost::numeric::bounds::lowest(); - - if (bg::get<0, 0>(box) != high || bg::get<0, 1>(box) != high - || bg::get<1, 0>(box) != low || bg::get<1, 1>(box) != low) + if (!is_inverse(box)) { bg::detail::indexed_point_view p_min(box); bg::detail::indexed_point_view p_max(box); From 9efcb83bb367daa10d2ced438280749aeed4531f Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Fri, 6 Jul 2018 16:08:01 +0300 Subject: [PATCH 07/11] [algorithms] [tests] Move include for make.hpp to correct place --- include/boost/geometry/algorithms/detail/expand/point.hpp | 2 -- test/algorithms/envelope_expand/expand_on_spheroid.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index 5e57dc1a0..e09a3e59e 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -44,8 +44,6 @@ #include -#include - namespace boost { namespace geometry { diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index d80579c32..7100a563f 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include "test_envelope_expand_on_spheroid.hpp" From 65084bb854141cdb7ee121fe19fb1e8026dfeb59 Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Fri, 6 Jul 2018 16:43:43 +0300 Subject: [PATCH 08/11] [util] Use exact coordinate check for inverse box --- include/boost/geometry/util/is_inverse.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/util/is_inverse.hpp b/include/boost/geometry/util/is_inverse.hpp index 3b1fed91c..833d78f38 100644 --- a/include/boost/geometry/util/is_inverse.hpp +++ b/include/boost/geometry/util/is_inverse.hpp @@ -32,10 +32,10 @@ bool is_inverse(Box const& box) bound_type high = bounds::highest(); bound_type low = bounds::lowest(); - return math::equals(geometry::get<0, 0>(box), high) && - math::equals(geometry::get<0, 1>(box), high) && - math::equals(geometry::get<1, 0>(box), low) && - math::equals(geometry::get<1, 1>(box), low); + return (geometry::get<0, 0>(box) == high) && + (geometry::get<0, 1>(box) == high) && + (geometry::get<1, 0>(box) == low) && + (geometry::get<1, 1>(box) == low); } }} // namespace boost::geometry From f04c25f43d8ae7669a1c5dd10e6c06b4232e781e Mon Sep 17 00:00:00 2001 From: Vissarion Fysikopoulos Date: Mon, 9 Jul 2018 12:58:34 +0300 Subject: [PATCH 09/11] [algorithms] [util] Rename is_inverse utility and update copyright notes --- .../boost/geometry/algorithms/detail/assign_values.hpp | 7 ++++++- include/boost/geometry/algorithms/detail/envelope/box.hpp | 6 +++--- .../algorithms/detail/envelope/range_of_boxes.hpp | 4 ++-- include/boost/geometry/algorithms/detail/expand/point.hpp | 8 ++++---- ..._inverse.hpp => is_inverse_spheroidal_coordinates.hpp} | 8 ++++---- test/algorithms/envelope_expand/expand_on_spheroid.cpp | 4 ++-- 6 files changed, 21 insertions(+), 16 deletions(-) rename include/boost/geometry/util/{is_inverse.hpp => is_inverse_spheroidal_coordinates.hpp} (80%) diff --git a/include/boost/geometry/algorithms/detail/assign_values.hpp b/include/boost/geometry/algorithms/detail/assign_values.hpp index 85cd2d15c..0821de32e 100644 --- a/include/boost/geometry/algorithms/detail/assign_values.hpp +++ b/include/boost/geometry/algorithms/detail/assign_values.hpp @@ -7,6 +7,11 @@ // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Vissarion Fysikopoulos, 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) @@ -34,7 +39,7 @@ #include -#include +#include #include diff --git a/include/boost/geometry/algorithms/detail/envelope/box.hpp b/include/boost/geometry/algorithms/detail/envelope/box.hpp index 8fb49043a..cf039a292 100644 --- a/include/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/box.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -126,7 +126,7 @@ struct envelope_box_on_spheroid { BoxIn box_in_normalized = box_in; - if (!is_inverse(box_in)) + if (!is_inverse_spheroidal_coordinates(box_in)) { box_in_normalized = detail::return_normalized(box_in); } diff --git a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 907f1a0bc..92d1fe395 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015-2017, Oracle and/or its affiliates. +// Copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -272,7 +272,7 @@ struct envelope_range_of_boxes it != boost::end(range_of_boxes); ++it) { - if (is_inverse(*it)) + if (is_inverse_spheroidal_coordinates(*it)) { continue; } diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index e09a3e59e..88ebe75db 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2015, 2016, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015-2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -35,7 +35,7 @@ #include #include -#include +#include #include #include @@ -117,7 +117,7 @@ struct point_loop_on_spheroid box_point_type box_point; detail::envelope::transform_units(p_normalized, box_point); - if (is_inverse(box)) + if (is_inverse_spheroidal_coordinates(box)) { geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); diff --git a/include/boost/geometry/util/is_inverse.hpp b/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp similarity index 80% rename from include/boost/geometry/util/is_inverse.hpp rename to include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp index 833d78f38..d67251254 100644 --- a/include/boost/geometry/util/is_inverse.hpp +++ b/include/boost/geometry/util/is_inverse_spheroidal_coordinates.hpp @@ -8,8 +8,8 @@ // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) -#ifndef BOOST_GEOMETRY_UTIL_IS_INVERSE_HPP -#define BOOST_GEOMETRY_UTIL_IS_INVERSE_HPP +#ifndef BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP +#define BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP #include @@ -24,7 +24,7 @@ struct bounds }; template -bool is_inverse(Box const& box) +bool is_inverse_spheroidal_coordinates(Box const& box) { typedef typename point_type::type point_type; typedef typename coordinate_type::type bound_type; @@ -40,4 +40,4 @@ bool is_inverse(Box const& box) }} // namespace boost::geometry -#endif // BOOST_GEOMETRY_UTIL_IS_INVERSE_HPP +#endif // BOOST_GEOMETRY_UTIL_IS_INVERSE_SPHEROIDAL_COORDINATES_HPP diff --git a/test/algorithms/envelope_expand/expand_on_spheroid.cpp b/test/algorithms/envelope_expand/expand_on_spheroid.cpp index 7100a563f..b192cf7e7 100644 --- a/test/algorithms/envelope_expand/expand_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/expand_on_spheroid.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015-2017, Oracle and/or its affiliates. +// Copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -245,7 +245,7 @@ private: //if the input box is the special one made from make_inverse //do not convert coordinates - if (!is_inverse(box)) + if (!is_inverse_spheroidal_coordinates(box)) { bg::detail::indexed_point_view p_min(box); bg::detail::indexed_point_view p_max(box); From 84d08d69362028ed6befa86ac5056b7d4001749d Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 11 Jul 2018 14:56:14 +0200 Subject: [PATCH 10/11] [test][iterators] Remove typename keyword. --- test/iterators/ever_circling_iterator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/iterators/ever_circling_iterator.cpp b/test/iterators/ever_circling_iterator.cpp index 9789794ec..835a7b5a3 100644 --- a/test/iterators/ever_circling_iterator.cpp +++ b/test/iterators/ever_circling_iterator.cpp @@ -126,7 +126,7 @@ void test_transformed_geometry(std::string const& wkt) } -BOOST_GEOMETRY_REGISTER_LINESTRING(typename transformed_geometry_type< bg::model::linestring< bg::model::d2::point_xy > >::type) +BOOST_GEOMETRY_REGISTER_LINESTRING(transformed_geometry_type< bg::model::linestring< bg::model::d2::point_xy > >::type) template void test_all() From ec7ac6df00195dbe7ba88022118276623cba972a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Wed, 11 Jul 2018 15:05:21 +0200 Subject: [PATCH 11/11] [test][strategies] Remove unused variable. --- test/strategies/segment_intersection_geo.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/strategies/segment_intersection_geo.cpp b/test/strategies/segment_intersection_geo.cpp index c0f275abf..e0ab9f6af 100644 --- a/test/strategies/segment_intersection_geo.cpp +++ b/test/strategies/segment_intersection_geo.cpp @@ -407,7 +407,6 @@ void test_geographic_radian() typedef bg::model::point > point_t; typedef bg::model::segment segment_t; - T const d2r = bg::math::d2r(); bg::strategy::intersection::geographic_segments strategy; // https://github.com/boostorg/geometry/issues/470