From 0be273f605b5f4d1f176b00bf0b28a6b85b72eda Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 02:27:55 +0200 Subject: [PATCH 01/35] [core][geometries][srs] Add cs::undefined and detail::cs_angular_units. Remove is_radian and units typedef from non-cartesian cs structs. --- include/boost/geometry/core/cs.hpp | 163 +++++++++++++----- include/boost/geometry/core/tags.hpp | 7 +- .../geometry/geometries/helper_geometry.hpp | 59 +------ include/boost/geometry/srs/transformation.hpp | 12 +- 4 files changed, 128 insertions(+), 113 deletions(-) diff --git a/include/boost/geometry/core/cs.hpp b/include/boost/geometry/core/cs.hpp index 301fb6b76..c39eec3d4 100644 --- a/include/boost/geometry/core/cs.hpp +++ b/include/boost/geometry/core/cs.hpp @@ -4,10 +4,11 @@ // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// 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. @@ -22,7 +23,6 @@ #include #include -#include #include #include @@ -56,7 +56,7 @@ namespace core_detail { template -struct coordinate_system_units +struct define_angular_units { BOOST_MPL_ASSERT_MSG ((false), @@ -65,13 +65,13 @@ struct coordinate_system_units }; template <> -struct coordinate_system_units +struct define_angular_units { typedef geometry::degree units; }; template <> -struct coordinate_system_units +struct define_angular_units { typedef geometry::radian units; }; @@ -107,12 +107,8 @@ known as lat,long or lo,la or phi,lambda */ template struct geographic -{ - typedef typename core_detail::coordinate_system_units - < - DegreeOrRadian - >::units units; -}; + : core_detail::define_angular_units +{}; @@ -136,12 +132,8 @@ struct geographic */ template struct spherical -{ - typedef typename core_detail::coordinate_system_units - < - DegreeOrRadian - >::units units; -}; + : core_detail::define_angular_units +{}; /*! @@ -156,12 +148,8 @@ struct spherical */ template struct spherical_equatorial -{ - typedef typename core_detail::coordinate_system_units - < - DegreeOrRadian - >::units units; -}; + : core_detail::define_angular_units +{}; @@ -174,12 +162,15 @@ struct spherical_equatorial */ template struct polar -{ - typedef typename core_detail::coordinate_system_units - < - DegreeOrRadian - >::units units; -}; + : core_detail::define_angular_units +{}; + + +/*! +\brief Undefined coordinate system +\ingroup cs +*/ +struct undefined {}; } // namespace cs @@ -227,9 +218,18 @@ struct cs_tag }; +template <> +struct cs_tag +{ + typedef cs_undefined_tag type; +}; + #endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + } // namespace traits + /*! \brief Meta-function returning coordinate system tag (cs family) of any geometry \tparam Geometry \tparam_geometry @@ -245,24 +245,97 @@ struct cs_tag }; -/*! -\brief Meta-function to verify if a coordinate system is radian -\tparam CoordinateSystem Any coordinate system. -\ingroup core -*/ -template -struct is_radian : boost::true_type {}; - - -#ifndef DOXYGEN_NO_SPECIALIZATIONS - -// Specialization for any degree coordinate systems -template class CoordinateSystem> -struct is_radian< CoordinateSystem > : boost::false_type +namespace traits { + +// cartesian or undefined +template +struct cs_angular_units +{ + typedef geometry::radian type; }; -#endif // DOXYGEN_NO_SPECIALIZATIONS +#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS + +template +struct cs_angular_units > +{ + typedef DegreeOrRadian type; +}; + +template +struct cs_angular_units > +{ + typedef DegreeOrRadian type; +}; + +template +struct cs_angular_units > +{ + typedef DegreeOrRadian type; +}; + +#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS + + +} // namespace traits + + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +struct cs_angular_units +{ + typedef typename traits::cs_angular_units + < + typename geometry::coordinate_system::type + >::type type; +}; + + +template +struct cs_tag_to_coordinate_system +{ + BOOST_MPL_ASSERT_MSG((false), + NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM, + (types)); +}; + +template +struct cs_tag_to_coordinate_system +{ + typedef cs::undefined type; +}; + +template +struct cs_tag_to_coordinate_system +{ + typedef cs::cartesian type; +}; + +template +struct cs_tag_to_coordinate_system +{ + typedef cs::spherical_equatorial type; +}; + +template +struct cs_tag_to_coordinate_system +{ + typedef cs::spherical type; +}; + +template +struct cs_tag_to_coordinate_system +{ + typedef cs::geographic type; +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + }} // namespace boost::geometry diff --git a/include/boost/geometry/core/tags.hpp b/include/boost/geometry/core/tags.hpp index 5d6acb187..f5bebbacb 100644 --- a/include/boost/geometry/core/tags.hpp +++ b/include/boost/geometry/core/tags.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -25,6 +25,9 @@ namespace boost { namespace geometry // Tags defining strategies linked to coordinate systems +/// Tag used for undefined coordinate system +struct cs_undefined_tag {}; + /// Tag used for casting spherical/geographic coordinate systems struct spherical_tag {}; diff --git a/include/boost/geometry/geometries/helper_geometry.hpp b/include/boost/geometry/geometries/helper_geometry.hpp index f3102fee9..e110dd2b1 100644 --- a/include/boost/geometry/geometries/helper_geometry.hpp +++ b/include/boost/geometry/geometries/helper_geometry.hpp @@ -32,60 +32,6 @@ namespace boost { namespace geometry namespace detail { namespace helper_geometries { -template ::type> -struct default_units -{ - typedef typename coordinate_system::type::units type; -}; - -// The Cartesian coordinate system does not define the type units. -// For that reason the generic implementation for default_units cannot be used -// and specialization needs to be defined. -// Moreover, it makes sense to define the units for the Cartesian -// coordinate system to be radians, as this way a Cartesian point can -// potentially be used in algorithms taking non-Cartesian strategies -// and work as if it was as point in the non-Cartesian coordinate -// system with radian units. -template -struct default_units -{ - typedef radian type; -}; - - -template -struct cs_tag_to_coordinate_system -{ - BOOST_MPL_ASSERT_MSG((false), - NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM, - (types)); -}; - -template -struct cs_tag_to_coordinate_system -{ - typedef cs::cartesian type; -}; - -template -struct cs_tag_to_coordinate_system -{ - typedef cs::spherical_equatorial type; -}; - -template -struct cs_tag_to_coordinate_system -{ - typedef cs::spherical type; -}; - -template -struct cs_tag_to_coordinate_system -{ - typedef cs::geographic type; -}; - - template < typename Point, @@ -154,10 +100,7 @@ template < typename Geometry, typename NewCoordinateType = typename coordinate_type::type, - typename NewUnits = typename detail::helper_geometries::default_units - < - Geometry - >::type + typename NewUnits = typename detail::cs_angular_units::type > struct helper_geometry { diff --git a/include/boost/geometry/srs/transformation.hpp b/include/boost/geometry/srs/transformation.hpp index 2b1351b65..3a999936c 100644 --- a/include/boost/geometry/srs/transformation.hpp +++ b/include/boost/geometry/srs/transformation.hpp @@ -59,15 +59,11 @@ template < typename PtIn, typename PtOut, - bool SameUnits = geometry::is_radian + bool SameUnits = boost::is_same < - typename geometry::coordinate_system::type - >::type::value - == - geometry::is_radian - < - typename geometry::coordinate_system::type - >::type::value + typename geometry::detail::cs_angular_units::type, + typename geometry::detail::cs_angular_units::type + >::value > struct transform_geometry_point_coordinates { From 96115158d3555c798b20f30ab59df02186c13c47 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 02:36:37 +0200 Subject: [PATCH 02/35] [area][distance] Dispatch on struct level by strategy at resolve_strategy step. --- include/boost/geometry/algorithms/area.hpp | 9 +++++++-- .../algorithms/detail/distance/interface.hpp | 18 +++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/algorithms/area.hpp b/include/boost/geometry/algorithms/area.hpp index c6e237e7c..6776c09ba 100644 --- a/include/boost/geometry/algorithms/area.hpp +++ b/include/boost/geometry/algorithms/area.hpp @@ -215,15 +215,20 @@ struct area : detail::multi_sum namespace resolve_strategy { +template struct area { - template + template static inline typename area_result::type apply(Geometry const& geometry, Strategy const& strategy) { return dispatch::area::apply(geometry, strategy); } +}; +template <> +struct area +{ template static inline typename area_result::type apply(Geometry const& geometry, default_strategy) @@ -251,7 +256,7 @@ struct area static inline typename area_result::type apply(Geometry const& geometry, Strategy const& strategy) { - return resolve_strategy::area::apply(geometry, strategy); + return resolve_strategy::area::apply(geometry, strategy); } }; diff --git a/include/boost/geometry/algorithms/detail/distance/interface.hpp b/include/boost/geometry/algorithms/detail/distance/interface.hpp index 53d24d992..ec6685058 100644 --- a/include/boost/geometry/algorithms/detail/distance/interface.hpp +++ b/include/boost/geometry/algorithms/detail/distance/interface.hpp @@ -6,10 +6,11 @@ // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. // Copyright (c) 2014 Samuel Debionne, Grenoble, France. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// 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. @@ -94,9 +95,10 @@ struct distance namespace resolve_strategy { +template struct distance { - template + template static inline typename distance_result::type apply(Geometry1 const& geometry1, Geometry2 const& geometry2, @@ -107,7 +109,11 @@ struct distance Geometry1, Geometry2, Strategy >::apply(geometry1, geometry2, strategy); } +}; +template <> +struct distance +{ template static inline typename distance_result::type @@ -143,8 +149,10 @@ struct distance Geometry2 const& geometry2, Strategy const& strategy) { - return - resolve_strategy::distance::apply(geometry1, geometry2, strategy); + return resolve_strategy::distance + < + Strategy + >::apply(geometry1, geometry2, strategy); } }; From 5b6651d588a2d35ffe2909ebbaac04242e4a8c0c Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 02:58:53 +0200 Subject: [PATCH 03/35] [formulas] Fix coordinates comparison warning. --- include/boost/geometry/formulas/spherical.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/formulas/spherical.hpp b/include/boost/geometry/formulas/spherical.hpp index 5599cd6e8..862600232 100644 --- a/include/boost/geometry/formulas/spherical.hpp +++ b/include/boost/geometry/formulas/spherical.hpp @@ -183,6 +183,7 @@ inline T spherical_azimuth(T const& lon1, T const& lat1, T const& lon2, T const& template inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2) { + T const c0 = 0; T const pi = math::pi(); T const two_pi = math::two_pi(); @@ -213,7 +214,7 @@ inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2) // the difference to 0 as well // positive azimuth is on the right side - return math::equals(a_diff, 0) + return math::equals(a_diff, c0) || math::equals(a_diff, pi) || math::equals(a_diff, -pi) ? 0 : a_diff > 0 ? -1 // right From 94c7c810aa3a88c9fafeac496bdc0e82c211e2d6 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:00:24 +0200 Subject: [PATCH 04/35] [normalize][strategies] Move CS-specific part of normalization code to strategies. --- .../geometry/algorithms/detail/normalize.hpp | 285 +----------------- .../boost/geometry/strategies/normalize.hpp | 268 ++++++++++++++++ 2 files changed, 277 insertions(+), 276 deletions(-) create mode 100644 include/boost/geometry/strategies/normalize.hpp diff --git a/include/boost/geometry/algorithms/detail/normalize.hpp b/include/boost/geometry/algorithms/detail/normalize.hpp index 7a761d42b..b53243f08 100644 --- a/include/boost/geometry/algorithms/detail/normalize.hpp +++ b/include/boost/geometry/algorithms/detail/normalize.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 Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -11,298 +11,31 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include +// For backward compatibility +#include namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace normalization -{ - - -struct do_nothing -{ - template - static inline void apply(GeometryIn const&, GeometryOut&) - { - } -}; - - -template -struct assign_loop -{ - template - static inline void apply(CoordinateType const& longitude, - CoordinateType const& latitude, - PointIn const& point_in, - PointOut& point_out) - { - geometry::set(point_out, boost::numeric_cast - < - typename coordinate_type::type - >(geometry::get(point_in))); - - assign_loop - < - Dimension + 1, DimensionCount - >::apply(longitude, latitude, point_in, point_out); - } -}; - -template -struct assign_loop -{ - template - static inline void apply(CoordinateType const&, - CoordinateType const&, - PointIn const&, - PointOut&) - { - } -}; - -template -struct assign_loop<0, DimensionCount> -{ - template - static inline void apply(CoordinateType const& longitude, - CoordinateType const& latitude, - PointIn const& point_in, - PointOut& point_out) - { - geometry::set<0>(point_out, boost::numeric_cast - < - typename coordinate_type::type - >(longitude)); - - assign_loop - < - 1, DimensionCount - >::apply(longitude, latitude, point_in, point_out); - } -}; - -template -struct assign_loop<1, DimensionCount> -{ - template - static inline void apply(CoordinateType const& longitude, - CoordinateType const& latitude, - PointIn const& point_in, - PointOut& point_out) - { - geometry::set<1>(point_out, boost::numeric_cast - < - typename coordinate_type::type - >(latitude)); - - assign_loop - < - 2, DimensionCount - >::apply(longitude, latitude, point_in, point_out); - } -}; - - -template -struct normalize_point -{ - static inline void apply(PointIn const& point_in, PointOut& point_out) - { - typedef typename coordinate_type::type in_coordinate_type; - - in_coordinate_type longitude = geometry::get<0>(point_in); - in_coordinate_type latitude = geometry::get<1>(point_in); - - math::normalize_spheroidal_coordinates - < - typename coordinate_system::type::units, - IsEquatorial, - in_coordinate_type - >(longitude, latitude); - - assign_loop - < - 0, dimension::value - >::apply(longitude, latitude, point_in, point_out); - } -}; - - -template -class normalize_box -{ - template - static inline void apply_to_coordinates(CoordinateInType& lon_min, - CoordinateInType& lat_min, - CoordinateInType& lon_max, - CoordinateInType& lat_max, - BoxIn const& box_in, - BoxOut& box_out) - { - detail::indexed_point_view p_min_out(box_out); - assign_loop - < - 0, dimension::value - >::apply(lon_min, - lat_min, - detail::indexed_point_view - < - BoxIn const, min_corner - >(box_in), - p_min_out); - - detail::indexed_point_view p_max_out(box_out); - assign_loop - < - 0, dimension::value - >::apply(lon_max, - lat_max, - detail::indexed_point_view - < - BoxIn const, max_corner - >(box_in), - p_max_out); - } - -public: - static inline void apply(BoxIn const& box_in, BoxOut& box_out) - { - typedef typename coordinate_type::type in_coordinate_type; - - in_coordinate_type lon_min = geometry::get(box_in); - in_coordinate_type lat_min = geometry::get(box_in); - in_coordinate_type lon_max = geometry::get(box_in); - in_coordinate_type lat_max = geometry::get(box_in); - - math::normalize_spheroidal_box_coordinates - < - typename coordinate_system::type::units, - IsEquatorial, - in_coordinate_type - >(lon_min, lat_min, lon_max, lat_max); - - apply_to_coordinates - < - typename coordinate_system::type::units, - typename coordinate_system::type::units - >(lon_min, lat_min, lon_max, lat_max, box_in, box_out); - } -}; - - -}} // namespace detail::normalization -#endif // DOXYGEN_NO_DETAIL - -#ifndef DOXYGEN_NO_DISPATCH -namespace dispatch -{ - -template -< - typename GeometryIn, - typename GeometryOut, - typename TagIn = typename tag::type, - typename TagOut = typename tag::type, - typename CSTagIn = typename cs_tag::type, - typename CSTagOut = typename cs_tag::type -> -struct normalize : detail::normalization::do_nothing -{}; - - -template -struct normalize - < - PointIn, PointOut, point_tag, point_tag, - spherical_equatorial_tag, spherical_equatorial_tag - > : detail::normalization::normalize_point -{}; - - -template -struct normalize - < - PointIn, PointOut, point_tag, point_tag, - spherical_polar_tag, spherical_polar_tag - > : detail::normalization::normalize_point -{}; - - -template -struct normalize - < - PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag - > : detail::normalization::normalize_point -{}; - - -template -struct normalize - < - BoxIn, BoxOut, box_tag, box_tag, - spherical_equatorial_tag, spherical_equatorial_tag - > : detail::normalization::normalize_box -{}; - - -template -struct normalize - < - BoxIn, BoxOut, box_tag, box_tag, - spherical_polar_tag, spherical_polar_tag - > : detail::normalization::normalize_box -{}; - - -template -struct normalize - < - BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag - > : detail::normalization::normalize_box -{}; - - -} // namespace dispatch -#endif // DOXYGEN_NO_DISPATCH - #ifndef DOXYGEN_NO_DETAIL namespace detail { -template -inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out) +template +inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out, Strategy const& ) { - dispatch::normalize - < - GeometryIn, GeometryOut - >::apply(geometry_in, geometry_out); + Strategy::apply(geometry_in, geometry_out); } -template -inline GeometryOut return_normalized(GeometryIn const& geometry_in) +template +inline GeometryOut return_normalized(GeometryIn const& geometry_in, Strategy const& strategy) { GeometryOut geometry_out; - detail::normalize(geometry_in, geometry_out); + detail::normalize(geometry_in, geometry_out, strategy); return geometry_out; } diff --git a/include/boost/geometry/strategies/normalize.hpp b/include/boost/geometry/strategies/normalize.hpp new file mode 100644 index 000000000..1887c1e63 --- /dev/null +++ b/include/boost/geometry/strategies/normalize.hpp @@ -0,0 +1,268 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2015-2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Licensed under the Boost Software License version 1.0. +// http://www.boost.org/users/license.html + +#ifndef BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP +#define BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace normalize +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +struct do_nothing +{ + template + static inline void apply(GeometryIn const&, GeometryOut&) + { + } +}; + + +template +struct assign_loop +{ + template + static inline void apply(CoordinateType const& longitude, + CoordinateType const& latitude, + PointIn const& point_in, + PointOut& point_out) + { + geometry::set(point_out, boost::numeric_cast + < + typename coordinate_type::type + >(geometry::get(point_in))); + + assign_loop + < + Dimension + 1, DimensionCount + >::apply(longitude, latitude, point_in, point_out); + } +}; + +template +struct assign_loop +{ + template + static inline void apply(CoordinateType const&, + CoordinateType const&, + PointIn const&, + PointOut&) + { + } +}; + +template +struct assign_loop<0, DimensionCount> +{ + template + static inline void apply(CoordinateType const& longitude, + CoordinateType const& latitude, + PointIn const& point_in, + PointOut& point_out) + { + geometry::set<0>(point_out, boost::numeric_cast + < + typename coordinate_type::type + >(longitude)); + + assign_loop + < + 1, DimensionCount + >::apply(longitude, latitude, point_in, point_out); + } +}; + +template +struct assign_loop<1, DimensionCount> +{ + template + static inline void apply(CoordinateType const& longitude, + CoordinateType const& latitude, + PointIn const& point_in, + PointOut& point_out) + { + geometry::set<1>(point_out, boost::numeric_cast + < + typename coordinate_type::type + >(latitude)); + + assign_loop + < + 2, DimensionCount + >::apply(longitude, latitude, point_in, point_out); + } +}; + + +template +struct normalize_point +{ + static inline void apply(PointIn const& point_in, PointOut& point_out) + { + typedef typename coordinate_type::type in_coordinate_type; + + in_coordinate_type longitude = geometry::get<0>(point_in); + in_coordinate_type latitude = geometry::get<1>(point_in); + + math::normalize_spheroidal_coordinates + < + typename geometry::detail::cs_angular_units::type, + IsEquatorial, + in_coordinate_type + >(longitude, latitude); + + assign_loop + < + 0, dimension::value + >::apply(longitude, latitude, point_in, point_out); + } +}; + + +template +class normalize_box +{ + template + static inline void apply_to_coordinates(CoordinateInType& lon_min, + CoordinateInType& lat_min, + CoordinateInType& lon_max, + CoordinateInType& lat_max, + BoxIn const& box_in, + BoxOut& box_out) + { + geometry::detail::indexed_point_view p_min_out(box_out); + assign_loop + < + 0, dimension::value + >::apply(lon_min, + lat_min, + geometry::detail::indexed_point_view + < + BoxIn const, min_corner + >(box_in), + p_min_out); + + geometry::detail::indexed_point_view p_max_out(box_out); + assign_loop + < + 0, dimension::value + >::apply(lon_max, + lat_max, + geometry::detail::indexed_point_view + < + BoxIn const, max_corner + >(box_in), + p_max_out); + } + +public: + static inline void apply(BoxIn const& box_in, BoxOut& box_out) + { + typedef typename coordinate_type::type in_coordinate_type; + + in_coordinate_type lon_min = geometry::get(box_in); + in_coordinate_type lat_min = geometry::get(box_in); + in_coordinate_type lon_max = geometry::get(box_in); + in_coordinate_type lat_max = geometry::get(box_in); + + math::normalize_spheroidal_box_coordinates + < + typename geometry::detail::cs_angular_units::type, + IsEquatorial, + in_coordinate_type + >(lon_min, lat_min, lon_max, lat_max); + + apply_to_coordinates + < + typename geometry::detail::cs_angular_units::type, + typename geometry::detail::cs_angular_units::type + >(lon_min, lat_min, lon_max, lat_max, box_in, box_out); + } +}; + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + +struct cartesian_point + : detail::do_nothing +{}; + +struct cartesian_box + : detail::do_nothing +{}; + +struct spherical_point +{ + template + static inline void apply(PointIn const& point_in, PointOut& point_out) + { + detail::normalize_point + < + PointIn, PointOut, + boost::mpl::not_ + < + boost::is_same + < + typename cs_tag::type, + spherical_polar_tag + > + >::value + >::apply(point_in, point_out); + } +}; + +struct spherical_box +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& box_out) + { + detail::normalize_box + < + BoxIn, BoxOut, + boost::mpl::not_ + < + boost::is_same + < + typename cs_tag::type, + spherical_polar_tag + > + >::value + >::apply(box_in, box_out); + } +}; + +}} // namespace strategy::normalize + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_NORMALIZE_HPP From 17017e43283b706a570894f6d87a8587863e6537 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:05:59 +0200 Subject: [PATCH 05/35] [envelope][expand][strategies] Move CS-specific code of envelope and expand to strategies. --- .../algorithms/detail/envelope/areal.hpp | 70 +--- .../algorithms/detail/envelope/box.hpp | 152 +------ .../algorithms/detail/envelope/interface.hpp | 31 +- .../algorithms/detail/envelope/linear.hpp | 77 +--- .../algorithms/detail/envelope/multipoint.hpp | 353 +--------------- .../algorithms/detail/envelope/point.hpp | 90 +---- .../algorithms/detail/envelope/range.hpp | 113 ++---- .../detail/envelope/range_of_boxes.hpp | 20 +- .../algorithms/detail/envelope/segment.hpp | 18 +- .../geometry/algorithms/detail/expand/box.hpp | 103 +---- .../algorithms/detail/expand/indexed.hpp | 24 +- .../algorithms/detail/expand/interface.hpp | 27 +- .../algorithms/detail/expand/point.hpp | 271 +------------ .../algorithms/detail/expand/segment.hpp | 118 +----- .../geometry/algorithms/dispatch/envelope.hpp | 8 +- .../geometry/algorithms/dispatch/expand.hpp | 8 +- .../strategies/cartesian/envelope.hpp | 153 +++++++ .../strategies/cartesian/envelope_box.hpp | 119 ++++++ .../cartesian/envelope_multipoint.hpp | 59 +++ .../strategies/cartesian/envelope_point.hpp | 113 ++++++ .../strategies/cartesian/envelope_segment.hpp | 18 +- .../strategies/cartesian/expand_box.hpp | 69 ++++ .../strategies/cartesian/expand_point.hpp | 125 ++++++ .../strategies/cartesian/expand_segment.hpp | 71 ++++ .../boost/geometry/strategies/envelope.hpp | 7 +- include/boost/geometry/strategies/expand.hpp | 45 +++ .../strategies/geographic/envelope.hpp | 111 +++++ .../geographic/envelope_segment.hpp | 23 +- .../strategies/geographic/expand_segment.hpp | 102 +++++ .../strategies/spherical/envelope.hpp | 146 +++++++ .../strategies/spherical/envelope_box.hpp | 145 +++++++ .../spherical/envelope_multipoint.hpp | 379 ++++++++++++++++++ .../strategies/spherical/envelope_point.hpp | 111 +++++ .../strategies/spherical/envelope_segment.hpp | 29 +- .../strategies/spherical/expand_box.hpp | 98 +++++ .../strategies/spherical/expand_point.hpp | 233 +++++++++++ .../strategies/spherical/expand_segment.hpp | 118 ++++++ 37 files changed, 2450 insertions(+), 1307 deletions(-) create mode 100644 include/boost/geometry/strategies/cartesian/envelope.hpp create mode 100644 include/boost/geometry/strategies/cartesian/envelope_box.hpp create mode 100644 include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp create mode 100644 include/boost/geometry/strategies/cartesian/envelope_point.hpp create mode 100644 include/boost/geometry/strategies/cartesian/expand_box.hpp create mode 100644 include/boost/geometry/strategies/cartesian/expand_point.hpp create mode 100644 include/boost/geometry/strategies/cartesian/expand_segment.hpp create mode 100644 include/boost/geometry/strategies/expand.hpp create mode 100644 include/boost/geometry/strategies/geographic/envelope.hpp create mode 100644 include/boost/geometry/strategies/geographic/expand_segment.hpp create mode 100644 include/boost/geometry/strategies/spherical/envelope.hpp create mode 100644 include/boost/geometry/strategies/spherical/envelope_box.hpp create mode 100644 include/boost/geometry/strategies/spherical/envelope_multipoint.hpp create mode 100644 include/boost/geometry/strategies/spherical/envelope_point.hpp create mode 100644 include/boost/geometry/strategies/spherical/expand_box.hpp create mode 100644 include/boost/geometry/strategies/spherical/expand_point.hpp create mode 100644 include/boost/geometry/strategies/spherical/expand_segment.hpp diff --git a/include/boost/geometry/algorithms/detail/envelope/areal.hpp b/include/boost/geometry/algorithms/detail/envelope/areal.hpp index 034a98c0a..3c9b5c576 100644 --- a/include/boost/geometry/algorithms/detail/envelope/areal.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/areal.hpp @@ -3,6 +3,7 @@ // Copyright (c) 2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// 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 @@ -28,7 +29,6 @@ namespace boost { namespace geometry namespace detail { namespace envelope { -template struct envelope_polygon { template @@ -42,13 +42,13 @@ struct envelope_polygon // if the exterior ring is empty, consider the interior rings envelope_multi_range < - EnvelopePolicy + envelope_range >::apply(interior_rings(polygon), mbr, strategy); } else { // otherwise, consider only the exterior ring - EnvelopePolicy::apply(ext_ring, mbr, strategy); + envelope_range::apply(ext_ring, mbr, strategy); } } }; @@ -62,77 +62,21 @@ namespace dispatch { -template -struct envelope +template +struct envelope : detail::envelope::envelope_range {}; -template -struct envelope - : detail::envelope::envelope_linestring_or_ring_on_spheroid -{}; - -template -struct envelope - : detail::envelope::envelope_linestring_or_ring_on_spheroid -{}; - - -template -struct envelope - : detail::envelope::envelope_polygon - < - detail::envelope::envelope_range - > -{}; - template -struct envelope +struct envelope : detail::envelope::envelope_polygon - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > -{}; - -template -struct envelope - : detail::envelope::envelope_polygon - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > -{}; - - -template -struct envelope - : detail::envelope::envelope_multi_range - < - detail::envelope::envelope_polygon - < - detail::envelope::envelope_range - > - > {}; template -struct envelope +struct envelope : detail::envelope::envelope_multi_range < detail::envelope::envelope_polygon - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > - > -{}; - -template -struct envelope - : detail::envelope::envelope_multi_range - < - detail::envelope::envelope_polygon - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > > {}; diff --git a/include/boost/geometry/algorithms/detail/envelope/box.hpp b/include/boost/geometry/algorithms/detail/envelope/box.hpp index cf039a292..b085a14b9 100644 --- a/include/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/box.hpp @@ -18,134 +18,17 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP -#include -#include -#include -#include #include -#include - -#include -#include -#include - -#include +// For backward compatibility +#include +#include namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace envelope -{ - - -template -< - std::size_t Index, - std::size_t Dimension, - std::size_t DimensionCount -> -struct envelope_indexed_box -{ - template - static inline void apply(BoxIn const& box_in, BoxOut& mbr) - { - detail::indexed_point_view box_in_corner(box_in); - detail::indexed_point_view mbr_corner(mbr); - - detail::conversion::point_to_point - < - detail::indexed_point_view, - detail::indexed_point_view, - Dimension, - DimensionCount - >::apply(box_in_corner, mbr_corner); - } -}; - -template -< - std::size_t Index, - std::size_t DimensionCount -> -struct envelope_indexed_box_on_spheroid -{ - template - static inline void apply(BoxIn const& box_in, BoxOut& mbr) - { - // transform() does not work with boxes of dimension higher - // than 2; to account for such boxes we transform the min/max - // points of the boxes using the indexed_point_view - detail::indexed_point_view box_in_corner(box_in); - detail::indexed_point_view mbr_corner(mbr); - - // first transform the units - transform_units(box_in_corner, mbr_corner); - - // now transform the remaining coordinates - detail::conversion::point_to_point - < - detail::indexed_point_view, - detail::indexed_point_view, - 2, - DimensionCount - >::apply(box_in_corner, mbr_corner); - } -}; - - -struct envelope_box -{ - template - static inline void apply(BoxIn const& box_in, - BoxOut& mbr, - Strategy const&) - { - envelope_indexed_box - < - min_corner, 0, dimension::value - >::apply(box_in, mbr); - - envelope_indexed_box - < - max_corner, 0, dimension::value - >::apply(box_in, mbr); - } -}; - - -struct envelope_box_on_spheroid -{ - template - static inline void apply(BoxIn const& box_in, - BoxOut& mbr, - Strategy const&) - { - BoxIn box_in_normalized = box_in; - - if (!is_inverse_spheroidal_coordinates(box_in)) - { - box_in_normalized = detail::return_normalized(box_in); - } - - envelope_indexed_box_on_spheroid - < - min_corner, dimension::value - >::apply(box_in_normalized, mbr); - - envelope_indexed_box_on_spheroid - < - max_corner, dimension::value - >::apply(box_in_normalized, mbr); - } -}; - - -}} // namespace detail::envelope -#endif // DOXYGEN_NO_DETAIL #ifndef DOXYGEN_NO_DISPATCH namespace dispatch @@ -153,27 +36,14 @@ namespace dispatch template -struct envelope - : detail::envelope::envelope_box -{}; - - -template -struct envelope - : detail::envelope::envelope_box_on_spheroid -{}; - - -template -struct envelope - : detail::envelope::envelope_box_on_spheroid -{}; - - -template -struct envelope - : detail::envelope::envelope_box_on_spheroid -{}; +struct envelope +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& mbr, Strategy const& ) + { + Strategy::apply(box_in, mbr); + } +}; } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/envelope/interface.hpp b/include/boost/geometry/algorithms/detail/envelope/interface.hpp index 8e9c35b39..28c815f4c 100644 --- a/include/boost/geometry/algorithms/detail/envelope/interface.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/interface.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, 2016, 2017, 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 @@ -21,19 +21,24 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP + #include #include #include -#include - #include +#include +#include +#include + +#include + #include #include -#include -#include -#include + +#include + namespace boost { namespace geometry { @@ -57,13 +62,15 @@ struct envelope Box& box, default_strategy) { - typedef typename point_type::type point_type; - typedef typename coordinate_type::type coordinate_type; - typedef typename strategy::envelope::services::default_strategy < - typename cs_tag::type, - coordinate_type + typename tag::type, + typename cs_tag::type, + typename select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type + >::type >::type strategy_type; dispatch::envelope::apply(geometry, box, strategy_type()); diff --git a/include/boost/geometry/algorithms/detail/envelope/linear.hpp b/include/boost/geometry/algorithms/detail/envelope/linear.hpp index 7fa788b73..e2f05f2e3 100644 --- a/include/boost/geometry/algorithms/detail/envelope/linear.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/linear.hpp @@ -4,11 +4,12 @@ // 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. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at @@ -17,92 +18,40 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP -#include -#include -#include +#include #include #include +// For backward compatibility +#include +#include +#include namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace envelope -{ - -struct envelope_linestring_or_ring_on_spheroid -{ - template - static inline void apply(LinestringRing const& linestring_or_ring, - Box& mbr, - Strategy const& strategy) - { - envelope_range::apply(geometry::segments_begin(linestring_or_ring), - geometry::segments_end(linestring_or_ring), - mbr, - strategy); - } -}; - - -}} // namespace detail::envelope -#endif // DOXYGEN_NO_DETAIL - - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -struct envelope +template +struct envelope : detail::envelope::envelope_range {}; -template -struct envelope - : detail::envelope::envelope_linestring_or_ring_on_spheroid -{}; -template -struct envelope - : detail::envelope::envelope_linestring_or_ring_on_spheroid -{}; - - -template -struct envelope - < - MultiLinestring, multi_linestring_tag, CS_Tag - > : detail::envelope::envelope_multi_range +template +struct envelope + : detail::envelope::envelope_multi_range < detail::envelope::envelope_range > {}; -template -struct envelope - < - MultiLinestring, multi_linestring_tag, spherical_equatorial_tag - > : detail::envelope::envelope_multi_range_on_spheroid - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > -{}; - -template -struct envelope - < - MultiLinestring, multi_linestring_tag, geographic_tag - > : detail::envelope::envelope_multi_range_on_spheroid - < - detail::envelope::envelope_linestring_or_ring_on_spheroid - > -{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp index eef756379..7d9216e20 100644 --- a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/multipoint.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 @@ -13,361 +13,32 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include #include -#include -#include - -#include - -#include - -#include -#include -#include -#include - #include +// For backward compatibility +#include +#include namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace envelope -{ - - -class envelope_multipoint_on_spheroid -{ -private: - template - struct coordinate_less - { - template - inline bool operator()(Point const& point1, Point const& point2) const - { - return math::smaller(geometry::get(point1), - geometry::get(point2)); - } - }; - - template - static inline void analyze_point_coordinates(MultiPoint const& multipoint, - bool& has_south_pole, - bool& has_north_pole, - OutputIterator oit) - { - typedef typename boost::range_value::type point_type; - typedef typename boost::range_iterator - < - MultiPoint const - >::type iterator_type; - - // analyze point coordinates: - // (1) normalize point coordinates - // (2) check if any point is the north or the south pole - // (3) put all non-pole points in a container - // - // notice that at this point in the algorithm, we have at - // least two points on the spheroid - has_south_pole = false; - has_north_pole = false; - - for (iterator_type it = boost::begin(multipoint); - it != boost::end(multipoint); - ++it) - { - point_type point = detail::return_normalized(*it); - - if (math::equals(geometry::get<1>(point), - Constants::min_latitude())) - { - has_south_pole = true; - } - else if (math::equals(geometry::get<1>(point), - Constants::max_latitude())) - { - has_north_pole = true; - } - else - { - *oit++ = point; - } - } - } - - template - static inline Value maximum_gap(SortedRange const& sorted_range, - Value& max_gap_left, - Value& max_gap_right) - { - typedef typename boost::range_iterator - < - SortedRange const - >::type iterator_type; - - iterator_type it1 = boost::begin(sorted_range), it2 = it1; - ++it2; - max_gap_left = geometry::get<0>(*it1); - max_gap_right = geometry::get<0>(*it2); - - Value max_gap = max_gap_right - max_gap_left; - for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2) - { - Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1); - if (math::larger(gap, max_gap)) - { - max_gap_left = geometry::get<0>(*it1); - max_gap_right = geometry::get<0>(*it2); - max_gap = gap; - } - } - - return max_gap; - } - - template - < - typename Constants, - typename PointRange, - typename LongitudeLess, - typename CoordinateType - > - static inline void get_min_max_longitudes(PointRange& range, - LongitudeLess const& lon_less, - CoordinateType& lon_min, - CoordinateType& lon_max) - { - typedef typename boost::range_iterator - < - PointRange const - >::type iterator_type; - - // compute min and max longitude values - std::pair min_max_longitudes - = boost::minmax_element(boost::begin(range), - boost::end(range), - lon_less); - - lon_min = geometry::get<0>(*min_max_longitudes.first); - lon_max = geometry::get<0>(*min_max_longitudes.second); - - // if the longitude span is "large" compute the true maximum gap - if (math::larger(lon_max - lon_min, Constants::half_period())) - { - std::sort(boost::begin(range), boost::end(range), lon_less); - - CoordinateType max_gap_left = 0, max_gap_right = 0; - CoordinateType max_gap - = maximum_gap(range, max_gap_left, max_gap_right); - - CoordinateType complement_gap - = Constants::period() + lon_min - lon_max; - - if (math::larger(max_gap, complement_gap)) - { - lon_min = max_gap_right; - lon_max = max_gap_left + Constants::period(); - } - } - } - - template - < - typename Constants, - typename Iterator, - typename LatitudeLess, - typename CoordinateType - > - static inline void get_min_max_latitudes(Iterator const first, - Iterator const last, - LatitudeLess const& lat_less, - bool has_south_pole, - bool has_north_pole, - CoordinateType& lat_min, - CoordinateType& lat_max) - { - if (has_south_pole && has_north_pole) - { - lat_min = Constants::min_latitude(); - lat_max = Constants::max_latitude(); - } - else if (has_south_pole) - { - lat_min = Constants::min_latitude(); - lat_max - = geometry::get<1>(*std::max_element(first, last, lat_less)); - } - else if (has_north_pole) - { - lat_min - = geometry::get<1>(*std::min_element(first, last, lat_less)); - lat_max = Constants::max_latitude(); - } - else - { - std::pair min_max_latitudes - = boost::minmax_element(first, last, lat_less); - - lat_min = geometry::get<1>(*min_max_latitudes.first); - lat_max = geometry::get<1>(*min_max_latitudes.second); - } - } - -public: - template - static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy) - { - typedef typename point_type::type point_type; - typedef typename coordinate_type::type coordinate_type; - typedef typename boost::range_iterator - < - MultiPoint const - >::type iterator_type; - - typedef math::detail::constants_on_spheroid - < - coordinate_type, - typename coordinate_system::type::units - > constants; - - if (boost::empty(multipoint)) - { - initialize::value>::apply(mbr); - return; - } - - initialize::apply(mbr); - - if (boost::size(multipoint) == 1) - { - return dispatch::envelope - < - typename boost::range_value::type - >::apply(range::front(multipoint), mbr, strategy); - } - - // analyze the points and put the non-pole ones in the - // points vector - std::vector points; - bool has_north_pole = false, has_south_pole = false; - - analyze_point_coordinates(multipoint, - has_south_pole, has_north_pole, - std::back_inserter(points)); - - coordinate_type lon_min, lat_min, lon_max, lat_max; - if (points.size() == 1) - { - // we have one non-pole point and at least one pole point - lon_min = geometry::get<0>(range::front(points)); - lon_max = geometry::get<0>(range::front(points)); - lat_min = has_south_pole - ? constants::min_latitude() - : constants::max_latitude(); - lat_max = has_north_pole - ? constants::max_latitude() - : constants::min_latitude(); - } - else if (points.empty()) - { - // all points are pole points - BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole); - lon_min = coordinate_type(0); - lon_max = coordinate_type(0); - lat_min = has_south_pole - ? constants::min_latitude() - : constants::max_latitude(); - lat_max = (has_north_pole) - ? constants::max_latitude() - : constants::min_latitude(); - } - else - { - get_min_max_longitudes(points, - coordinate_less<0>(), - lon_min, - lon_max); - - get_min_max_latitudes(points.begin(), - points.end(), - coordinate_less<1>(), - has_south_pole, - has_north_pole, - lat_min, - lat_max); - } - - typedef typename helper_geometry - < - Box, - coordinate_type, - typename coordinate_system::type::units - >::type helper_box_type; - - helper_box_type helper_mbr; - - geometry::set(helper_mbr, lon_min); - geometry::set(helper_mbr, lat_min); - geometry::set(helper_mbr, lon_max); - geometry::set(helper_mbr, lat_max); - - // now transform to output MBR (per index) - envelope_indexed_box_on_spheroid::apply(helper_mbr, mbr); - envelope_indexed_box_on_spheroid::apply(helper_mbr, mbr); - - // compute envelope for higher coordinates - iterator_type it = boost::begin(multipoint); - envelope_one_point<2, dimension::value>::apply(*it, mbr, strategy); - - for (++it; it != boost::end(multipoint); ++it) - { - detail::expand::point_loop - < - 2, dimension::value - >::apply(mbr, *it, strategy); - } - } -}; - - -}} // namespace detail::envelope -#endif // DOXYGEN_NO_DETAIL - - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -struct envelope - : detail::envelope::envelope_range -{}; - template -struct envelope - : detail::envelope::envelope_multipoint_on_spheroid -{}; - -template -struct envelope - : detail::envelope::envelope_multipoint_on_spheroid -{}; +struct envelope +{ + template + static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& ) + { + Strategy::apply(multipoint, mbr); + } +}; } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/envelope/point.hpp b/include/boost/geometry/algorithms/detail/envelope/point.hpp index 86e73f3aa..164274a28 100644 --- a/include/boost/geometry/algorithms/detail/envelope/point.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/point.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-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 2017, 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 @@ -18,23 +18,14 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP -#include - -#include -#include -#include -#include #include -#include - -#include -#include - -#include - #include +// For backward compatibility +#include +#include + namespace boost { namespace geometry { @@ -44,53 +35,12 @@ namespace detail { namespace envelope { -template -struct envelope_one_point +struct envelope_point { - template - static inline void apply(Point const& point, Box& mbr) - { - detail::indexed_point_view box_corner(mbr); - detail::conversion::point_to_point - < - Point, - detail::indexed_point_view, - Dimension, - DimensionCount - >::apply(point, box_corner); - } - template - static inline void apply(Point const& point, Box& mbr, Strategy const&) + static inline void apply(Point const& point, Box& mbr, Strategy const& ) { - apply(point, mbr); - apply(point, mbr); - } -}; - - -struct envelope_point_on_spheroid -{ - template - static inline void apply(Point const& point, Box& mbr, Strategy const& strategy) - { - Point normalized_point = detail::return_normalized(point); - - typename point_type::type box_point; - - // transform units of input point to units of a box point - transform_units(normalized_point, box_point); - - geometry::set(mbr, geometry::get<0>(box_point)); - geometry::set(mbr, geometry::get<1>(box_point)); - - geometry::set(mbr, geometry::get<0>(box_point)); - geometry::set(mbr, geometry::get<1>(box_point)); - - envelope_one_point - < - 2, dimension::value - >::apply(normalized_point, mbr, strategy); + Strategy::apply(point, mbr); } }; @@ -104,26 +54,8 @@ namespace dispatch template -struct envelope - : detail::envelope::envelope_one_point<0, dimension::value> -{}; - - -template -struct envelope - : detail::envelope::envelope_point_on_spheroid -{}; - - -template -struct envelope - : detail::envelope::envelope_point_on_spheroid -{}; - - -template -struct envelope - : detail::envelope::envelope_point_on_spheroid +struct envelope + : detail::envelope::envelope_point {}; diff --git a/include/boost/geometry/algorithms/detail/envelope/range.hpp b/include/boost/geometry/algorithms/detail/envelope/range.hpp index b5591f61a..b834eaf94 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range.hpp @@ -4,11 +4,12 @@ // 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. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 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 +// 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. @@ -23,23 +24,16 @@ #include #include -#include - -#include - -#include +#include +#include #include -#include -#include - #include #include #include -#include - +#include namespace boost { namespace geometry { @@ -53,7 +47,7 @@ namespace detail { namespace envelope struct envelope_range { template - static inline void apply(Iterator first, + static inline void apply(Iterator it, Iterator last, Box& mbr, Strategy const& strategy) @@ -63,16 +57,21 @@ struct envelope_range // initialize MBR initialize::value>::apply(mbr); - Iterator it = first; if (it != last) { // initialize box with first element in range - dispatch::envelope::apply(*it, mbr, strategy); + dispatch::envelope + < + value_type + >::apply(*it, mbr, strategy.get_element_envelope_strategy()); // consider now the remaining elements in the range (if any) for (++it; it != last; ++it) { - dispatch::expand::apply(mbr, *it, strategy); + dispatch::expand + < + Box, value_type + >::apply(mbr, *it, strategy.get_element_expand_strategy()); } } } @@ -80,7 +79,7 @@ struct envelope_range template static inline void apply(Range const& range, Box& mbr, Strategy const& strategy) { - return apply(boost::begin(range), boost::end(range), mbr, strategy); + return apply(Strategy::begin(range), Strategy::end(range), mbr, strategy); } }; @@ -94,86 +93,26 @@ struct envelope_multi_range Box& mbr, Strategy const& strategy) { - typedef typename boost::range_iterator - < - MultiRange const - >::type iterator_type; - - bool initialized = false; - for (iterator_type it = boost::begin(multirange); - it != boost::end(multirange); - ++it) - { - if (! geometry::is_empty(*it)) - { - if (initialized) - { - Box helper_mbr; - EnvelopePolicy::apply(*it, helper_mbr, strategy); - - dispatch::expand::apply(mbr, helper_mbr, strategy); - } - else - { - // compute the initial envelope - EnvelopePolicy::apply(*it, mbr, strategy); - initialized = true; - } - } - } - - if (! initialized) - { - // if not already initialized, initialize MBR - initialize::value>::apply(mbr); - } + apply(boost::begin(multirange), boost::end(multirange), mbr, strategy); } -}; - -// implementation for multi-range on a spheroid (longitude is periodic) -template -struct envelope_multi_range_on_spheroid -{ - template - static inline void apply(MultiRange const& multirange, + template + static inline void apply(Iter it, + Iter last, Box& mbr, Strategy const& strategy) { - typedef typename boost::range_iterator - < - MultiRange const - >::type iterator_type; - - // due to the periodicity of longitudes we need to compute the boxes - // of all the single geometries and keep them in a container - std::vector boxes; - for (iterator_type it = boost::begin(multirange); - it != boost::end(multirange); - ++it) + Strategy::template multi_state state; + for (; it != last; ++it) { if (! geometry::is_empty(*it)) { - Box helper_box; - EnvelopePolicy::apply(*it, helper_box, strategy); - boxes.push_back(helper_box); + Box helper_mbr; + EnvelopePolicy::apply(*it, helper_mbr, strategy); + state.apply(helper_mbr); } } - - // now we need to compute the envelope of the range of boxes - // (cannot be done in an incremental fashion as in the - // Cartesian coordinate system) - // if all single geometries are empty no boxes have been found - // and the MBR is simply initialized - if (! boxes.empty()) - { - envelope_range_of_boxes::apply(boxes, mbr, strategy); - } - else - { - initialize::value>::apply(mbr); - } - + state.result(mbr); } }; 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 92d1fe395..111441036 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -151,10 +151,8 @@ struct envelope_range_of_longitudes template struct envelope_range_of_boxes_by_expansion { - template - static inline void apply(RangeOfBoxes const& range_of_boxes, - Box& mbr, - Strategy const& strategy) + template + static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) { typedef typename boost::range_value::type box_type; @@ -198,14 +196,14 @@ struct envelope_range_of_boxes_by_expansion min_corner, Dimension, DimensionCount - >::apply(mbr, *it, strategy); + >::apply(mbr, *it); detail::expand::indexed_loop < max_corner, Dimension, DimensionCount - >::apply(mbr, *it, strategy); + >::apply(mbr, *it); } } @@ -225,16 +223,14 @@ struct envelope_range_of_boxes } }; - template - static inline void apply(RangeOfBoxes const& range_of_boxes, - Box& mbr, - Strategy const& strategy) + template + static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) { // boxes in the range are assumed to be normalized already typedef typename boost::range_value::type box_type; typedef typename coordinate_type::type coordinate_type; - typedef typename coordinate_system::type::units units_type; + typedef typename detail::cs_angular_units::type units_type; typedef typename boost::range_iterator < RangeOfBoxes const @@ -326,7 +322,7 @@ struct envelope_range_of_boxes envelope_range_of_boxes_by_expansion < 2, dimension::value - >::apply(range_of_boxes, mbr, strategy); + >::apply(range_of_boxes, mbr); } }; diff --git a/include/boost/geometry/algorithms/detail/envelope/segment.hpp b/include/boost/geometry/algorithms/detail/envelope/segment.hpp index cfa139a08..051d40b8e 100644 --- a/include/boost/geometry/algorithms/detail/envelope/segment.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/segment.hpp @@ -46,6 +46,11 @@ #include +// For backward compatibility +#include +#include +#include + namespace boost { namespace geometry { @@ -416,18 +421,17 @@ public: template struct envelope_one_segment { - template + template static inline void apply(Point const& p1, Point const& p2, - Box& mbr, - Strategy const& strategy) + Box& mbr) { - envelope_one_point::apply(p1, mbr, strategy); - detail::expand::point_loop + envelope_one_point::apply(p1, mbr); + strategy::expand::detail::point_loop < Dimension, DimensionCount - >::apply(mbr, p2, strategy); + >::apply(mbr, p2); } }; @@ -446,7 +450,7 @@ struct envelope_segment // now compute the envelope range for coordinates of // dimension 2 and higher - envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy); + envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr); } template diff --git a/include/boost/geometry/algorithms/detail/expand/box.hpp b/include/boost/geometry/algorithms/detail/expand/box.hpp index 485f4d25e..4a2bfa1d2 100644 --- a/include/boost/geometry/algorithms/detail/expand/box.hpp +++ b/include/boost/geometry/algorithms/detail/expand/box.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, 2016, 2017, 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 @@ -19,52 +19,19 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include #include +#include + +// For backward compatibility +#include +#include + namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace expand -{ - - -struct box_on_spheroid -{ - template - static inline void apply(BoxOut& box_out, - BoxIn const& box_in, - Strategy const& strategy) - { - // normalize both boxes and convert box-in to be of type of box-out - BoxOut mbrs[2]; - detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy); - detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy); - - // compute the envelope of the two boxes - detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy); - } -}; - - -}} // namespace detail::expand -#endif // DOXYGEN_NO_DETAIL - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { @@ -73,59 +40,23 @@ namespace dispatch // Box + box -> new box containing two input boxes template < - typename BoxOut, typename BoxIn, - typename CSTagOut, typename CSTag + typename BoxOut, typename BoxIn > struct expand < BoxOut, BoxIn, - box_tag, box_tag, - CSTagOut, CSTag + box_tag, box_tag > { - BOOST_MPL_ASSERT_MSG((false), - NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS, - (types())); + template + static inline void apply(BoxOut& box_out, + BoxIn const& box_in, + Strategy const& ) + { + Strategy::apply(box_out, box_in); + } }; -template -struct expand - < - BoxOut, BoxIn, - box_tag, box_tag, - cartesian_tag, cartesian_tag - > : detail::expand::expand_indexed - < - 0, dimension::value - > -{}; - -template -struct expand - < - BoxOut, BoxIn, - box_tag, box_tag, - spherical_equatorial_tag, spherical_equatorial_tag - > : detail::expand::box_on_spheroid -{}; - -template -struct expand - < - BoxOut, BoxIn, - box_tag, box_tag, - spherical_polar_tag, spherical_polar_tag - > : detail::expand::box_on_spheroid -{}; - -template -struct expand - < - BoxOut, BoxIn, - box_tag, box_tag, - geographic_tag, geographic_tag - > : detail::expand::box_on_spheroid -{}; } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/expand/indexed.hpp b/include/boost/geometry/algorithms/detail/expand/indexed.hpp index fe7ee4f78..08463689d 100644 --- a/include/boost/geometry/algorithms/detail/expand/indexed.hpp +++ b/include/boost/geometry/algorithms/detail/expand/indexed.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, 2016, 2017, 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 @@ -48,8 +48,8 @@ template > struct indexed_loop { - template - static inline void apply(Box& box, Geometry const& source, Strategy const& strategy) + template + static inline void apply(Box& box, Geometry const& source) { typedef typename select_coordinate_type < @@ -75,7 +75,7 @@ struct indexed_loop indexed_loop < Index, Dimension + 1, DimensionCount - >::apply(box, source, strategy); + >::apply(box, source); } }; @@ -86,8 +86,8 @@ struct indexed_loop Index, DimensionCount, DimensionCount > { - template - static inline void apply(Box&, Geometry const&, Strategy const&) {} + template + static inline void apply(Box&, Geometry const&) {} }; @@ -96,20 +96,18 @@ struct indexed_loop template struct expand_indexed { - template - static inline void apply(Box& box, - Geometry const& geometry, - Strategy const& strategy) + template + static inline void apply(Box& box, Geometry const& geometry) { indexed_loop < 0, Dimension, DimensionCount - >::apply(box, geometry, strategy); + >::apply(box, geometry); indexed_loop < 1, Dimension, DimensionCount - >::apply(box, geometry, strategy); + >::apply(box, geometry); } }; diff --git a/include/boost/geometry/algorithms/detail/expand/interface.hpp b/include/boost/geometry/algorithms/detail/expand/interface.hpp index 5aacd8e72..28241b379 100644 --- a/include/boost/geometry/algorithms/detail/expand/interface.hpp +++ b/include/boost/geometry/algorithms/detail/expand/interface.hpp @@ -5,11 +5,12 @@ // 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. -// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2016, 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 +// 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. @@ -25,16 +26,17 @@ #include #include +#include +#include +#include + #include #include #include +#include -#include -#include -#include -#include namespace boost { namespace geometry { @@ -58,14 +60,11 @@ struct expand Geometry const& geometry, default_strategy) { - typedef typename point_type::type point_type; - typedef typename coordinate_type::type coordinate_type; - - typedef typename strategy::envelope::services::default_strategy - < - typename cs_tag::type, - coordinate_type - >::type strategy_type; + typedef typename strategy::expand::services::default_strategy + < + typename tag::type, + typename cs_tag::type + >::type strategy_type; dispatch::expand::apply(box, geometry, strategy_type()); } diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index 88ebe75db..e46f5c973 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -22,263 +22,25 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include #include +#include + +// For backward compatibility +#include +#include + + namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace expand -{ - - -template -struct point_loop -{ - template - static inline void apply(Box& box, Point const& source, Strategy const& strategy) - { - typedef typename select_coordinate_type - < - Point, Box - >::type coordinate_type; - - std::less less; - std::greater greater; - - coordinate_type const coord = get(source); - - if (less(coord, get(box))) - { - set(box, coord); - } - - if (greater(coord, get(box))) - { - set(box, coord); - } - - point_loop::apply(box, source, strategy); - } -}; - - -template -struct point_loop -{ - template - static inline void apply(Box&, Point const&, Strategy const&) {} -}; - - -// implementation for the spherical and geographic coordinate systems -template -struct point_loop_on_spheroid -{ - template - static inline void apply(Box& box, - Point const& point, - Strategy const& strategy) - { - typedef typename point_type::type box_point_type; - typedef typename coordinate_type::type box_coordinate_type; - typedef typename coordinate_system::type::units units_type; - - typedef math::detail::constants_on_spheroid - < - box_coordinate_type, - units_type - > constants; - - // normalize input point and input box - Point p_normalized = detail::return_normalized(point); - - // 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); - - 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)); - geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); - geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); - - } else { - - detail::normalize(box, box); - - box_coordinate_type p_lon = geometry::get<0>(box_point); - box_coordinate_type p_lat = geometry::get<1>(box_point); - - 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)) - { - // 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; - } - } - - 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); - } -}; - - -}} // namespace detail::expand -#endif // DOXYGEN_NO_DETAIL - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { // Box + point -> new box containing also point -template -< - typename BoxOut, typename Point, - typename CSTagOut, typename CSTag -> -struct expand - < - BoxOut, Point, - box_tag, point_tag, - CSTagOut, CSTag - > -{ - BOOST_MPL_ASSERT_MSG((false), - NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS, - (types())); -}; - - -template -struct expand - < - BoxOut, Point, - box_tag, point_tag, - cartesian_tag, cartesian_tag - > : detail::expand::point_loop - < - 0, dimension::value - > -{}; - -template -struct expand - < - BoxOut, Point, - box_tag, point_tag, - spherical_equatorial_tag, spherical_equatorial_tag - > : detail::expand::point_loop_on_spheroid - < - dimension::value - > -{}; - -template -struct expand - < - BoxOut, Point, - box_tag, point_tag, - spherical_polar_tag, spherical_polar_tag - > : detail::expand::point_loop_on_spheroid - < - dimension::value, - false - > -{}; - template < typename BoxOut, typename Point @@ -286,13 +48,18 @@ template struct expand < BoxOut, Point, - box_tag, point_tag, - geographic_tag, geographic_tag - > : detail::expand::point_loop_on_spheroid - < - dimension::value - > -{}; + box_tag, point_tag + > +{ + template + static inline void apply(Box& box, + Point const& point, + Strategy const& ) + { + Strategy::apply(box, point); + } +}; + } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/expand/segment.hpp b/include/boost/geometry/algorithms/detail/expand/segment.hpp index dddd3d2c7..61894ae43 100644 --- a/include/boost/geometry/algorithms/detail/expand/segment.hpp +++ b/include/boost/geometry/algorithms/detail/expand/segment.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, 2016, 2017, 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 @@ -19,79 +19,26 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP -#include -#include -#include -#include - -#include -#include -#include - -#include +#include #include +#include + +// For backward compatibility +#include +#include +#include + namespace boost { namespace geometry { -#ifndef DOXYGEN_NO_DETAIL -namespace detail { namespace expand -{ - -struct segment -{ - template - static inline void apply(Box& box, - Segment const& segment, - Strategy const& strategy) - { - Box mbrs[2]; - - // compute the envelope of the segment - typename point_type::type p[2]; - detail::assign_point_from_index<0>(segment, p[0]); - detail::assign_point_from_index<1>(segment, p[1]); - detail::envelope::envelope_segment - < - dimension::value - >::apply(p[0], p[1], mbrs[0], strategy); - - // normalize the box - detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy); - - // compute the envelope of the two boxes - detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy); - } -}; - - -}} // namespace detail::expand -#endif // DOXYGEN_NO_DETAIL - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { -template -< - typename Box, typename Segment, - typename CSTagOut, typename CSTag -> -struct expand - < - Box, Segment, - box_tag, segment_tag, - CSTagOut, CSTag - > -{ - BOOST_MPL_ASSERT_MSG((false), - NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS, - (types())); -}; - template < typename Box, typename Segment @@ -99,40 +46,19 @@ template struct expand < Box, Segment, - box_tag, segment_tag, - cartesian_tag, cartesian_tag - > : detail::expand::expand_indexed - < - 0, dimension::value - > -{}; + box_tag, segment_tag + > +{ + template + static inline void apply(Box& box, + Segment const& segment, + Strategy const& strategy) + { + boost::ignore_unused(strategy); + strategy.apply(box, segment); + } +}; -template -struct expand - < - Box, Segment, - box_tag, segment_tag, - spherical_polar_tag, spherical_polar_tag - > : detail::expand::segment -{}; - -template -struct expand - < - Box, Segment, - box_tag, segment_tag, - spherical_equatorial_tag, spherical_equatorial_tag - > : detail::expand::segment -{}; - -template -struct expand - < - Box, Segment, - box_tag, segment_tag, - geographic_tag, geographic_tag - > : detail::expand::segment -{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/include/boost/geometry/algorithms/dispatch/envelope.hpp b/include/boost/geometry/algorithms/dispatch/envelope.hpp index bb8a99f5a..bfe0f0d44 100644 --- a/include/boost/geometry/algorithms/dispatch/envelope.hpp +++ b/include/boost/geometry/algorithms/dispatch/envelope.hpp @@ -4,10 +4,11 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015, 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 Menelaos Karavelas, on behalf of Oracle +// 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. @@ -35,8 +36,7 @@ namespace dispatch template < typename Geometry, - typename Tag = typename tag::type, - typename CS_Tag = typename cs_tag::type + typename Tag = typename tag::type > struct envelope : not_implemented {}; diff --git a/include/boost/geometry/algorithms/dispatch/expand.hpp b/include/boost/geometry/algorithms/dispatch/expand.hpp index c7a769648..204bbc6ce 100644 --- a/include/boost/geometry/algorithms/dispatch/expand.hpp +++ b/include/boost/geometry/algorithms/dispatch/expand.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, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017, 2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -41,9 +41,7 @@ template < typename GeometryOut, typename Geometry, typename TagOut = typename tag::type, - typename Tag = typename tag::type, - typename CSTagOut = typename cs_tag::type, - typename CSTag = typename cs_tag::type + typename Tag = typename tag::type > struct expand : not_implemented {}; diff --git a/include/boost/geometry/strategies/cartesian/envelope.hpp b/include/boost/geometry/strategies/cartesian/envelope.hpp new file mode 100644 index 000000000..2a11dc5a5 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/envelope.hpp @@ -0,0 +1,153 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// 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, 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 +// 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. + +// Distributed under 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_STRATEGIES_CARTESIAN_ENVELOPE_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP + +#include +#include + +#include + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +template +class cartesian +{ +public: + typedef cartesian_point element_envelope_strategy_type; + static inline element_envelope_strategy_type get_element_envelope_strategy() + { + return element_envelope_strategy_type(); + } + + typedef expand::cartesian_point element_expand_strategy_type; + static inline element_expand_strategy_type get_element_expand_strategy() + { + return element_expand_strategy_type(); + } + + typedef expand::cartesian_box box_expand_strategy_type; + static inline box_expand_strategy_type get_box_expand_strategy() + { + return box_expand_strategy_type(); + } + + // Linestring, Ring, Polygon + + template + static inline typename boost::range_iterator::type begin(Range const& range) + { + return boost::begin(range); + } + + template + static inline typename boost::range_iterator::type end(Range const& range) + { + return boost::end(range); + } + + // MultiLinestring, MultiPolygon + + template + struct multi_state + { + multi_state() + : m_initialized(false) + {} + + void apply(Box const& single_box) + { + if (! m_initialized) + { + m_box = single_box; + m_initialized = true; + } + else + { + box_expand_strategy_type::apply(m_box, single_box); + } + } + + void result(Box & box) + { + if (m_initialized) + { + box = m_box; + } + else + { + geometry::detail::envelope::initialize::value>::apply(box); + } + } + + private: + bool m_initialized; + Box m_box; + }; + + // Segment + + template + static inline void apply(Point1 const& point1, Point2 const& point2, + Box& box) + { + cartesian_segment::apply(point1, point2, box); + } + + // Box + + template + static inline void apply(BoxIn const& box_in, Box& box) + { + cartesian_box::apply(box_in, box); + } +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::cartesian type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP diff --git a/include/boost/geometry/strategies/cartesian/envelope_box.hpp b/include/boost/geometry/strategies/cartesian/envelope_box.hpp new file mode 100644 index 000000000..c6dd21835 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/envelope_box.hpp @@ -0,0 +1,119 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. + +// 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP + +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace envelope +{ + + +template +< + std::size_t Index, + std::size_t Dimension, + std::size_t DimensionCount +> +struct envelope_indexed_box +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& mbr) + { + detail::indexed_point_view box_in_corner(box_in); + detail::indexed_point_view mbr_corner(mbr); + + detail::conversion::point_to_point + < + detail::indexed_point_view, + detail::indexed_point_view, + Dimension, + DimensionCount + >::apply(box_in_corner, mbr_corner); + } +}; + + +}} // namespace detail::envelope +#endif // DOXYGEN_NO_DETAIL + + +namespace strategy { namespace envelope +{ + + +struct cartesian_box +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& mbr) + { + geometry::detail::envelope::envelope_indexed_box + < + min_corner, 0, dimension::value + >::apply(box_in, mbr); + + geometry::detail::envelope::envelope_indexed_box + < + max_corner, 0, dimension::value + >::apply(box_in, mbr); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::cartesian_box type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP diff --git a/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp b/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp new file mode 100644 index 000000000..28c2374ce --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/envelope_multipoint.hpp @@ -0,0 +1,59 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +class cartesian_multipoint +{ +public: + template + static inline void apply(MultiPoint const& multipoint, Box& mbr) + { + geometry::detail::envelope::envelope_range::apply(multipoint, mbr, cartesian<>()); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::cartesian_multipoint type; +}; + + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP diff --git a/include/boost/geometry/strategies/cartesian/envelope_point.hpp b/include/boost/geometry/strategies/cartesian/envelope_point.hpp new file mode 100644 index 000000000..51c006abf --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/envelope_point.hpp @@ -0,0 +1,113 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP + +#include + +#include +#include +#include +#include +#include + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace envelope +{ + +template +struct envelope_one_point +{ + template + static inline void apply(Point const& point, Box& mbr) + { + detail::indexed_point_view box_corner(mbr); + detail::conversion::point_to_point + < + Point, + detail::indexed_point_view, + Dimension, + DimensionCount + >::apply(point, box_corner); + } + + template + static inline void apply(Point const& point, Box& mbr) + { + apply(point, mbr); + apply(point, mbr); + } +}; + + +}} // namespace detail::envelope +#endif // DOXYGEN_NO_DETAIL + + +namespace strategy { namespace envelope +{ + +struct cartesian_point +{ + template + static inline void apply(Point const& point, Box& mbr) + { + typedef geometry::detail::envelope::envelope_one_point + < + 0, dimension::value + > per_corner; + per_corner::apply(point, mbr); + per_corner::apply(point, mbr); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::cartesian_point type; +}; + + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP diff --git a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp index a591996b8..6bd5c15c4 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -11,11 +11,12 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP +#include +#include #include -#include + #include -#include namespace boost { namespace geometry @@ -30,11 +31,9 @@ template > class cartesian_segment { -public : - +public: template - inline void - apply(Point1 const& point1, Point2 const& point2, Box& box) const + static inline void apply(Point1 const& point1, Point2 const& point2, Box& box) { geometry::detail::envelope::envelope_one_segment < @@ -43,8 +42,7 @@ public : > ::apply(point1, point2, - box, - strategy::envelope::cartesian_segment()); + box); } }; @@ -55,7 +53,7 @@ namespace services { template -struct default_strategy +struct default_strategy { typedef strategy::envelope::cartesian_segment type; }; diff --git a/include/boost/geometry/strategies/cartesian/expand_box.hpp b/include/boost/geometry/strategies/cartesian/expand_box.hpp new file mode 100644 index 000000000..68b8824f8 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/expand_box.hpp @@ -0,0 +1,69 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// 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. + +// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +struct cartesian_box +{ + template + static void apply(BoxOut & box_out, BoxIn const& box_in) + { + geometry::detail::expand::expand_indexed + < + 0, dimension::value + >::apply(box_out, box_in); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef cartesian_box type; +}; + + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP diff --git a/include/boost/geometry/strategies/cartesian/expand_point.hpp b/include/boost/geometry/strategies/cartesian/expand_point.hpp new file mode 100644 index 000000000..87d82dca0 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/expand_point.hpp @@ -0,0 +1,125 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. + +// 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 +// 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. + +// Distributed under 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_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP + +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +struct point_loop +{ + template + static inline void apply(Box& box, Point const& source) + { + typedef typename select_coordinate_type + < + Point, Box + >::type coordinate_type; + + std::less less; + std::greater greater; + + coordinate_type const coord = get(source); + + if (less(coord, get(box))) + { + set(box, coord); + } + + if (greater(coord, get(box))) + { + set(box, coord); + } + + point_loop::apply(box, source); + } +}; + + +template +struct point_loop +{ + template + static inline void apply(Box&, Point const&) {} +}; + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +struct cartesian_point +{ + template + static void apply(Box & box, Point const& point) + { + expand::detail::point_loop + < + 0, dimension::value + >::apply(box, point); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef cartesian_point type; +}; + + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP diff --git a/include/boost/geometry/strategies/cartesian/expand_segment.hpp b/include/boost/geometry/strategies/cartesian/expand_segment.hpp new file mode 100644 index 000000000..18fd9c9a7 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/expand_segment.hpp @@ -0,0 +1,71 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP + + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +class cartesian_segment +{ +public: + template + static void apply(Box & box, Segment const& segment) + { + geometry::detail::expand::expand_indexed + < + 0, dimension::value + >::apply(box, segment); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef cartesian_segment type; +}; + + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP diff --git a/include/boost/geometry/strategies/envelope.hpp b/include/boost/geometry/strategies/envelope.hpp index fde9c858a..050ed4658 100644 --- a/include/boost/geometry/strategies/envelope.hpp +++ b/include/boost/geometry/strategies/envelope.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2016-2017 Oracle and/or its affiliates. +// Copyright (c) 2016-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -23,16 +23,17 @@ namespace strategy { namespace envelope { namespace services /*! \brief Traits class binding a default envelope strategy to a coordinate system \ingroup util +\tparam Tag tag of geometry \tparam CSTag tag of coordinate system \tparam CalculationType \tparam_calculation */ -template +template struct default_strategy { BOOST_MPL_ASSERT_MSG ( false, NOT_IMPLEMENTED_FOR_THIS_TYPE - , (types) + , (types) ); }; diff --git a/include/boost/geometry/strategies/expand.hpp b/include/boost/geometry/strategies/expand.hpp new file mode 100644 index 000000000..39d414514 --- /dev/null +++ b/include/boost/geometry/strategies/expand.hpp @@ -0,0 +1,45 @@ +// Boost.Geometry + +// Copyright (c) 2018 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_STRATEGIES_EXPAND_HPP +#define BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP + +#include + +namespace boost { namespace geometry +{ + + +namespace strategy { namespace expand { namespace services +{ + +/*! +\brief Traits class binding a default envelope strategy to a coordinate system +\ingroup util +\tparam Tag tag of geometry +\tparam CSTag tag of coordinate system +\tparam CalculationType \tparam_calculation +*/ +template +struct default_strategy +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_TYPE + , (types) + ); +}; + +}}} // namespace strategy::expand::services + + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP + diff --git a/include/boost/geometry/strategies/geographic/envelope.hpp b/include/boost/geometry/strategies/geographic/envelope.hpp new file mode 100644 index 000000000..c98d995fe --- /dev/null +++ b/include/boost/geometry/strategies/geographic/envelope.hpp @@ -0,0 +1,111 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// 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, 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 +// 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. + +// Distributed under 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_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP + +#include + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + + +template +< + typename FormulaPolicy = strategy::andoyer, + typename Spheroid = geometry::srs::spheroid, + typename CalculationType = void +> +class geographic + : public spherical +{ +public: + typedef Spheroid model_type; + + inline geographic() + : m_spheroid() + {} + + explicit inline geographic(Spheroid const& spheroid) + : m_spheroid(spheroid) + {} + + typedef geographic_segment + < + FormulaPolicy, Spheroid, CalculationType + > element_envelope_strategy_type; + inline element_envelope_strategy_type get_element_envelope_strategy() const + { + return element_envelope_strategy_type(m_spheroid); + } + + typedef expand::geographic_segment + < + FormulaPolicy, Spheroid, CalculationType + > element_expand_strategy_type; + inline element_expand_strategy_type get_element_expand_strategy() const + { + return element_expand_strategy_type(m_spheroid); + } + + template + inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const + { + geographic_segment + < + FormulaPolicy, + Spheroid, + CalculationType + >(m_spheroid).apply(point1, point2, box); + } + +private: + Spheroid m_spheroid; +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::geographic type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP diff --git a/include/boost/geometry/strategies/geographic/envelope_segment.hpp b/include/boost/geometry/strategies/geographic/envelope_segment.hpp index 5bada63f6..ffe1a1a00 100644 --- a/include/boost/geometry/strategies/geographic/envelope_segment.hpp +++ b/include/boost/geometry/strategies/geographic/envelope_segment.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -20,7 +20,7 @@ #include #include #include - +#include namespace boost { namespace geometry { @@ -47,11 +47,19 @@ public: : m_spheroid(spheroid) {} + typedef strategy::expand::spherical_box box_expand_strategy_type; + static inline box_expand_strategy_type get_box_expand_strategy() + { + return box_expand_strategy_type(); + } + template inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const { - Point1 p1_normalized = detail::return_normalized(point1); - Point2 p2_normalized = detail::return_normalized(point2); + Point1 p1_normalized; + strategy::normalize::spherical_point::apply(point1, p1_normalized); + Point2 p2_normalized; + strategy::normalize::spherical_point::apply(point2, p2_normalized); geometry::strategy::azimuth::geographic < @@ -60,7 +68,10 @@ public: CalculationType > azimuth_geographic(m_spheroid); - typedef typename coordinate_system::type::units units_type; + typedef typename geometry::detail::cs_angular_units + < + Point1 + >::type units_type; detail::envelope::envelope_segment_impl < @@ -84,7 +95,7 @@ namespace services { template -struct default_strategy +struct default_strategy { typedef strategy::envelope::geographic_segment < diff --git a/include/boost/geometry/strategies/geographic/expand_segment.hpp b/include/boost/geometry/strategies/geographic/expand_segment.hpp new file mode 100644 index 000000000..66779c109 --- /dev/null +++ b/include/boost/geometry/strategies/geographic/expand_segment.hpp @@ -0,0 +1,102 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +template +< + typename FormulaPolicy = strategy::andoyer, + typename Spheroid = geometry::srs::spheroid, + typename CalculationType = void +> +class geographic_segment +{ +public: + inline geographic_segment() + : m_envelope_strategy() + {} + + explicit inline geographic_segment(Spheroid const& spheroid) + : m_envelope_strategy(spheroid) + {} + + template + inline void apply(Box& box, Segment const& segment) const + { + detail::segment_on_spheroid::apply(box, segment, m_envelope_strategy); + } + +private: + strategy::envelope::geographic_segment + < + FormulaPolicy, Spheroid, CalculationType + > m_envelope_strategy; +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef geographic_segment + < + strategy::andoyer, + geometry::srs::spheroid, + CalculationType + > type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope.hpp b/include/boost/geometry/strategies/spherical/envelope.hpp new file mode 100644 index 000000000..4353f0180 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/envelope.hpp @@ -0,0 +1,146 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// 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, 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 +// 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. + +// Distributed under 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_STRATEGIES_SPHERICAL_ENVELOPE_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP + +#include +#include + +#include + +#include +#include +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +template +class spherical +{ +public: + typedef spherical_segment element_envelope_strategy_type; + static inline element_envelope_strategy_type get_element_envelope_strategy() + { + return element_envelope_strategy_type(); + } + + typedef expand::spherical_segment element_expand_strategy_type; + static inline element_expand_strategy_type get_element_expand_strategy() + { + return element_expand_strategy_type(); + } + + typedef strategy::expand::spherical_box box_expand_strategy_type; + static inline box_expand_strategy_type get_box_expand_strategy() + { + return box_expand_strategy_type(); + } + + // Linestring, Ring, Polygon + + template + static inline geometry::segment_iterator begin(Range const& range) + { + return geometry::segments_begin(range); + } + + template + static inline geometry::segment_iterator end(Range const& range) + { + return geometry::segments_end(range); + } + + // MultiLinestring, MultiPolygon + + template + struct multi_state + { + void apply(Box const& single_box) + { + m_boxes.push_back(single_box); + } + + void result(Box & box) + { + if (!m_boxes.empty()) + { + geometry::detail::envelope::envelope_range_of_boxes::apply(m_boxes, box); + } + else + { + geometry::detail::envelope::initialize::value>::apply(box); + } + } + + private: + std::vector m_boxes; + }; + + // Segment + + template + static inline void apply(Point1 const& point1, Point2 const& point2, + Box& box) + { + spherical_segment::apply(point1, point2, box); + } + + // Box + + template + static inline void apply(BoxIn const& box_in, Box& box) + { + spherical_box::apply(box_in, box); + } +}; + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::spherical type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} //namepsace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope_box.hpp b/include/boost/geometry/strategies/spherical/envelope_box.hpp new file mode 100644 index 000000000..0a9436d12 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/envelope_box.hpp @@ -0,0 +1,145 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. + +// 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP + +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace envelope +{ + + +template +< + std::size_t Index, + std::size_t DimensionCount +> +struct envelope_indexed_box_on_spheroid +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& mbr) + { + // transform() does not work with boxes of dimension higher + // than 2; to account for such boxes we transform the min/max + // points of the boxes using the indexed_point_view + detail::indexed_point_view box_in_corner(box_in); + detail::indexed_point_view mbr_corner(mbr); + + // first transform the units + transform_units(box_in_corner, mbr_corner); + + // now transform the remaining coordinates + detail::conversion::point_to_point + < + detail::indexed_point_view, + detail::indexed_point_view, + 2, + DimensionCount + >::apply(box_in_corner, mbr_corner); + } +}; + + +}} // namespace detail::envelope +#endif // DOXYGEN_NO_DETAIL + + +namespace strategy { namespace envelope +{ + + +struct spherical_box +{ + template + static inline void apply(BoxIn const& box_in, BoxOut& mbr) + { + BoxIn box_in_normalized = box_in; + + if (!is_inverse_spheroidal_coordinates(box_in)) + { + strategy::normalize::spherical_box::apply(box_in, box_in_normalized); + } + + geometry::detail::envelope::envelope_indexed_box_on_spheroid + < + min_corner, dimension::value + >::apply(box_in_normalized, mbr); + + geometry::detail::envelope::envelope_indexed_box_on_spheroid + < + max_corner, dimension::value + >::apply(box_in_normalized, mbr); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_box type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_box type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_box type; +}; + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_BOX_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp b/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp new file mode 100644 index 000000000..e7817370f --- /dev/null +++ b/include/boost/geometry/strategies/spherical/envelope_multipoint.hpp @@ -0,0 +1,379 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +class spherical_multipoint +{ +private: + template + struct coordinate_less + { + template + inline bool operator()(Point const& point1, Point const& point2) const + { + return math::smaller(geometry::get(point1), + geometry::get(point2)); + } + }; + + template + static inline void analyze_point_coordinates(MultiPoint const& multipoint, + bool& has_south_pole, + bool& has_north_pole, + OutputIterator oit) + { + typedef typename boost::range_value::type point_type; + typedef typename boost::range_iterator + < + MultiPoint const + >::type iterator_type; + + // analyze point coordinates: + // (1) normalize point coordinates + // (2) check if any point is the north or the south pole + // (3) put all non-pole points in a container + // + // notice that at this point in the algorithm, we have at + // least two points on the spheroid + has_south_pole = false; + has_north_pole = false; + + for (iterator_type it = boost::begin(multipoint); + it != boost::end(multipoint); + ++it) + { + point_type point; + normalize::spherical_point::apply(*it, point); + + if (math::equals(geometry::get<1>(point), + Constants::min_latitude())) + { + has_south_pole = true; + } + else if (math::equals(geometry::get<1>(point), + Constants::max_latitude())) + { + has_north_pole = true; + } + else + { + *oit++ = point; + } + } + } + + template + static inline Value maximum_gap(SortedRange const& sorted_range, + Value& max_gap_left, + Value& max_gap_right) + { + typedef typename boost::range_iterator + < + SortedRange const + >::type iterator_type; + + iterator_type it1 = boost::begin(sorted_range), it2 = it1; + ++it2; + max_gap_left = geometry::get<0>(*it1); + max_gap_right = geometry::get<0>(*it2); + + Value max_gap = max_gap_right - max_gap_left; + for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2) + { + Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1); + if (math::larger(gap, max_gap)) + { + max_gap_left = geometry::get<0>(*it1); + max_gap_right = geometry::get<0>(*it2); + max_gap = gap; + } + } + + return max_gap; + } + + template + < + typename Constants, + typename PointRange, + typename LongitudeLess, + typename CoordinateType + > + static inline void get_min_max_longitudes(PointRange& range, + LongitudeLess const& lon_less, + CoordinateType& lon_min, + CoordinateType& lon_max) + { + typedef typename boost::range_iterator + < + PointRange const + >::type iterator_type; + + // compute min and max longitude values + std::pair min_max_longitudes + = boost::minmax_element(boost::begin(range), + boost::end(range), + lon_less); + + lon_min = geometry::get<0>(*min_max_longitudes.first); + lon_max = geometry::get<0>(*min_max_longitudes.second); + + // if the longitude span is "large" compute the true maximum gap + if (math::larger(lon_max - lon_min, Constants::half_period())) + { + std::sort(boost::begin(range), boost::end(range), lon_less); + + CoordinateType max_gap_left = 0, max_gap_right = 0; + CoordinateType max_gap + = maximum_gap(range, max_gap_left, max_gap_right); + + CoordinateType complement_gap + = Constants::period() + lon_min - lon_max; + + if (math::larger(max_gap, complement_gap)) + { + lon_min = max_gap_right; + lon_max = max_gap_left + Constants::period(); + } + } + } + + template + < + typename Constants, + typename Iterator, + typename LatitudeLess, + typename CoordinateType + > + static inline void get_min_max_latitudes(Iterator const first, + Iterator const last, + LatitudeLess const& lat_less, + bool has_south_pole, + bool has_north_pole, + CoordinateType& lat_min, + CoordinateType& lat_max) + { + if (has_south_pole && has_north_pole) + { + lat_min = Constants::min_latitude(); + lat_max = Constants::max_latitude(); + } + else if (has_south_pole) + { + lat_min = Constants::min_latitude(); + lat_max + = geometry::get<1>(*std::max_element(first, last, lat_less)); + } + else if (has_north_pole) + { + lat_min + = geometry::get<1>(*std::min_element(first, last, lat_less)); + lat_max = Constants::max_latitude(); + } + else + { + std::pair min_max_latitudes + = boost::minmax_element(first, last, lat_less); + + lat_min = geometry::get<1>(*min_max_latitudes.first); + lat_max = geometry::get<1>(*min_max_latitudes.second); + } + } + +public: + template + static inline void apply(MultiPoint const& multipoint, Box& mbr) + { + typedef typename point_type::type point_type; + typedef typename coordinate_type::type coordinate_type; + typedef typename boost::range_iterator + < + MultiPoint const + >::type iterator_type; + + typedef math::detail::constants_on_spheroid + < + coordinate_type, + typename geometry::detail::cs_angular_units::type + > constants; + + if (boost::empty(multipoint)) + { + geometry::detail::envelope::initialize::value>::apply(mbr); + return; + } + + geometry::detail::envelope::initialize::apply(mbr); + + if (boost::size(multipoint) == 1) + { + return dispatch::envelope + < + typename boost::range_value::type + >::apply(range::front(multipoint), mbr, strategy::envelope::spherical_point()); + } + + // analyze the points and put the non-pole ones in the + // points vector + std::vector points; + bool has_north_pole = false, has_south_pole = false; + + analyze_point_coordinates(multipoint, + has_south_pole, has_north_pole, + std::back_inserter(points)); + + coordinate_type lon_min, lat_min, lon_max, lat_max; + if (points.size() == 1) + { + // we have one non-pole point and at least one pole point + lon_min = geometry::get<0>(range::front(points)); + lon_max = geometry::get<0>(range::front(points)); + lat_min = has_south_pole + ? constants::min_latitude() + : constants::max_latitude(); + lat_max = has_north_pole + ? constants::max_latitude() + : constants::min_latitude(); + } + else if (points.empty()) + { + // all points are pole points + BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole); + lon_min = coordinate_type(0); + lon_max = coordinate_type(0); + lat_min = has_south_pole + ? constants::min_latitude() + : constants::max_latitude(); + lat_max = (has_north_pole) + ? constants::max_latitude() + : constants::min_latitude(); + } + else + { + get_min_max_longitudes(points, + coordinate_less<0>(), + lon_min, + lon_max); + + get_min_max_latitudes(points.begin(), + points.end(), + coordinate_less<1>(), + has_south_pole, + has_north_pole, + lat_min, + lat_max); + } + + typedef typename helper_geometry + < + Box, + coordinate_type, + typename geometry::detail::cs_angular_units::type + >::type helper_box_type; + + helper_box_type helper_mbr; + + geometry::set(helper_mbr, lon_min); + geometry::set(helper_mbr, lat_min); + geometry::set(helper_mbr, lon_max); + geometry::set(helper_mbr, lat_max); + + // now transform to output MBR (per index) + geometry::detail::envelope::envelope_indexed_box_on_spheroid::apply(helper_mbr, mbr); + geometry::detail::envelope::envelope_indexed_box_on_spheroid::apply(helper_mbr, mbr); + + // compute envelope for higher coordinates + iterator_type it = boost::begin(multipoint); + geometry::detail::envelope::envelope_one_point<2, dimension::value>::apply(*it, mbr); + + for (++it; it != boost::end(multipoint); ++it) + { + strategy::expand::detail::point_loop + < + 2, dimension::value + >::apply(mbr, *it); + } + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_multipoint type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_multipoint type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_multipoint type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_MULTIPOINT_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope_point.hpp b/include/boost/geometry/strategies/spherical/envelope_point.hpp new file mode 100644 index 000000000..f09a39caa --- /dev/null +++ b/include/boost/geometry/strategies/spherical/envelope_point.hpp @@ -0,0 +1,111 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace envelope +{ + +struct spherical_point +{ + template + static inline void apply(Point const& point, Box& mbr) + { + Point normalized_point; + strategy::normalize::spherical_point::apply(point, normalized_point); + + typename point_type::type box_point; + + // transform units of input point to units of a box point + geometry::detail::envelope::transform_units(normalized_point, box_point); + + geometry::set(mbr, geometry::get<0>(box_point)); + geometry::set(mbr, geometry::get<1>(box_point)); + + geometry::set(mbr, geometry::get<0>(box_point)); + geometry::set(mbr, geometry::get<1>(box_point)); + + typedef geometry::detail::envelope::envelope_one_point + < + 2, dimension::value + > per_corner; + per_corner::apply(normalized_point, mbr); + per_corner::apply(normalized_point, mbr); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_point type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_point type; +}; + +template +struct default_strategy +{ + typedef strategy::envelope::spherical_point type; +}; + + +} + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::envelope + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_POINT_HPP diff --git a/include/boost/geometry/strategies/spherical/envelope_segment.hpp b/include/boost/geometry/strategies/spherical/envelope_segment.hpp index 98f085fe7..ce202965b 100644 --- a/include/boost/geometry/strategies/spherical/envelope_segment.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_segment.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -15,6 +15,7 @@ #include #include #include +#include namespace boost { namespace geometry { @@ -28,21 +29,25 @@ template > class spherical_segment { -public : - - inline spherical_segment() - {} +public: + typedef strategy::expand::spherical_box box_expand_strategy_type; + static inline box_expand_strategy_type get_box_expand_strategy() + { + return box_expand_strategy_type(); + } template - inline void - apply(Point1 const& point1, Point2 const& point2, Box& box) const + static inline void apply(Point1 const& point1, Point2 const& point2, + Box& box) { - Point1 p1_normalized = detail::return_normalized(point1); - Point2 p2_normalized = detail::return_normalized(point2); + Point1 p1_normalized; + strategy::normalize::spherical_point::apply(point1, p1_normalized); + Point2 p2_normalized; + strategy::normalize::spherical_point::apply(point2, p2_normalized); geometry::strategy::azimuth::spherical azimuth_spherical; - typedef typename coordinate_system::type::units units_type; + typedef typename geometry::detail::cs_angular_units::type units_type; geometry::detail::envelope::envelope_segment_impl ::template apply(geometry::get<0>(p1_normalized), @@ -61,14 +66,14 @@ namespace services { template -struct default_strategy +struct default_strategy { typedef strategy::envelope::spherical_segment type; }; template -struct default_strategy +struct default_strategy { typedef strategy::envelope::spherical_segment type; }; diff --git a/include/boost/geometry/strategies/spherical/expand_box.hpp b/include/boost/geometry/strategies/spherical/expand_box.hpp new file mode 100644 index 000000000..e3801861b --- /dev/null +++ b/include/boost/geometry/strategies/spherical/expand_box.hpp @@ -0,0 +1,98 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP + +#include +#include + +#include +#include + +#include +#include + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +struct box_on_spheroid +{ + template + static inline void apply(BoxOut& box_out, BoxIn const& box_in) + { + // normalize both boxes and convert box-in to be of type of box-out + BoxOut mbrs[2]; + strategy::envelope::spherical_box::apply(box_in, mbrs[0]); + strategy::envelope::spherical_box::apply(box_out, mbrs[1]); + + // compute the envelope of the two boxes + geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out); + } +}; + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +struct spherical_box + : detail::box_on_spheroid +{}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef spherical_box type; +}; + +template +struct default_strategy +{ + typedef spherical_box type; +}; + +template +struct default_strategy +{ + typedef spherical_box type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_BOX_HPP diff --git a/include/boost/geometry/strategies/spherical/expand_point.hpp b/include/boost/geometry/strategies/spherical/expand_point.hpp new file mode 100644 index 000000000..b2cff013a --- /dev/null +++ b/include/boost/geometry/strategies/spherical/expand_point.hpp @@ -0,0 +1,233 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France. + +// 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 +// 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. + +// Distributed under 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_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +// implementation for the spherical and geographic coordinate systems +template +struct point_loop_on_spheroid +{ + template + static inline void apply(Box& box, Point const& point) + { + typedef typename point_type::type box_point_type; + typedef typename coordinate_type::type box_coordinate_type; + typedef typename geometry::detail::cs_angular_units::type units_type; + + typedef math::detail::constants_on_spheroid + < + box_coordinate_type, + units_type + > constants; + + // normalize input point and input box + Point p_normalized; + strategy::normalize::spherical_point::apply(point, p_normalized); + + // transform input point to be of the same type as the box point + box_point_type box_point; + geometry::detail::envelope::transform_units(p_normalized, box_point); + + 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)); + geometry::set_from_radian(box, geometry::get_as_radian<0>(p_normalized)); + geometry::set_from_radian(box, geometry::get_as_radian<1>(p_normalized)); + + } else { + + strategy::normalize::spherical_box::apply(box, box); + + box_coordinate_type p_lon = geometry::get<0>(box_point); + box_coordinate_type p_lat = geometry::get<1>(box_point); + + 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)) + { + // 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; + } + } + + 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); + } +}; + + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +struct spherical_point +{ + template + static void apply(Box & box, Point const& point) + { + expand::detail::point_loop_on_spheroid + < + dimension::value, + ! boost::is_same::type, spherical_polar_tag>::value + >::apply(box, point); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef spherical_point type; +}; + +template +struct default_strategy +{ + typedef spherical_point type; +}; + +template +struct default_strategy +{ + typedef spherical_point type; +}; + + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_POINT_HPP diff --git a/include/boost/geometry/strategies/spherical/expand_segment.hpp b/include/boost/geometry/strategies/spherical/expand_segment.hpp new file mode 100644 index 000000000..75f4698ff --- /dev/null +++ b/include/boost/geometry/strategies/spherical/expand_segment.hpp @@ -0,0 +1,118 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// 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, 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 +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle + +// Distributed under 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_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +namespace strategy { namespace expand +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +struct segment_on_spheroid +{ + template + static inline void apply(Box& box, Segment const& segment, EnvelopeStrategy const& strategy) + { + Box mbrs[2]; + + // compute the envelope of the segment + typename point_type::type p[2]; + geometry::detail::assign_point_from_index<0>(segment, p[0]); + geometry::detail::assign_point_from_index<1>(segment, p[1]); + geometry::detail::envelope::envelope_segment + < + dimension::value + >::apply(p[0], p[1], mbrs[0], strategy); + + // normalize the box + strategy::envelope::spherical_box::apply(box, mbrs[1]); + + // compute the envelope of the two boxes + geometry::detail::envelope::envelope_range_of_boxes::apply(mbrs, box); + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +template +< + typename CalculationType = void +> +class spherical_segment +{ +public: + template + static inline void apply(Box& box, Segment const& segment) + { + detail::segment_on_spheroid::apply(box, segment, + strategy::envelope::spherical_segment()); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + +namespace services +{ + +template +struct default_strategy +{ + typedef spherical_segment type; +}; + +template +struct default_strategy +{ + typedef spherical_segment type; +}; + +} // namespace services + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}} // namespace strategy::expand + +}} // namespace boost::geometry + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_EXPAND_SEGMENT_HPP From 2a9370527162deecbfa4a236587713f13fc929a8 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:12:03 +0200 Subject: [PATCH 06/35] [disjoint][equals][strategies] Move CS-specific code of P/P disjoint/equals to strategies. --- .../detail/disjoint/point_point.hpp | 202 ++---------------- .../detail/equals/implementation.hpp | 30 +-- .../algorithms/detail/equals/point_point.hpp | 16 +- .../strategies/agnostic/point_in_point.hpp | 69 ++---- .../strategies/cartesian/point_in_point.hpp | 124 +++++++++++ .../strategies/spherical/point_in_point.hpp | 174 +++++++++++++++ 6 files changed, 362 insertions(+), 253 deletions(-) create mode 100644 include/boost/geometry/strategies/cartesian/point_in_point.hpp create mode 100644 include/boost/geometry/strategies/spherical/point_in_point.hpp diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp index 13ac34d71..33c1397e0 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -23,29 +23,15 @@ #include -#include - -#include -#include -#include -#include -#include -#include #include -#include -#include - -#include - -#include - -#include - -#include - #include +// For backward compatibility +#include +#include +#include + namespace boost { namespace geometry { @@ -56,169 +42,15 @@ namespace detail { namespace disjoint { -template -struct point_point_generic -{ - template - static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& ) - { - return apply(p1, p2); - } - - template - static inline bool apply(Point1 const& p1, Point2 const& p2) - { - if (! geometry::math::equals(get(p1), get(p2))) - { - return true; - } - return - point_point_generic::apply(p1, p2); - } -}; - -template -struct point_point_generic -{ - template - static inline bool apply(Point1 const&, Point2 const& ) - { - return false; - } -}; - - -class point_point_on_spheroid -{ -private: - template - struct are_same_points - { - static inline bool apply(Point1 const& point1, Point2 const& point2) - { - typedef typename helper_geometry::type helper_point_type1; - typedef typename helper_geometry::type helper_point_type2; - - helper_point_type1 point1_normalized - = return_normalized(point1); - helper_point_type2 point2_normalized - = return_normalized(point2); - - return point_point_generic - < - 0, dimension::value - >::apply(point1_normalized, point2_normalized); - } - }; - - template - struct are_same_points // points have different units - { - static inline bool apply(Point1 const& point1, Point2 const& point2) - { - typedef typename geometry::select_most_precise - < - typename fp_coordinate_type::type, - typename fp_coordinate_type::type - >::type calculation_type; - - typename helper_geometry - < - Point1, calculation_type, radian - >::type helper_point1, helper_point2; - - Point1 point1_normalized = return_normalized(point1); - Point2 point2_normalized = return_normalized(point2); - - geometry::transform(point1_normalized, helper_point1); - geometry::transform(point2_normalized, helper_point2); - - return point_point_generic - < - 0, dimension::value - >::apply(helper_point1, helper_point2); - } - }; - -public: - template - static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& ) - { - return apply(point1, point2); - } - - template - static inline bool apply(Point1 const& point1, Point2 const& point2) - { - return are_same_points - < - Point1, - Point2, - boost::is_same - < - typename coordinate_system::type::units, - typename coordinate_system::type::units - >::value - >::apply(point1, point2); - } -}; - - -template -< - typename Point1, typename Point2, - std::size_t Dimension, std::size_t DimensionCount, - typename CSTag1 = typename cs_tag::type, - typename CSTag2 = CSTag1 -> -struct point_point - : point_point -{}; - -template -< - typename Point1, typename Point2, - std::size_t Dimension, std::size_t DimensionCount -> -struct point_point - < - Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag - > : point_point_on_spheroid -{}; - -template -< - typename Point1, typename Point2, - std::size_t Dimension, std::size_t DimensionCount -> -struct point_point - < - Point1, Point2, Dimension, DimensionCount, geographic_tag - > : point_point_on_spheroid -{}; - -template -< - typename Point1, typename Point2, - std::size_t Dimension, std::size_t DimensionCount -> -struct point_point - : point_point_generic -{}; - - /*! \brief Internal utility function to detect of points are disjoint \note To avoid circular references */ -template -inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2) +template +inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2, + Strategy const& ) { - return point_point - < - Point1, Point2, - 0, dimension::type::value - >::apply(point1, point2); + return ! Strategy::apply(point1, point2); } @@ -226,8 +58,6 @@ inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2) #endif // DOXYGEN_NO_DETAIL - - #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { @@ -235,8 +65,14 @@ namespace dispatch template struct disjoint - : detail::disjoint::point_point -{}; +{ + template + static inline bool apply(Point1 const& point1, Point2 const& point2, + Strategy const& ) + { + return ! Strategy::apply(point1, point2); + } +}; } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/equals/implementation.hpp b/include/boost/geometry/algorithms/detail/equals/implementation.hpp index 310059a42..f39ae0b8b 100644 --- a/include/boost/geometry/algorithms/detail/equals/implementation.hpp +++ b/include/boost/geometry/algorithms/detail/equals/implementation.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015, 2016, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2016, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -64,13 +64,9 @@ template struct point_point { template - static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy) + static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& ) { - return ! detail::disjoint::point_point - < - Point1, Point2, - Dimension, DimensionCount - >::apply(point1, point2, strategy); + return Strategy::apply(point1, point2); } }; @@ -108,20 +104,28 @@ struct box_box struct segment_segment { template - static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& ) + static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, + Strategy const& strategy) { + typename Strategy::point_in_point_strategy_type const& + pt_pt_strategy = strategy.get_point_in_point_strategy(); + return equals::equals_point_point( indexed_point_view(segment1), - indexed_point_view(segment2) ) + indexed_point_view(segment2), + pt_pt_strategy) ? equals::equals_point_point( indexed_point_view(segment1), - indexed_point_view(segment2) ) + indexed_point_view(segment2), + pt_pt_strategy) : ( equals::equals_point_point( indexed_point_view(segment1), - indexed_point_view(segment2) ) + indexed_point_view(segment2), + pt_pt_strategy) && equals::equals_point_point( indexed_point_view(segment1), - indexed_point_view(segment2) ) + indexed_point_view(segment2), + pt_pt_strategy) ); } }; diff --git a/include/boost/geometry/algorithms/detail/equals/point_point.hpp b/include/boost/geometry/algorithms/detail/equals/point_point.hpp index 12daa85e9..06a784284 100644 --- a/include/boost/geometry/algorithms/detail/equals/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/equals/point_point.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013-2014. -// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -21,13 +21,10 @@ #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP -#include - namespace boost { namespace geometry { - #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace equals { @@ -36,17 +33,16 @@ namespace detail { namespace equals \brief Internal utility function to detect of points are disjoint \note To avoid circular references */ -template -inline bool equals_point_point(Point1 const& point1, Point2 const& point2) +template +inline bool equals_point_point(Point1 const& point1, Point2 const& point2, + Strategy const& ) { - return ! detail::disjoint::disjoint_point_point(point1, point2); + return Strategy::apply(point1, point2); } - }} // namespace detail::equals #endif // DOXYGEN_NO_DETAIL - }} // namespace boost::geometry #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP diff --git a/include/boost/geometry/strategies/agnostic/point_in_point.hpp b/include/boost/geometry/strategies/agnostic/point_in_point.hpp index d4692766c..051b87f40 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_point.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_point.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2017 Oracle and/or its affiliates. +// Copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -12,10 +12,12 @@ #ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP #define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP -#include -#include -#include +#include +#include + +#include +#include namespace boost { namespace geometry @@ -26,59 +28,32 @@ namespace strategy { namespace within template < - typename Point1, typename Point2 + typename Point1, typename Point2, + typename CSTag = typename cs_tag::type > struct point_in_point -{ - static inline bool apply(Point1 const& point1, Point2 const& point2) - { - return geometry::detail::equals::equals_point_point(point1, point2); - } -}; + : strategy::within::cartesian_point_point +{}; +template +struct point_in_point + : strategy::within::spherical_point_point +{}; -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +template +struct point_in_point + : strategy::within::spherical_point_point +{}; -namespace services -{ - -template -struct default_strategy -{ - typedef strategy::within::point_in_point - < - typename point_type::type, - typename point_type::type - > type; -}; - - -} // namespace services - -#endif +template +struct point_in_point + : strategy::within::spherical_point_point +{}; }} // namespace strategy::within -#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS -namespace strategy { namespace covered_by { namespace services -{ - -template -struct default_strategy -{ - typedef strategy::within::point_in_point - < - typename point_type::type, - typename point_type::type - > type; -}; - -}}} // namespace strategy::covered_by::services -#endif - - }} // namespace boost::geometry diff --git a/include/boost/geometry/strategies/cartesian/point_in_point.hpp b/include/boost/geometry/strategies/cartesian/point_in_point.hpp new file mode 100644 index 000000000..fc849dcd4 --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/point_in_point.hpp @@ -0,0 +1,124 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland + +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, 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. + +// 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_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP +#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP + +#include + +#include +#include +#include + +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace within +{ + + +template +struct point_point_generic +{ + template + static inline bool apply(Point1 const& p1, Point2 const& p2) + { + if (! geometry::math::equals(get(p1), get(p2))) + { + return false; + } + return + point_point_generic::apply(p1, p2); + } +}; + +template +struct point_point_generic +{ + template + static inline bool apply(Point1 const&, Point2 const& ) + { + return true; + } +}; + +}} // namespace detail::within +#endif // DOXYGEN_NO_DETAIL + + +namespace strategy { namespace within +{ + +struct cartesian_point_point +{ + template + static inline bool apply(Point1 const& point1, Point2 const& point2) + { + return geometry::detail::within::point_point_generic + < + 0, dimension::type::value + >::apply(point1, point2); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::within::cartesian_point_point type; +}; + +} // namespace services +#endif + + +}} // namespace strategy::within + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace strategy { namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::within::cartesian_point_point type; +}; + +}}} // namespace strategy::covered_by::services +#endif + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP diff --git a/include/boost/geometry/strategies/spherical/point_in_point.hpp b/include/boost/geometry/strategies/spherical/point_in_point.hpp new file mode 100644 index 000000000..1441ee650 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/point_in_point.hpp @@ -0,0 +1,174 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland + +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, 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. + +// 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_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP +#define BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include + +#include + +#include +#include + + +namespace boost { namespace geometry +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace within +{ + +class point_point_on_spheroid +{ +private: + template + struct are_same_points + { + static inline bool apply(Point1 const& point1, Point2 const& point2) + { + typedef typename helper_geometry::type helper_point_type1; + typedef typename helper_geometry::type helper_point_type2; + + helper_point_type1 point1_normalized; + strategy::normalize::spherical_point::apply(point1, point1_normalized); + helper_point_type2 point2_normalized; + strategy::normalize::spherical_point::apply(point2, point2_normalized); + + return point_point_generic + < + 0, dimension::value + >::apply(point1_normalized, point2_normalized); + } + }; + + template + struct are_same_points // points have different units + { + static inline bool apply(Point1 const& point1, Point2 const& point2) + { + typedef typename geometry::select_most_precise + < + typename fp_coordinate_type::type, + typename fp_coordinate_type::type + >::type calculation_type; + + typename helper_geometry + < + Point1, calculation_type, radian + >::type helper_point1, helper_point2; + + Point1 point1_normalized = return_normalized(point1); + Point2 point2_normalized = return_normalized(point2); + + geometry::transform(point1_normalized, helper_point1); + geometry::transform(point2_normalized, helper_point2); + + return point_point_generic + < + 0, dimension::value + >::apply(helper_point1, helper_point2); + } + }; + +public: + template + static inline bool apply(Point1 const& point1, Point2 const& point2) + { + return are_same_points + < + Point1, + Point2, + boost::is_same + < + typename detail::cs_angular_units::type, + typename detail::cs_angular_units::type + >::value + >::apply(point1, point2); + } +}; + +}} // namespace detail::within +#endif // DOXYGEN_NO_DETAIL + + +namespace strategy { namespace within +{ + +struct spherical_point_point + : geometry::detail::within::point_point_on_spheroid +{}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +struct default_strategy +{ + typedef strategy::within::spherical_point_point type; +}; + +} // namespace services +#endif + + +}} // namespace strategy::within + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace strategy { namespace covered_by { namespace services +{ + +template +struct default_strategy +{ + typedef strategy::within::spherical_point_point type; +}; + +}}} // namespace strategy::covered_by::services +#endif + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_STRATEGY_SPHERICAL_POINT_IN_POINT_HPP From 64863cceeb3d1afa725a55aca7e3b6f9e64bb494 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:12:34 +0200 Subject: [PATCH 07/35] [strategies] Update WRT recent changes: - use CS-specific normalization strategies instead of algorithm. - add lower-level strategies getters (point in point, envelope, expand). - pass strategy to equals_point_point() --- .../cartesian/distance_projected_point.hpp | 8 +++- .../strategies/cartesian/intersection.hpp | 38 ++++++++++++++---- .../cartesian/point_in_poly_winding.hpp | 10 ++++- .../strategies/cartesian/side_by_triangle.hpp | 28 +++++++++---- .../geographic/disjoint_segment_box.hpp | 10 ++++- .../geographic/distance_cross_track.hpp | 5 ++- .../geographic/distance_segment_box.hpp | 13 ++++++- .../strategies/geographic/intersection.hpp | 37 +++++++++++++++--- .../geometry/strategies/geographic/side.hpp | 11 +++++- .../spherical/disjoint_segment_box.hpp | 8 +++- .../spherical/distance_cross_track.hpp | 10 ++++- .../spherical/distance_segment_box.hpp | 14 ++++--- .../strategies/spherical/intersection.hpp | 39 ++++++++++++++++--- .../spherical/point_in_poly_winding.hpp | 10 ++++- .../geometry/strategies/spherical/ssf.hpp | 15 +++++-- 15 files changed, 205 insertions(+), 51 deletions(-) diff --git a/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp b/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp index 5aaa9db43..37a6b6e80 100644 --- a/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp +++ b/include/boost/geometry/strategies/cartesian/distance_projected_point.hpp @@ -4,10 +4,11 @@ // Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2014. -// Modifications copyright (c) 2014, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// 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. @@ -35,6 +36,7 @@ #include #include #include +#include #include @@ -75,6 +77,8 @@ template class projected_point { public : + typedef within::cartesian_point_point equals_point_point_strategy_type; + // The three typedefs below are necessary to calculate distances // from segments defined in integer coordinates. diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index 10fd73ba5..576994ba3 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2016, 2017. -// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017, 2018. +// Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -35,7 +35,9 @@ #include #include -#include +#include +#include +#include #include #include #include @@ -132,14 +134,34 @@ struct cartesian_segments return strategy_type(); } - typedef envelope::cartesian_segment - envelope_strategy_type; + typedef envelope::cartesian envelope_strategy_type; static inline envelope_strategy_type get_envelope_strategy() { return envelope_strategy_type(); } + typedef expand::cartesian_segment expand_strategy_type; + + static inline expand_strategy_type get_expand_strategy() + { + return expand_strategy_type(); + } + + typedef within::cartesian_point_point point_in_point_strategy_type; + + static inline point_in_point_strategy_type get_point_in_point_strategy() + { + return point_in_point_strategy_type(); + } + + typedef within::cartesian_point_point equals_point_point_strategy_type; + + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + template struct segment_intersection_info { @@ -314,12 +336,12 @@ struct cartesian_segments BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); using geometry::detail::equals::equals_point_point; - bool const a_is_point = equals_point_point(robust_a1, robust_a2); - bool const b_is_point = equals_point_point(robust_b1, robust_b2); + bool const a_is_point = equals_point_point(robust_a1, robust_a2, point_in_point_strategy_type()); + bool const b_is_point = equals_point_point(robust_b1, robust_b2, point_in_point_strategy_type()); if(a_is_point && b_is_point) { - return equals_point_point(robust_a1, robust_b2) + return equals_point_point(robust_a1, robust_b2, point_in_point_strategy_type()) ? Policy::degenerate(a, true) : Policy::disjoint() ; diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index c41bc9b83..d7546d710 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2016, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018. +// Modifications copyright (c) 2013-2018 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 @@ -103,6 +103,12 @@ public: return side_strategy_type::get_disjoint_strategy(); } + typedef typename side_strategy_type::equals_point_point_strategy_type equals_point_point_strategy_type; + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return side_strategy_type::get_equals_point_point_strategy(); + } + // Typedefs and static methods to fulfill the concept typedef Point point_type; typedef PointOfSegment segment_point_type; diff --git a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp b/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp index 91bbee7bb..9760f560c 100644 --- a/include/boost/geometry/strategies/cartesian/side_by_triangle.hpp +++ b/include/boost/geometry/strategies/cartesian/side_by_triangle.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, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017, 2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -29,7 +29,8 @@ #include #include -#include +#include +#include #include #include @@ -70,7 +71,7 @@ class side_by_triangle }; public : - typedef strategy::envelope::cartesian_segment envelope_strategy_type; + typedef strategy::envelope::cartesian envelope_strategy_type; static inline envelope_strategy_type get_envelope_strategy() { @@ -84,6 +85,12 @@ public : return disjoint_strategy_type(); } + typedef strategy::within::cartesian_point_point equals_point_point_strategy_type; + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + // Template member function, because it is not always trivial // or convenient to explicitly mention the typenames in the // strategy-struct itself. @@ -166,9 +173,9 @@ public : // For robustness purposes, first check if any two points are // the same; in this case simply return that the points are // collinear - if (geometry::detail::equals::equals_point_point(p1, p2) - || geometry::detail::equals::equals_point_point(p1, p) - || geometry::detail::equals::equals_point_point(p2, p)) + if (equals_point_point(p1, p2) + || equals_point_point(p1, p) + || equals_point_point(p2, p)) { return PromotedType(0); } @@ -258,6 +265,13 @@ public : : -1; } +private: + template + static inline bool equals_point_point(P1 const& p1, P2 const& p2) + { + typedef equals_point_point_strategy_type strategy_t; + return geometry::detail::equals::equals_point_point(p1, p2, strategy_t()); + } }; diff --git a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp index afc9d6677..963e280d7 100644 --- a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -29,6 +29,8 @@ #include #include +#include + #include #include #include @@ -89,7 +91,11 @@ public: > azimuth_geographic(m_spheroid); return geometry::detail::disjoint::disjoint_segment_box_sphere_or_spheroid - ::apply(segment, box, azimuth_geographic); + < + geographic_tag + >::apply(segment, box, + azimuth_geographic, + strategy::normalize::spherical_point()); } private: diff --git a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp index f84bb4134..eddd50302 100644 --- a/include/boost/geometry/strategies/geographic/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/geographic/distance_cross_track.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -84,6 +85,8 @@ template class geographic_cross_track { public : + typedef within::spherical_point_point equals_point_point_strategy_type; + template struct return_type : promote_floating_point @@ -105,7 +108,7 @@ public : inline typename return_type::type apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const { - typedef typename coordinate_system::type::units units_type; + typedef typename geometry::detail::cs_angular_units::type units_type; return (apply(get<0>(sp1), get<1>(sp1), get<0>(sp2), get<1>(sp2), diff --git a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp index 6bde78ca2..34b3797e7 100644 --- a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp @@ -10,8 +10,18 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP +#include + #include +#include +#include +#include +#include + +#include +#include + namespace boost { namespace geometry { @@ -107,7 +117,8 @@ struct geographic_segment_box ReturnType >(p0,p1,top_left,top_right,bottom_left,bottom_right, geographic_segment_box(), - az_strategy, es_strategy); + az_strategy, es_strategy, + normalize::spherical_point()); } template diff --git a/include/boost/geometry/strategies/geographic/intersection.hpp b/include/boost/geometry/strategies/geographic/intersection.hpp index 76c83bb53..b5db0889b 100644 --- a/include/boost/geometry/strategies/geographic/intersection.hpp +++ b/include/boost/geometry/strategies/geographic/intersection.hpp @@ -38,10 +38,11 @@ #include #include -#include +#include #include #include #include +#include #include #include #include @@ -141,7 +142,7 @@ struct geographic_segments return strategy_type(m_spheroid); } - typedef envelope::geographic_segment + typedef envelope::geographic envelope_strategy_type; inline envelope_strategy_type get_envelope_strategy() const @@ -149,6 +150,28 @@ struct geographic_segments return envelope_strategy_type(m_spheroid); } + typedef expand::geographic_segment + expand_strategy_type; + + inline expand_strategy_type get_expand_strategy() const + { + return expand_strategy_type(m_spheroid); + } + + typedef within::spherical_point_point point_in_point_strategy_type; + + static inline point_in_point_strategy_type get_point_in_point_strategy() + { + return point_in_point_strategy_type(); + } + + typedef within::spherical_point_point equals_point_point_strategy_type; + + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; template @@ -276,7 +299,6 @@ private: spheroid_type spheroid = formula::unit_spheroid(m_spheroid); // TODO: check only 2 first coordinates here? - using geometry::detail::equals::equals_point_point; bool a_is_point = equals_point_point(a1, a2); bool b_is_point = equals_point_point(b1, b2); @@ -679,7 +701,6 @@ private: dist_b1_b2 = res_b1_b2.distance; // assign the IP if some endpoints overlap - using geometry::detail::equals::equals_point_point; if (equals_point_point(a1, b1)) { lon = a1_lon; @@ -879,7 +900,6 @@ private: P1 const& ai, P2 const& b1) { static CalcT const c0 = 0; - using geometry::detail::equals::equals_point_point; return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1)); } @@ -939,6 +959,13 @@ private: ip_flag; } + template + static inline bool equals_point_point(Point1 const& point1, Point2 const& point2) + { + return detail::equals::equals_point_point(point1, point2, + point_in_point_strategy_type()); + } + private: Spheroid m_spheroid; }; diff --git a/include/boost/geometry/strategies/geographic/side.hpp b/include/boost/geometry/strategies/geographic/side.hpp index 1201dc2f6..e22718f32 100644 --- a/include/boost/geometry/strategies/geographic/side.hpp +++ b/include/boost/geometry/strategies/geographic/side.hpp @@ -28,9 +28,10 @@ #include #include -#include +#include #include #include +#include //#include @@ -64,7 +65,7 @@ template class geographic { public: - typedef strategy::envelope::geographic_segment + typedef strategy::envelope::geographic < FormulaPolicy, Spheroid, @@ -88,6 +89,12 @@ public: return disjoint_strategy_type(m_model); } + typedef strategy::within::spherical_point_point equals_point_point_strategy_type; + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + geographic() {} diff --git a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp index bda62a77f..1432f7d89 100644 --- a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -67,7 +67,11 @@ struct segment_box_spherical geometry::strategy::azimuth::spherical azimuth_strategy; return geometry::detail::disjoint::disjoint_segment_box_sphere_or_spheroid - ::apply(segment, box, azimuth_strategy); + < + spherical_equatorial_tag + >::apply(segment, box, + azimuth_strategy, + strategy::normalize::spherical_point()); } }; diff --git a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp index 97a36b8b2..d9f1ac350 100644 --- a/include/boost/geometry/strategies/spherical/distance_cross_track.hpp +++ b/include/boost/geometry/strategies/spherical/distance_cross_track.hpp @@ -2,11 +2,12 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014-2017. -// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2014-2018. +// Modifications copyright (c) 2014-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 +// 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 @@ -30,6 +31,7 @@ #include #include #include +#include #include #include @@ -326,6 +328,8 @@ template class cross_track { public : + typedef within::spherical_point_point equals_point_point_strategy_type; + template struct return_type : promote_floating_point @@ -505,6 +509,8 @@ template class cross_track { public : + typedef within::spherical_point_point equals_point_point_strategy_type; + template struct return_type : promote_floating_point diff --git a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp index d5647182a..b334a921d 100644 --- a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp @@ -2,6 +2,7 @@ // Copyright (c) 2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle +// 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 @@ -29,7 +30,8 @@ struct generic_segment_box typename BoxPoint, typename SegmentBoxStrategy, typename AzimuthStrategy, - typename EnvelopeSegmentStrategy + typename EnvelopeSegmentStrategy, + typename NormalizePointStrategy > static inline ReturnType segment_below_of_box( SegmentPoint const& p0, @@ -39,8 +41,9 @@ struct generic_segment_box BoxPoint const& bottom_left, BoxPoint const& bottom_right, SegmentBoxStrategy const& sb_strategy, - AzimuthStrategy & az_strategy, - EnvelopeSegmentStrategy & es_strategy) + AzimuthStrategy const& az_strategy, + EnvelopeSegmentStrategy const& es_strategy, + NormalizePointStrategy const& np_strategy) { ReturnType result; typename LessEqual::other less_equal; @@ -66,7 +69,7 @@ struct generic_segment_box SegmentPoint p_max; disjoint_info_type disjoint_result = disjoint_sb:: - apply(seg, input_box, az_strategy, p_max); + apply(seg, input_box, p_max, az_strategy, np_strategy); if (disjoint_result == disjoint_info_type::intersect) //intersect { @@ -222,7 +225,8 @@ struct spherical_segment_box ReturnType >(p0,p1,top_left,top_right,bottom_left,bottom_right, spherical_segment_box(), - az_strategy, es_strategy); + az_strategy, es_strategy, + normalize::spherical_point()); } template diff --git a/include/boost/geometry/strategies/spherical/intersection.hpp b/include/boost/geometry/strategies/spherical/intersection.hpp index 2bdc8b51a..2141e626a 100644 --- a/include/boost/geometry/strategies/spherical/intersection.hpp +++ b/include/boost/geometry/strategies/spherical/intersection.hpp @@ -42,7 +42,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -149,7 +150,7 @@ struct ecef_segments return strategy_type(); } - typedef envelope::spherical_segment + typedef envelope::spherical envelope_strategy_type; static inline envelope_strategy_type get_envelope_strategy() @@ -157,6 +158,28 @@ struct ecef_segments return envelope_strategy_type(); } + typedef expand::spherical_segment + expand_strategy_type; + + static inline expand_strategy_type get_expand_strategy() + { + return expand_strategy_type(); + } + + typedef within::spherical_point_point point_in_point_strategy_type; + + static inline point_in_point_strategy_type get_point_in_point_strategy() + { + return point_in_point_strategy_type(); + } + + typedef within::spherical_point_point equals_point_point_strategy_type; + + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; // segment_intersection_info cannot outlive relate_ecef_segments @@ -252,7 +275,6 @@ struct ecef_segments BOOST_CONCEPT_ASSERT( (concepts::ConstSegment) ); // TODO: check only 2 first coordinates here? - using geometry::detail::equals::equals_point_point; bool a_is_point = equals_point_point(a1, a2); bool b_is_point = equals_point_point(b1, b2); @@ -645,7 +667,6 @@ private: } // reassign the IP if some endpoints overlap - using geometry::detail::equals::equals_point_point; if (is_near_a1) { if (is_near_b1 && equals_point_point(a1, b1)) @@ -822,7 +843,6 @@ private: P1 const& ai, P2 const& b1) { static CalcT const c0 = 0; - using geometry::detail::equals::equals_point_point; return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1)); } @@ -850,6 +870,13 @@ private: : ca1 < cb2 ? 4 : 2 ); } + + template + static inline bool equals_point_point(Point1 const& point1, Point2 const& point2) + { + return detail::equals::equals_point_point(point1, point2, + point_in_point_strategy_type()); + } }; struct spherical_segments_calc_policy @@ -921,7 +948,7 @@ struct spherical_segments_calc_policy multiply_value(ip2, coord_t(-1)); return true; - } + } }; diff --git a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp index c942cbe46..803559a5f 100644 --- a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2016, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018. +// Modifications copyright (c) 2013-2018 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 @@ -140,6 +140,12 @@ public: return m_side_strategy.get_disjoint_strategy(); } + typedef typename SideStrategy::equals_point_point_strategy_type equals_point_point_strategy_type; + inline equals_point_point_strategy_type get_equals_point_point_strategy() const + { + return m_side_strategy.get_equals_point_point_strategy(); + } + spherical_winding_base() {} diff --git a/include/boost/geometry/strategies/spherical/ssf.hpp b/include/boost/geometry/strategies/spherical/ssf.hpp index 03f5428ed..18c547ced 100644 --- a/include/boost/geometry/strategies/spherical/ssf.hpp +++ b/include/boost/geometry/strategies/spherical/ssf.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2011-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016, Oracle and/or its affiliates. +// This file was modified by Oracle on 2016, 2018. +// Modifications copyright (c) 2016-2018, 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, @@ -24,8 +24,9 @@ #include #include -#include +#include //#include +#include namespace boost { namespace geometry @@ -84,7 +85,7 @@ class spherical_side_formula { public : - typedef strategy::envelope::spherical_segment envelope_strategy_type; + typedef strategy::envelope::spherical envelope_strategy_type; static inline envelope_strategy_type get_envelope_strategy() { @@ -98,6 +99,12 @@ public : return disjoint_strategy_type(); } + typedef strategy::within::spherical_point_point equals_point_point_strategy_type; + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + template static inline int apply(P1 const& p1, P2 const& p2, P const& p) { From 203618b404d119a5a65ba5838bfd3a2e17ea2f24 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:19:21 +0200 Subject: [PATCH 08/35] [algorithms] Remove point_on_border Midpoint parameter as unneeded, cartesian-only hack. If using this parameter changes the result it means that a different method should be used. Using it does not solve the real problem, it only hides it. Consider a polygon in another, touching at the first vertex. Checking the midpoint of the first segment of contained polygon could result in finding out that the polygon is inside. However if the segment was collinear to the containing polygon's segment or this polygon had vertex exactly at the checked midpoint the result would be the same as using the first point of the contained polygon. --- .../algorithms/detail/point_on_border.hpp | 170 ++++-------------- 1 file changed, 34 insertions(+), 136 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/point_on_border.hpp b/include/boost/geometry/algorithms/detail/point_on_border.hpp index 831081aa6..7116586a4 100644 --- a/include/boost/geometry/algorithms/detail/point_on_border.hpp +++ b/include/boost/geometry/algorithms/detail/point_on_border.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2018 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 @@ -56,117 +56,47 @@ struct get_point } }; -template -struct midpoint_helper -{ - template - static inline bool apply(Point& p, InputPoint const& p1, InputPoint const& p2) - { - typename coordinate_type::type const two = 2; - set(p, - (get(p1) + get(p2)) / two); - return midpoint_helper::apply(p, p1, p2); - } -}; - -template -struct midpoint_helper -{ - template - static inline bool apply(Point& , InputPoint const& , InputPoint const& ) - { - return true; - } -}; - - -template struct point_on_range { // Version with iterator template static inline bool apply(Point& point, Iterator begin, Iterator end) { - Iterator it = begin; - if (it == end) + if (begin == end) { return false; } - if (! Midpoint) - { - geometry::detail::conversion::convert_point_to_point(*it, point); - return true; - } - - Iterator prev = it++; - - // Go to next non-duplicate point - while (it != end - && detail::equals::equals_point_point(*it, *prev)) - { - prev = it++; - } - if (it != end) - { - return midpoint_helper - < - Point, - 0, dimension::value - >::apply(point, *prev, *it); - } - return false; + geometry::detail::conversion::convert_point_to_point(*begin, point); + return true; } // Version with range template static inline bool apply(Point& point, Range const& range) { - typedef typename geometry::cs_tag::type cs_tag; - BOOST_STATIC_ASSERT((! Midpoint || boost::is_same::value)); - return apply(point, boost::begin(range), boost::end(range)); } }; -template struct point_on_polygon { template static inline bool apply(Point& point, Polygon const& polygon) { - return point_on_range - < - Midpoint - >::apply(point, exterior_ring(polygon)); + return point_on_range::apply(point, exterior_ring(polygon)); } }; -template struct point_on_box { template static inline bool apply(Point& point, Box const& box) { - if (BOOST_GEOMETRY_CONDITION(Midpoint)) - { - Point p1, p2; - detail::assign::assign_box_2d_corner(box, p1); - detail::assign::assign_box_2d_corner(box, p2); - midpoint_helper - < - Point, - 0, dimension::value - >::apply(point, p1, p2); - } - else - { - detail::assign::assign_box_2d_corner(box, point); - } - + detail::assign::assign_box_2d_corner(box, point); return true; } }; @@ -206,60 +136,50 @@ namespace dispatch { -template -< - typename GeometryTag, - bool Midpoint - -> +template struct point_on_border {}; - -template -struct point_on_border +template <> +struct point_on_border : detail::point_on_border::get_point {}; +template <> +struct point_on_border + : detail::point_on_border::point_on_range +{}; -template -struct point_on_border - : detail::point_on_border::point_on_range +template <> +struct point_on_border + : detail::point_on_border::point_on_range +{}; + +template <> +struct point_on_border + : detail::point_on_border::point_on_polygon +{}; + +template <> +struct point_on_border + : detail::point_on_border::point_on_box {}; -template -struct point_on_border - : detail::point_on_border::point_on_range -{}; - - -template -struct point_on_border - : detail::point_on_border::point_on_polygon -{}; - - -template -struct point_on_border - : detail::point_on_border::point_on_box -{}; - - -template -struct point_on_border +template <> +struct point_on_border : detail::point_on_border::point_on_multi < - detail::point_on_border::point_on_polygon + detail::point_on_border::point_on_polygon > {}; -template -struct point_on_border +template <> +struct point_on_border : detail::point_on_border::point_on_multi < - detail::point_on_border::point_on_range + detail::point_on_border::point_on_range > {}; @@ -286,33 +206,11 @@ inline bool point_on_border(Point& point, Geometry const& geometry) return dispatch::point_on_border < - typename tag::type, - false + typename tag::type >::apply(point, geometry); } -/*! -\tparam Midpoint boolean flag, true if the point should not be a vertex, but some point - in between of two vertices -\note for Midpoint, it is not taken from two consecutive duplicate vertices, - (unless there are no other). - */ -/* -template -inline bool point_on_border(Point& point, Geometry const& geometry) -{ - concepts::check(); - concepts::check(); - - return dispatch::point_on_border - < - typename tag::type, - Midpoint - >::apply(point, geometry); -} -*/ - }} // namespace boost::geometry From 6c322e6625bc4b61fb3e359a2299f095e20f8dfb Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:26:10 +0200 Subject: [PATCH 09/35] [algorithms] Update various algorithms after recent changes: - use equals P/P in equals_point_point extracted from strategy passed to algorithm - remove Midpoint of point_on_border (this exposes an error in is_valid) - use envelope and expand strategies extracted from strategy passed to algorithm - change union's default strategy (relate v.s. intersection). --- .../detail/disjoint/segment_box.hpp | 45 ++++----- .../algorithms/detail/is_valid/polygon.hpp | 5 +- .../detail/overlay/append_no_duplicates.hpp | 29 ++++-- .../overlay/append_no_dups_or_spikes.hpp | 31 ++++-- .../detail/overlay/clip_linestring.hpp | 21 +++- .../detail/overlay/copy_segments.hpp | 8 +- .../algorithms/detail/overlay/follow.hpp | 24 ++--- .../overlay/get_turn_info_for_endpoint.hpp | 21 ++-- .../detail/overlay/get_turn_info_la.hpp | 59 ++++++++---- .../detail/overlay/get_turn_info_ll.hpp | 30 +++--- .../algorithms/detail/overlay/get_turns.hpp | 34 ++++--- .../detail/overlay/pointlike_pointlike.hpp | 14 +-- .../detail/overlay/self_turn_points.hpp | 7 +- .../algorithms/detail/relate/areal_areal.hpp | 34 ++++--- .../detail/relate/boundary_checker.hpp | 37 ++++--- .../detail/relate/follow_helpers.hpp | 11 ++- .../algorithms/detail/relate/linear_areal.hpp | 54 +++++++---- .../detail/relate/linear_linear.hpp | 50 +++++++--- .../detail/relate/multi_point_geometry.hpp | 69 +++++++++---- .../detail/relate/point_geometry.hpp | 10 +- .../algorithms/detail/relate/point_point.hpp | 20 ++-- .../detail/relate/topology_check.hpp | 64 +++++++------ .../detail/sections/sectionalize.hpp | 96 +++++++++++++------ .../detail/within/point_in_geometry.hpp | 25 +++-- .../boost/geometry/algorithms/is_convex.hpp | 14 ++- .../boost/geometry/algorithms/simplify.hpp | 22 ++++- include/boost/geometry/algorithms/union.hpp | 9 +- 27 files changed, 542 insertions(+), 301 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index baa4cf83d..9896245e8 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. // Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-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 @@ -50,21 +50,6 @@ namespace detail { namespace disjoint template struct disjoint_segment_box_sphere_or_spheroid { -private: - - template - static inline void swap(CT& lon1, - CT& lat1, - CT& lon2, - CT& lat2) - { - std::swap(lon1, lon2); - std::swap(lat1, lat2); - } - - -public: - struct disjoint_info { enum type @@ -82,21 +67,24 @@ public: operator T () const; }; - template + template static inline bool apply(Segment const& segment, Box const& box, - Strategy const& azimuth_strategy) + AzimuthStrategy const& azimuth_strategy, + NormalizeStrategy const& normalize_strategy) { typedef typename point_type::type segment_point; segment_point vertex; - return (apply(segment, box, azimuth_strategy, vertex) != disjoint_info::intersect); + return apply(segment, box, vertex, azimuth_strategy, normalize_strategy) + != disjoint_info::intersect; } - template + template static inline disjoint_info apply(Segment const& segment, Box const& box, - Strategy const& azimuth_strategy, - P& vertex) + P& vertex, + AzimuthStrategy const& azimuth_strategy, + NormalizeStrategy const& ) { assert_dimension_equal(); @@ -122,10 +110,10 @@ public: typedef typename coordinate_type::type CT; - segment_point_type p0_normalized = - geometry::detail::return_normalized(p0); - segment_point_type p1_normalized = - geometry::detail::return_normalized(p1); + segment_point_type p0_normalized; + NormalizeStrategy::apply(p0, p0_normalized); + segment_point_type p1_normalized; + NormalizeStrategy::apply(p1, p1_normalized); CT lon1 = geometry::get_as_radian<0>(p0_normalized); CT lat1 = geometry::get_as_radian<1>(p0_normalized); @@ -134,7 +122,8 @@ public: if (lon1 > lon2) { - swap(lon1, lat1, lon2, lat2); + std::swap(lon1, lon2); + std::swap(lat1, lat2); } //Compute alp1 outside envelope and pass it to envelope_segment_impl diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index 5c6229b79..b3f6c8228 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -2,7 +2,7 @@ // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// Copyright (c) 2014-2017, Oracle and/or its affiliates. +// Copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -221,12 +221,11 @@ protected: inline bool is_within(Item const& first, Item const& second) { typename point_type::type point; - typedef detail::point_on_border::point_on_range pob; // TODO: this should check for a point on the interior, instead // of on border. Or it should check using the overlap function. - return pob::apply(point, points_begin(first), points_end(first)) + return geometry::point_on_border(point, first) && geometry::within(point, second, m_strategy); } diff --git a/include/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp b/include/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp index 0fd1fe4de..34e9fc79c 100644 --- a/include/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp @@ -2,6 +2,11 @@ // Copyright (c) 2007-2012 Barend Gehrels, 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 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) @@ -10,11 +15,10 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP -#include - #include #include +#include namespace boost { namespace geometry @@ -26,11 +30,24 @@ namespace detail { namespace overlay { template -inline void append_no_duplicates(Range& range, Point const& point, bool force = false) +inline void append_with_duplicates(Range& range, Point const& point) { - if (boost::size(range) == 0 - || force - || ! geometry::detail::equals::equals_point_point(*(boost::end(range)-1), point)) +#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION + std::cout << " add: (" + << geometry::get<0>(point) << ", " << geometry::get<1>(point) << ")" + << std::endl; +#endif + geometry::append(range, point); +} + +template +inline void append_no_duplicates(Range& range, Point const& point, + EqPPStrategy const& strategy) +{ + if ( boost::empty(range) + || ! geometry::detail::equals::equals_point_point(geometry::range::back(range), + point, + strategy) ) { #ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION std::cout << " add: (" diff --git a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp index 724996ae3..bc9db32f8 100644 --- a/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -15,6 +15,7 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPS_OR_SPIKES_HPP #include +#include #include #include @@ -33,12 +34,13 @@ namespace detail { namespace overlay { // TODO: move this / rename this -template +template inline bool points_equal_or_close(Point1 const& point1, Point2 const& point2, + EqualsStrategy const& strategy, RobustPolicy const& robust_policy) { - if (detail::equals::equals_point_point(point1, point2)) + if (detail::equals::equals_point_point(point1, point2, strategy)) { return true; } @@ -59,7 +61,14 @@ inline bool points_equal_or_close(Point1 const& point1, geometry::recalculate(point1_rob, point1, robust_policy); geometry::recalculate(point2_rob, point2, robust_policy); - return detail::equals::equals_point_point(point1_rob, point2_rob); + // Only if this is the case the same strategy can be used. + BOOST_STATIC_ASSERT((boost::is_same + < + typename geometry::cs_tag::type, + typename geometry::cs_tag::type + >::value)); + + return detail::equals::equals_point_point(point1_rob, point2_rob, strategy); } @@ -76,8 +85,10 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point, // The code below this condition checks all spikes/dups // for geometries >= 3 points. // So we have to check the first potential duplicate differently - if (boost::size(range) == 1 - && points_equal_or_close(*(boost::begin(range)), point, robust_policy)) + if ( boost::size(range) == 1 + && points_equal_or_close(*(boost::begin(range)), point, + strategy.get_equals_point_point_strategy(), + robust_policy) ) { return; } @@ -113,8 +124,10 @@ inline void append_no_collinear(Range& range, Point const& point, // The code below this condition checks all spikes/dups // for geometries >= 3 points. // So we have to check the first potential duplicate differently - if (boost::size(range) == 1 - && points_equal_or_close(*(boost::begin(range)), point, robust_policy)) + if ( boost::size(range) == 1 + && points_equal_or_close(*(boost::begin(range)), point, + strategy.get_equals_point_point_strategy(), + robust_policy) ) { return; } diff --git a/include/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp b/include/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp index 8cb37d695..ead9e7014 100644 --- a/include/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/clip_linestring.hpp @@ -2,10 +2,11 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015. -// Modifications copyright (c) 2015 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 Menelaos Karavelas, on behalf of Oracle +// 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 @@ -24,6 +25,8 @@ #include #include +#include + namespace boost { namespace geometry { @@ -83,6 +86,15 @@ private: public: +// TODO: Temporary, this strategy should be moved, it is cartesian-only + + typedef strategy::within::cartesian_point_point equals_point_point_strategy_type; + + static inline equals_point_point_strategy_type get_equals_point_point_strategy() + { + return equals_point_point_strategy_type(); + } + inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const { typedef typename select_coordinate_type::type coordinate_type; @@ -224,9 +236,10 @@ OutputIterator clip_range_with_box(Box const& b, Range const& range, // b. Add p1 only if it is the first point, then add p2 if (boost::empty(line_out)) { - detail::overlay::append_no_duplicates(line_out, p1, true); + detail::overlay::append_with_duplicates(line_out, p1); } - detail::overlay::append_no_duplicates(line_out, p2); + detail::overlay::append_no_duplicates(line_out, p2, + strategy.get_equals_point_point_strategy()); // c. If c2 is clipped, finish the line if (c2) diff --git a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp index c6f540a97..286ac4b71 100644 --- a/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/copy_segments.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -137,11 +137,11 @@ private: template static inline void append_to_output(RangeOut& current_output, Point const& point, - SideStrategy const&, + SideStrategy const& strategy, RobustPolicy const&, boost::false_type const&) { - detail::overlay::append_no_duplicates(current_output, point); + detail::overlay::append_no_duplicates(current_output, point, strategy.get_equals_point_point_strategy()); } public: diff --git a/include/boost/geometry/algorithms/detail/overlay/follow.hpp b/include/boost/geometry/algorithms/detail/overlay/follow.hpp index d948c4f67..5d62e0c47 100644 --- a/include/boost/geometry/algorithms/detail/overlay/follow.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/follow.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -159,7 +159,7 @@ struct action_selector typename LineString, typename Point, typename Operation, - typename SideStrategy, + typename Strategy, typename RobustPolicy > static inline void enter(LineStringOut& current_piece, @@ -167,13 +167,13 @@ struct action_selector segment_identifier& segment_id, signed_size_type , Point const& point, Operation const& operation, - SideStrategy const& , + Strategy const& strategy, RobustPolicy const& , OutputIterator& ) { // On enter, append the intersection point and remember starting point // TODO: we don't check on spikes for linestrings (?). Consider this. - detail::overlay::append_no_duplicates(current_piece, point); + detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy()); segment_id = operation.seg_id; } @@ -184,7 +184,7 @@ struct action_selector typename LineString, typename Point, typename Operation, - typename SideStrategy, + typename Strategy, typename RobustPolicy > static inline void leave(LineStringOut& current_piece, @@ -192,7 +192,7 @@ struct action_selector segment_identifier& segment_id, signed_size_type index, Point const& point, Operation const& , - SideStrategy const& strategy, + Strategy const& strategy, RobustPolicy const& robust_policy, OutputIterator& out) { @@ -202,7 +202,7 @@ struct action_selector < false, RemoveSpikes >::apply(linestring, segment_id, index, strategy, robust_policy, current_piece); - detail::overlay::append_no_duplicates(current_piece, point); + detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy()); if (::boost::size(current_piece) > 1) { *out++ = current_piece; @@ -260,7 +260,7 @@ struct action_selector typename LineString, typename Point, typename Operation, - typename SideStrategy, + typename Strategy, typename RobustPolicy > static inline void enter(LineStringOut& current_piece, @@ -268,7 +268,7 @@ struct action_selector segment_identifier& segment_id, signed_size_type index, Point const& point, Operation const& operation, - SideStrategy const& strategy, + Strategy const& strategy, RobustPolicy const& robust_policy, OutputIterator& out) { @@ -283,7 +283,7 @@ struct action_selector typename LineString, typename Point, typename Operation, - typename SideStrategy, + typename Strategy, typename RobustPolicy > static inline void leave(LineStringOut& current_piece, @@ -291,7 +291,7 @@ struct action_selector segment_identifier& segment_id, signed_size_type index, Point const& point, Operation const& operation, - SideStrategy const& strategy, + Strategy const& strategy, RobustPolicy const& robust_policy, OutputIterator& out) { diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp index 48716634c..9b67b07d3 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_for_endpoint.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -108,11 +108,12 @@ namespace detail { namespace overlay { class linear_intersections { public: - template + template linear_intersections(Point1 const& pi, Point2 const& qi, IntersectionResult const& result, - bool is_p_last, bool is_q_last) + bool is_p_last, bool is_q_last, + EqPPStrategy const& strategy) { int arrival_a = result.template get<1>().arrival[0]; int arrival_b = result.template get<1>().arrival[1]; @@ -132,10 +133,10 @@ public: ips[0].is_pi = equals::equals_point_point( - pi, result.template get<0>().intersections[0]); + pi, result.template get<0>().intersections[0], strategy); ips[0].is_qi = equals::equals_point_point( - qi, result.template get<0>().intersections[0]); + qi, result.template get<0>().intersections[0], strategy); ips[1].is_pj = arrival_a != -1; ips[1].is_qj = arrival_b != -1; } @@ -230,7 +231,8 @@ struct get_turn_info_for_endpoint typename Point2, typename TurnInfo, typename IntersectionInfo, - typename OutputIterator + typename OutputIterator, + typename EqPPStrategy > static inline bool apply(Point1 const& pi, Point1 const& pj, Point1 const& pk, Point2 const& qi, Point2 const& qj, Point2 const& qk, @@ -239,7 +241,8 @@ struct get_turn_info_for_endpoint TurnInfo const& tp_model, IntersectionInfo const& inters, method_type /*method*/, - OutputIterator out) + OutputIterator out, + EqPPStrategy const& strategy) { std::size_t ip_count = inters.i_info().count; // no intersection points @@ -249,7 +252,7 @@ struct get_turn_info_for_endpoint if ( !is_p_first && !is_p_last && !is_q_first && !is_q_last ) return false; - linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last); + linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last, strategy); bool append0_last = analyse_segment_and_assign_ip(pi, pj, pk, qi, qj, qk, diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index 46c1305cd..d94afacef 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -54,7 +54,7 @@ struct get_turn_info_linear_areal bool is_p_first, bool is_p_last, bool is_q_first, bool is_q_last, TurnInfo const& tp_model, - IntersectionStrategy const& intersection_strategy, + IntersectionStrategy const& strategy, RobustPolicy const& robust_policy, OutputIterator out) { @@ -66,7 +66,7 @@ struct get_turn_info_linear_areal RobustPolicy > inters_info; - inters_info inters(pi, pj, pk, qi, qj, qk, intersection_strategy, robust_policy); + inters_info inters(pi, pj, pk, qi, qj, qk, strategy, robust_policy); char const method = inters.d_info().how; @@ -82,7 +82,8 @@ struct get_turn_info_linear_areal get_turn_info_for_endpoint( pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_none, out); + tp_model, inters, method_none, out, + strategy.get_point_in_point_strategy()); break; case 'd' : // disjoint: never do anything @@ -93,7 +94,8 @@ struct get_turn_info_linear_areal if ( get_turn_info_for_endpoint( pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_touch_interior, out) ) + tp_model, inters, method_touch_interior, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -139,7 +141,8 @@ struct get_turn_info_linear_areal // this function assumes that 'u' must be set for a spike calculate_spike_operation(tp.operations[0].operation, - inters, is_p_last); + inters, is_p_last, + strategy.get_point_in_point_strategy()); AssignPolicy::apply(tp, pi, qi, inters); @@ -164,7 +167,8 @@ struct get_turn_info_linear_areal if ( get_turn_info_for_endpoint( pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_touch, out) ) + tp_model, inters, method_touch, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -236,7 +240,8 @@ struct get_turn_info_linear_areal bool ignore_spike = calculate_spike_operation(tp.operations[0].operation, - inters, is_p_last); + inters, is_p_last, + strategy.get_point_in_point_strategy()); // TODO: move this into the append_xxx and call for each turn? AssignPolicy::apply(tp, pi, qi, inters); @@ -256,7 +261,8 @@ struct get_turn_info_linear_areal if ( get_turn_info_for_endpoint( pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_equal, out) ) + tp_model, inters, method_equal, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -303,7 +309,8 @@ struct get_turn_info_linear_areal if ( get_turn_info_for_endpoint( pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_collinear, out) ) + tp_model, inters, method_collinear, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -385,12 +392,12 @@ struct get_turn_info_linear_areal only_convert::apply(tp, inters.i_info()); if ( is_p_first - && equals::equals_point_point(pi, tp.point) ) + && equals_point_point(pi, tp.point, strategy) ) { tp.operations[0].position = position_front; } else if ( is_p_last - && equals::equals_point_point(pj, tp.point) ) + && equals_point_point(pj, tp.point, strategy) ) { tp.operations[0].position = position_back; } @@ -417,10 +424,12 @@ struct get_turn_info_linear_areal } template + typename IntersectionInfo, + typename EqPPStrategy> static inline bool calculate_spike_operation(Operation & op, IntersectionInfo const& inters, - bool is_p_last) + bool is_p_last, + EqPPStrategy const& strategy) { bool is_p_spike = ( op == operation_union || op == operation_intersection ) && ! is_p_last @@ -441,7 +450,7 @@ struct get_turn_info_linear_areal // spike on the edge point // if it's already known that the spike is going out this musn't be checked if ( ! going_out - && equals::equals_point_point(inters.rpj(), inters.rqj()) ) + && detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) ) { int const pk_q2 = inters.sides().pk_wrt_q2(); going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both @@ -453,7 +462,7 @@ struct get_turn_info_linear_areal // spike on the edge point // if it's already known that the spike is going in this musn't be checked if ( ! going_in - && equals::equals_point_point(inters.rpj(), inters.rqj()) ) + && detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) ) { int const pk_q2 = inters.sides().pk_wrt_q2(); going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them @@ -710,7 +719,8 @@ struct get_turn_info_linear_areal typename Point2, typename TurnInfo, typename IntersectionInfo, - typename OutputIterator> + typename OutputIterator, + typename EqPPStrategy> static inline bool get_turn_info_for_endpoint( Point1 const& pi, Point1 const& /*pj*/, Point1 const& /*pk*/, Point2 const& qi, Point2 const& /*qj*/, Point2 const& /*qk*/, @@ -719,7 +729,8 @@ struct get_turn_info_linear_areal TurnInfo const& tp_model, IntersectionInfo const& inters, method_type /*method*/, - OutputIterator out) + OutputIterator out, + EqPPStrategy const& strategy) { namespace ov = overlay; typedef ov::get_turn_info_for_endpoint get_info_e; @@ -734,7 +745,7 @@ struct get_turn_info_linear_areal // TODO: is_q_last could probably be replaced by false and removed from parameters - linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last); + linear_intersections intersections(pi, qi, inters.result(), is_p_last, is_q_last, strategy); linear_intersections::ip_info const& ip0 = intersections.template get<0>(); linear_intersections::ip_info const& ip1 = intersections.template get<1>(); @@ -883,6 +894,14 @@ struct get_turn_info_linear_areal // don't ignore anything for now return false; } + + template + static inline bool equals_point_point(Point1 const& point1, Point2 const& point2, + IntersectionStrategy const& strategy) + { + return detail::equals::equals_point_point(point1, point2, + strategy.get_point_in_point_strategy()); + } }; }} // namespace detail::overlay diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp index 58fd4bb5c..bd73bb3b4 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_ll.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -77,7 +77,8 @@ struct get_turn_info_linear_linear get_turn_info_for_endpoint ::apply(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_none, out); + tp_model, inters, method_none, out, + strategy.get_point_in_point_strategy()); break; case 'd' : // disjoint: never do anything @@ -88,7 +89,8 @@ struct get_turn_info_linear_linear if ( get_turn_info_for_endpoint ::apply(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_touch_interior, out) ) + tp_model, inters, method_touch_interior, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -159,7 +161,8 @@ struct get_turn_info_linear_linear if ( get_turn_info_for_endpoint ::apply(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_touch, out) ) + tp_model, inters, method_touch, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -294,7 +297,8 @@ struct get_turn_info_linear_linear if ( get_turn_info_for_endpoint ::apply(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_equal, out) ) + tp_model, inters, method_equal, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -352,7 +356,8 @@ struct get_turn_info_linear_linear if ( get_turn_info_for_endpoint ::apply(pi, pj, pk, qi, qj, qk, is_p_first, is_p_last, is_q_first, is_q_last, - tp_model, inters, method_collinear, out) ) + tp_model, inters, method_collinear, out, + strategy.get_point_in_point_strategy()) ) { // do nothing } @@ -440,26 +445,29 @@ struct get_turn_info_linear_linear // degenerate points if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) ) { + typedef typename IntersectionStrategy::point_in_point_strategy_type + equals_strategy_type; + only_convert::apply(tp, inters.i_info()); // if any, only one of those should be true if ( is_p_first - && equals::equals_point_point(pi, tp.point) ) + && equals::equals_point_point(pi, tp.point, equals_strategy_type()) ) { tp.operations[0].position = position_front; } else if ( is_p_last - && equals::equals_point_point(pj, tp.point) ) + && equals::equals_point_point(pj, tp.point, equals_strategy_type()) ) { tp.operations[0].position = position_back; } else if ( is_q_first - && equals::equals_point_point(qi, tp.point) ) + && equals::equals_point_point(qi, tp.point, equals_strategy_type()) ) { tp.operations[1].position = position_front; } else if ( is_q_last - && equals::equals_point_point(qj, tp.point) ) + && equals::equals_point_point(qj, tp.point, equals_strategy_type()) ) { tp.operations[1].position = position_back; } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index fd1e49ca2..9ed67f928 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2016, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2016, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -233,7 +233,7 @@ public : { ever_circling_iterator nd_next1( begin_range_1, end_range_1, next1, true); - advance_to_non_duplicate_next(nd_next1, it1, sec1, robust_policy); + advance_to_non_duplicate_next(nd_next1, it1, sec1, intersection_strategy, robust_policy); signed_size_type index2 = sec2.begin_index; signed_size_type ndi2 = sec2.non_duplicate_index; @@ -282,7 +282,7 @@ public : // Move to the "non duplicate next" ever_circling_iterator nd_next2( begin_range_2, end_range_2, next2, true); - advance_to_non_duplicate_next(nd_next2, it2, sec2, robust_policy); + advance_to_non_duplicate_next(nd_next2, it2, sec2, intersection_strategy, robust_policy); typedef typename boost::range_value::type turn_info; @@ -328,10 +328,19 @@ private : typedef typename model::referring_segment segment1_type; typedef typename model::referring_segment segment2_type; - template + template + < + typename Iterator, typename RangeIterator, + typename Section, + typename IntersectionStrategy, typename RobustPolicy + > static inline void advance_to_non_duplicate_next(Iterator& next, - RangeIterator const& it, Section const& section, RobustPolicy const& robust_policy) + RangeIterator const& it, + Section const& section, + IntersectionStrategy const& , + RobustPolicy const& robust_policy) { + typedef typename IntersectionStrategy::point_in_point_strategy_type disjoint_strategy_type; typedef typename robust_point_type::type robust_point_type; robust_point_type robust_point_from_it; robust_point_type robust_point_from_next; @@ -348,10 +357,9 @@ private : // So advance to the "non duplicate next" // (the check is defensive, to avoid endless loops) std::size_t check = 0; - while(! detail::disjoint::disjoint_point_point - ( - robust_point_from_it, robust_point_from_next - ) + while(! detail::disjoint::disjoint_point_point(robust_point_from_it, + robust_point_from_next, + disjoint_strategy_type() ) && check++ < section.range_count) { next++; @@ -483,11 +491,13 @@ public: typename IntersectionStrategy::envelope_strategy_type const envelope_strategy = intersection_strategy.get_envelope_strategy(); + typename IntersectionStrategy::expand_strategy_type const + expand_strategy = intersection_strategy.get_expand_strategy(); geometry::sectionalize(geometry1, robust_policy, - sec1, envelope_strategy, 0); + sec1, envelope_strategy, expand_strategy, 0); geometry::sectionalize(geometry2, robust_policy, - sec2, envelope_strategy, 1); + sec2, envelope_strategy, expand_strategy, 1); // ... and then partition them, intersecting overlapping sections in visitor method section_visitor diff --git a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp index 88aedecf8..afe8f680b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2017, Oracle and/or its affiliates. +// Copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -148,13 +148,13 @@ struct point_point_point Point2 const& point2, RobustPolicy const& , OutputIterator oit, - Strategy const&) + Strategy const& strategy) { action_selector_pl_pl < PointOut, OverlayType >::apply(point1, - detail::equals::equals_point_point(point1, point2), + detail::equals::equals_point_point(point1, point2, strategy), oit); return oit; @@ -182,7 +182,7 @@ struct multipoint_point_point Point const& point, RobustPolicy const& , OutputIterator oit, - Strategy const&) + Strategy const& strategy) { BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference ); @@ -194,7 +194,7 @@ struct multipoint_point_point < PointOut, OverlayType >::apply(*it, - detail::equals::equals_point_point(*it, point), + detail::equals::equals_point_point(*it, point, strategy), oit); } @@ -218,7 +218,7 @@ struct point_multipoint_point MultiPoint const& multipoint, RobustPolicy const& , OutputIterator oit, - Strategy const&) + Strategy const& strategy) { typedef action_selector_pl_pl action; @@ -226,7 +226,7 @@ struct point_multipoint_point it = boost::begin(multipoint); it != boost::end(multipoint); ++it) { - if ( detail::equals::equals_point_point(*it, point) ) + if ( detail::equals::equals_point_point(*it, point, strategy) ) { action::apply(point, true, oit); return oit; diff --git a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp index 3cc98d3b7..ba8d1c413 100644 --- a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -154,7 +154,8 @@ struct get_turns sections_type sec; geometry::sectionalize(geometry, robust_policy, sec, - intersection_strategy.get_envelope_strategy()); + intersection_strategy.get_envelope_strategy(), + intersection_strategy.get_expand_strategy()); self_section_visitor < diff --git a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp index 800fbb2e9..fa0ab1ea0 100644 --- a/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp +++ b/include/boost/geometry/algorithms/detail/relate/areal_areal.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -277,7 +277,8 @@ struct areal_areal { // analyse sorted turns turns_analyser analyser; - analyse_each_turn(result, analyser, turns.begin(), turns.end()); + analyse_each_turn(result, analyser, turns.begin(), turns.end(), + point_in_areal_strategy12.get_equals_point_point_strategy()); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; @@ -317,7 +318,8 @@ struct areal_areal { // analyse sorted turns turns_analyser analyser; - analyse_each_turn(result, analyser, turns.begin(), turns.end()); + analyse_each_turn(result, analyser, turns.begin(), turns.end(), + point_in_areal_strategy21.get_equals_point_point_strategy()); if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; @@ -441,9 +443,8 @@ struct areal_areal , m_exit_detected(false) {} - template - void apply(Result & result, TurnIt it) + template + void apply(Result & result, TurnIt it, EqPPStrategy const& strategy) { //BOOST_GEOMETRY_ASSERT( it != last ); @@ -468,7 +469,7 @@ struct areal_areal { // real exit point - may be multiple if ( first_in_range - || ! turn_on_the_same_ip(*m_previous_turn_ptr, *it) ) + || ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, strategy) ) { update_exit(result); m_exit_detected = false; @@ -484,7 +485,7 @@ struct areal_areal { // real entry point if ( first_in_range - || ! turn_on_the_same_ip(*m_previous_turn_ptr, *it) ) + || ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, strategy) ) { update_enter(result); m_enter_detected = false; @@ -581,19 +582,24 @@ struct areal_areal // call analyser.apply() for each turn in range // IMPORTANT! The analyser is also called for the end iterator - last - template + template + < + typename Result, + typename Analyser, + typename TurnIt, + typename EqPPStrategy + > static inline void analyse_each_turn(Result & res, Analyser & analyser, - TurnIt first, TurnIt last) + TurnIt first, TurnIt last, + EqPPStrategy const& strategy) { if ( first == last ) return; for ( TurnIt it = first ; it != last ; ++it ) { - analyser.apply(res, it); + analyser.apply(res, it, strategy); if ( BOOST_GEOMETRY_CONDITION(res.interrupt) ) return; diff --git a/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp b/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp index 1a9a5a8fd..775b14f45 100644 --- a/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp +++ b/include/boost/geometry/algorithms/detail/relate/boundary_checker.hpp @@ -1,16 +1,18 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014 Oracle and/or its affiliates. +// Copyright (c) 2014-2018 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) -// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle - #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP +#include + #include #include #include @@ -28,46 +30,57 @@ namespace detail { namespace relate { enum boundary_query { boundary_front, boundary_back, boundary_any }; template ::type> class boundary_checker {}; -template -class boundary_checker +template +class boundary_checker { typedef typename point_type::type point_type; public: + typedef WithinStrategy equals_strategy_type; + boundary_checker(Geometry const& g) : has_boundary( boost::size(g) >= 2 - && !detail::equals::equals_point_point(range::front(g), range::back(g)) ) + && !detail::equals::equals_point_point(range::front(g), + range::back(g), + equals_strategy_type()) ) +#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER , geometry(g) +#endif {} template bool is_endpoint_boundary(point_type const& pt) const { - boost::ignore_unused_variable_warning(pt); + boost::ignore_unused(pt); #ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER // may give false positives for INT BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any) - && detail::equals::equals_point_point(pt, range::front(geometry)) + && detail::equals::equals_point_point(pt, range::front(geometry), WithinStrategy()) || (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any) - && detail::equals::equals_point_point(pt, range::back(geometry)) ); + && detail::equals::equals_point_point(pt, range::back(geometry), WithinStrategy()) ); #endif return has_boundary; } private: bool has_boundary; +#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER Geometry const& geometry; +#endif }; -template -class boundary_checker +template +class boundary_checker { typedef typename point_type::type point_type; public: + typedef WithinStrategy equals_strategy_type; + boundary_checker(Geometry const& g) : is_filled(false), geometry(g) {} @@ -110,7 +123,7 @@ public: point_reference back_pt = range::back(ls); // linear ring or point - no boundary - if (! equals::equals_point_point(front_pt, back_pt)) + if (! equals::equals_point_point(front_pt, back_pt, equals_strategy_type())) { // do not add points containing NaN coordinates // because they cannot be reasonably compared, e.g. with MSVC diff --git a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp index 20122471e..30a4f70cf 100644 --- a/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp +++ b/include/boost/geometry/algorithms/detail/relate/follow_helpers.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014. -// Modifications copyright (c) 2013-2014 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Use, modification and distribution is subject to the Boost Software License, // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at @@ -331,8 +331,9 @@ private: std::vector m_other_entry_points; // TODO: use map here or sorted vector? }; -template -inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn) +template +inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn, + EqPPStrategy const& strategy) { segment_identifier const& prev_seg_id = prev_turn.operations[OpId].seg_id; segment_identifier const& curr_seg_id = curr_turn.operations[OpId].seg_id; @@ -352,7 +353,7 @@ inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn) return false; } - return detail::equals::equals_point_point(prev_turn.point, curr_turn.point); + return detail::equals::equals_point_point(prev_turn.point, curr_turn.point, strategy); } template ::type within_strategy_type; within_strategy_type const within_strategy = intersection_strategy.template get_point_in_geometry_strategy(); - boundary_checker boundary_checker1(geometry1); + + typedef typename within_strategy_type::equals_point_point_strategy_type eq_pp_strategy_type; + + typedef boundary_checker + < + Geometry1, + eq_pp_strategy_type + > boundary_checker1_type; + boundary_checker1_type boundary_checker1(geometry1); + no_turns_la_linestring_pred < Geometry2, Result, within_strategy_type, - boundary_checker, + boundary_checker1_type, TransposeResult > pred1(geometry2, result, @@ -393,12 +402,14 @@ struct linear_areal typedef turns::less<1, turns::less_op_areal_linear<1> > less; std::sort(it, next, less()); + eq_pp_strategy_type const eq_pp_strategy = within_strategy.get_equals_point_point_strategy(); + // analyse areal_boundary_analyser analyser; for ( turn_iterator rit = it ; rit != next ; ++rit ) { // if the analyser requests, break the search - if ( !analyser.apply(it, rit, next) ) + if ( !analyser.apply(it, rit, next, eq_pp_strategy) ) break; } @@ -670,7 +681,8 @@ struct linear_areal { // real exit point - may be multiple // we know that we entered and now we exit - if ( ! turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it) ) + if ( ! turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it, + side_strategy.get_equals_point_point_strategy()) ) { m_exit_watcher.reset_detected_exit(); @@ -712,7 +724,8 @@ struct linear_areal if ( ( op == overlay::operation_intersection || op == overlay::operation_continue ) - && turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it) ) + && turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it, + side_strategy.get_equals_point_point_strategy()) ) { fake_enter_detected = true; } @@ -732,7 +745,8 @@ struct linear_areal && ( op != overlay::operation_blocked // operation different than block || seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry || ( m_previous_operation == overlay::operation_union - && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it) ) + && ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, + side_strategy.get_equals_point_point_strategy()) ) ) { update(res); @@ -764,7 +778,8 @@ struct linear_areal BOOST_GEOMETRY_ASSERT_MSG(m_previous_turn_ptr, "non-NULL ptr expected"); // real interior overlap - if ( ! turn_on_the_same_ip(*m_previous_turn_ptr, *it) ) + if ( ! turn_on_the_same_ip(*m_previous_turn_ptr, *it, + side_strategy.get_equals_point_point_strategy()) ) { update(res); m_interior_detected = false; @@ -1203,7 +1218,7 @@ struct linear_areal point2_type const& qj = range::at(range2, q_seg_ij + 1); point1_type qi_conv; geometry::convert(qi, qi_conv); - bool const is_ip_qj = equals::equals_point_point(turn.point, qj); + bool const is_ip_qj = equals::equals_point_point(turn.point, qj, side_strategy.get_equals_point_point_strategy()); // TODO: test this! // BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi)); // BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi)); @@ -1217,7 +1232,8 @@ struct linear_areal // It would be good to replace it with some O(1) mechanism range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2), range::pos(range2, q_seg_jk), - boost::end(range2)); + boost::end(range2), + side_strategy.get_equals_point_point_strategy()); // Will this sequence of points be always correct? overlay::side_calculator @@ -1237,8 +1253,9 @@ struct linear_areal } } - template - static inline It find_next_non_duplicated(It first, It current, It last) + template + static inline It find_next_non_duplicated(It first, It current, It last, + EqPPStrategy const& strategy) { BOOST_GEOMETRY_ASSERT( current != last ); @@ -1246,14 +1263,14 @@ struct linear_areal for ( ++it ; it != last ; ++it ) { - if ( !equals::equals_point_point(*current, *it) ) + if ( !equals::equals_point_point(*current, *it, strategy) ) return it; } // if not found start from the beginning for ( it = first ; it != current ; ++it ) { - if ( !equals::equals_point_point(*current, *it) ) + if ( !equals::equals_point_point(*current, *it, strategy) ) return it; } @@ -1396,8 +1413,9 @@ struct linear_areal , m_previous_turn_ptr(NULL) {} - template - bool apply(TurnIt /*first*/, TurnIt it, TurnIt last) + template + bool apply(TurnIt /*first*/, TurnIt it, TurnIt last, + EqPPStrategy const& strategy) { overlay::operation_type op = it->operations[1].operation; @@ -1412,7 +1430,7 @@ struct linear_areal if ( is_union_detected ) { BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL); - if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) ) + if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point, strategy) ) { // break return false; diff --git a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp index 520f2bd77..6c5d82fde 100644 --- a/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp +++ b/include/boost/geometry/algorithms/detail/relate/linear_linear.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -42,6 +42,8 @@ namespace detail { namespace relate { template class disjoint_linestring_pred { + typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type; + public: disjoint_linestring_pred(Result & res, BoundaryChecker const& boundary_checker) @@ -80,7 +82,8 @@ public: // point-like linestring if ( count == 2 && equals::equals_point_point(range::front(linestring), - range::back(linestring)) ) + range::back(linestring), + equals_strategy_type()) ) { update(m_result); } @@ -145,14 +148,24 @@ struct linear_linear if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; - boundary_checker boundary_checker1(geometry1); - disjoint_linestring_pred, false> pred1(result, boundary_checker1); + typedef boundary_checker + < + Geometry1, + typename IntersectionStrategy::point_in_point_strategy_type + > boundary_checker1_type; + boundary_checker1_type boundary_checker1(geometry1); + disjoint_linestring_pred pred1(result, boundary_checker1); for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; - boundary_checker boundary_checker2(geometry2); - disjoint_linestring_pred, true> pred2(result, boundary_checker2); + typedef boundary_checker + < + Geometry2, + typename IntersectionStrategy::point_in_point_strategy_type + > boundary_checker2_type; + boundary_checker2_type boundary_checker2(geometry2); + disjoint_linestring_pred pred2(result, boundary_checker2); for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2); if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) ) return; @@ -274,6 +287,8 @@ struct linear_linear BoundaryChecker const& boundary_checker, OtherBoundaryChecker const& other_boundary_checker) { + typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type; + overlay::operation_type const op = it->operations[op_id].operation; segment_identifier const& seg_id = it->operations[op_id].seg_id; @@ -323,7 +338,9 @@ struct linear_linear { // real exit point - may be multiple // we know that we entered and now we exit - if ( ! turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it) ) + if ( ! turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), + *it, + equals_strategy_type()) ) { m_exit_watcher.reset_detected_exit(); @@ -344,7 +361,9 @@ struct linear_linear return; if ( op == overlay::operation_intersection - && turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), *it) ) + && turn_on_the_same_ip(m_exit_watcher.get_exit_turn(), + *it, + equals_strategy_type()) ) { fake_enter_detected = true; } @@ -647,6 +666,11 @@ struct linear_linear OtherBoundaryChecker const& /*other_boundary_checker*/, bool first_in_range) { + typedef typename BoundaryChecker::equals_strategy_type + equals_strategy1_type; + typedef typename OtherBoundaryChecker::equals_strategy_type + equals_strategy2_type; + 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 @@ -714,9 +738,13 @@ struct linear_linear // here we don't know which one is degenerated bool const is_point1 = boost::size(ls1_ref) == 2 - && equals::equals_point_point(range::front(ls1_ref), range::back(ls1_ref)); + && equals::equals_point_point(range::front(ls1_ref), + range::back(ls1_ref), + equals_strategy1_type()); bool const is_point2 = boost::size(ls2_ref) == 2 - && equals::equals_point_point(range::front(ls2_ref), range::back(ls2_ref)); + && equals::equals_point_point(range::front(ls2_ref), + range::back(ls2_ref), + equals_strategy2_type()); // if the second one is degenerated if ( !is_point1 && is_point2 ) diff --git a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp index 8d5f21555..e41bb9206 100644 --- a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017 Oracle and/or its affiliates. +// Copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -40,20 +40,21 @@ namespace detail { namespace relate template < typename Geometry, + typename EqPPStrategy, typename Tag = typename tag::type > struct multi_point_geometry_eb { template static inline bool apply(MultiPoint const& , - detail::relate::topology_check const& ) + detail::relate::topology_check const& ) { return true; } }; -template -struct multi_point_geometry_eb +template +struct multi_point_geometry_eb { template struct boundary_visitor @@ -73,7 +74,7 @@ struct multi_point_geometry_eb template bool operator()(Pt const& pt) const { - return detail::equals::equals_point_point(pt, m_point); + return detail::equals::equals_point_point(pt, m_point, EqPPStrategy()); } Point const& m_point; @@ -99,7 +100,7 @@ struct multi_point_geometry_eb template static inline bool apply(MultiPoint const& multi_point, - detail::relate::topology_check const& tc) + detail::relate::topology_check const& tc) { boundary_visitor visitor(multi_point); tc.for_each_boundary_point(visitor); @@ -107,9 +108,12 @@ struct multi_point_geometry_eb } }; -template -struct multi_point_geometry_eb +template +struct multi_point_geometry_eb { + // TODO: CS-specific less compare strategy derived from EqPPStrategy + typedef geometry::less<> less_type; + template struct boundary_visitor { @@ -121,7 +125,7 @@ struct multi_point_geometry_eb template bool apply(Point const& boundary_point) { - if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, geometry::less<>())) + if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, less_type())) { m_boundary_found = true; return false; @@ -138,12 +142,12 @@ struct multi_point_geometry_eb template static inline bool apply(MultiPoint const& multi_point, - detail::relate::topology_check const& tc) + detail::relate::topology_check const& tc) { typedef typename boost::range_value::type point_type; typedef std::vector points_type; points_type points(boost::begin(multi_point), boost::end(multi_point)); - std::sort(points.begin(), points.end(), geometry::less<>()); + std::sort(points.begin(), points.end(), less_type()); boundary_visitor visitor(points); tc.for_each_boundary_point(visitor); @@ -165,6 +169,7 @@ struct multi_point_single_geometry { typedef typename point_type::type point2_type; typedef model::box box2_type; + typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type; box2_type box2; geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy()); @@ -209,7 +214,10 @@ struct multi_point_single_geometry } } - typedef detail::relate::topology_check tc_t; + typedef detail::relate::topology_check + < + SingleGeometry, eq_pp_strategy_type + > tc_t; if ( relate::may_update(result) || relate::may_update(result) ) { @@ -226,8 +234,13 @@ struct multi_point_single_geometry if ( relate::may_update(result) && tc.has_boundary() ) { - if (multi_point_geometry_eb::apply(multi_point, tc)) + if (multi_point_geometry_eb + < + SingleGeometry, eq_pp_strategy_type + >::apply(multi_point, tc)) + { relate::set(result); + } } } @@ -283,9 +296,12 @@ class multi_point_multi_geometry_ii_ib template class item_visitor_type { + typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type; + typedef detail::relate::topology_check topology_check_type; + public: item_visitor_type(MultiGeometry const& multi_geometry, - detail::relate::topology_check const& tc, + topology_check_type const& tc, Result & result, PtSegStrategy const& strategy) : m_multi_geometry(multi_geometry) @@ -335,7 +351,7 @@ class multi_point_multi_geometry_ii_ib private: MultiGeometry const& m_multi_geometry; - detail::relate::topology_check const& m_tc; + topology_check_type const& m_tc; Result & m_result; PtSegStrategy const& m_strategy; }; @@ -351,7 +367,11 @@ public: static inline void apply(MultiPoint const& multi_point, MultiGeometry const& multi_geometry, std::vector const& boxes, - detail::relate::topology_check const& tc, + detail::relate::topology_check + < + MultiGeometry, + typename Strategy::equals_point_point_strategy_type + > const& tc, Result & result, Strategy const& strategy) { @@ -387,7 +407,11 @@ struct multi_point_multi_geometry_ii_ib_ie static inline void apply(MultiPoint const& multi_point, MultiGeometry const& multi_geometry, std::vector const& boxes, - detail::relate::topology_check const& tc, + detail::relate::topology_check + < + MultiGeometry, + typename Strategy::equals_point_point_strategy_type + > const& tc, Result & result, Strategy const& strategy) { @@ -461,6 +485,8 @@ struct multi_point_multi_geometry typedef model::box box2_type; typedef std::pair box_pair_type; + typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type; + typename Strategy::envelope_strategy_type const envelope_strategy = strategy.get_envelope_strategy(); @@ -473,7 +499,7 @@ struct multi_point_multi_geometry boxes[i].second = i; } - typedef detail::relate::topology_check tc_t; + typedef detail::relate::topology_check tc_t; tc_t tc(multi_geometry); if ( relate::may_update(result) @@ -512,8 +538,13 @@ struct multi_point_multi_geometry if ( relate::may_update(result) && tc.has_boundary() ) { - if (multi_point_geometry_eb::apply(multi_point, tc)) + if (multi_point_geometry_eb + < + MultiGeometry, eq_pp_strategy_type + >::apply(multi_point, tc)) + { relate::set(result); + } } } diff --git a/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp index e78a404b2..7b1726abe 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_geometry.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -60,7 +60,11 @@ struct point_geometry if ( BOOST_GEOMETRY_CONDITION(result.interrupt) ) return; - typedef detail::relate::topology_check tc_t; + typedef detail::relate::topology_check + < + Geometry, + typename Strategy::equals_point_point_strategy_type + > tc_t; if ( relate::may_update(result) || relate::may_update(result) ) { diff --git a/include/boost/geometry/algorithms/detail/relate/point_point.hpp b/include/boost/geometry/algorithms/detail/relate/point_point.hpp index e0bed72ba..d2a373f3c 100644 --- a/include/boost/geometry/algorithms/detail/relate/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/relate/point_point.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2013, 2014, 2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017, 2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -39,9 +39,9 @@ struct point_point template static inline void apply(Point1 const& point1, Point2 const& point2, Result & result, - Strategy const& /*strategy*/) + Strategy const& strategy) { - bool equal = detail::equals::equals_point_point(point1, point2); + bool equal = detail::equals::equals_point_point(point1, point2, strategy); if ( equal ) { relate::set(result); @@ -56,8 +56,10 @@ struct point_point } }; -template -std::pair point_multipoint_check(Point const& point, MultiPoint const& multi_point) +template +std::pair point_multipoint_check(Point const& point, + MultiPoint const& multi_point, + EqPPStrategy const& strategy) { bool found_inside = false; bool found_outside = false; @@ -70,7 +72,7 @@ std::pair point_multipoint_check(Point const& point, MultiPoint cons iterator last = boost::end(multi_point); for ( ; it != last ; ++it ) { - bool ii = detail::equals::equals_point_point(point, *it); + bool ii = detail::equals::equals_point_point(point, *it, strategy); if ( ii ) found_inside = true; @@ -92,7 +94,7 @@ struct point_multipoint template static inline void apply(Point const& point, MultiPoint const& multi_point, Result & result, - Strategy const& /*strategy*/) + Strategy const& strategy) { if ( boost::empty(multi_point) ) { @@ -101,7 +103,7 @@ struct point_multipoint return; } - std::pair rel = point_multipoint_check(point, multi_point); + std::pair rel = point_multipoint_check(point, multi_point, strategy); if ( rel.first ) // some point of MP is equal to P { diff --git a/include/boost/geometry/algorithms/detail/relate/topology_check.hpp b/include/boost/geometry/algorithms/detail/relate/topology_check.hpp index 810466ec0..3785f17b4 100644 --- a/include/boost/geometry/algorithms/detail/relate/topology_check.hpp +++ b/include/boost/geometry/algorithms/detail/relate/topology_check.hpp @@ -1,6 +1,6 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2017, Oracle and/or its affiliates. +// Copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -28,6 +28,7 @@ namespace detail { namespace relate { // TODO: change the name for e.g. something with the word "exterior" template ::type> struct topology_check : not_implemented @@ -47,8 +48,8 @@ struct topology_check // topology_check(Point const&, IgnoreBoundaryPoint const&) {} //}; -template -struct topology_check +template +struct topology_check { static const char interior = '1'; static const char boundary = '0'; @@ -99,8 +100,11 @@ private: std::size_t count = boost::size(m_ls); m_has_interior = count > 0; // NOTE: Linestring with all points equal is treated as 1d linear ring + using detail::equals::equals_point_point; m_has_boundary = count > 1 - && ! detail::equals::equals_point_point(range::front(m_ls), range::back(m_ls)); + && ! equals_point_point(range::front(m_ls), + range::back(m_ls), + EqPPStrategy()); m_is_initialized = true; } @@ -112,8 +116,8 @@ private: mutable bool m_has_boundary; }; -template -struct topology_check +template +struct topology_check { static const char interior = '1'; static const char boundary = '0'; @@ -159,6 +163,9 @@ struct topology_check } private: +// TODO: CS-specific less derived from EqPPStrategy + typedef geometry::less<> less_type; + void init() const { if (m_is_initialized) @@ -192,7 +199,7 @@ private: point_reference back_pt = range::back(ls); // don't store boundaries of linear rings, this doesn't change anything - if (! equals::equals_point_point(front_pt, back_pt)) + if (! equals::equals_point_point(front_pt, back_pt, EqPPStrategy())) { // do not add points containing NaN coordinates // because they cannot be reasonably compared, e.g. with MSVC @@ -215,7 +222,7 @@ private: if (! m_endpoints.empty() ) { - std::sort(m_endpoints.begin(), m_endpoints.end(), geometry::less<>()); + std::sort(m_endpoints.begin(), m_endpoints.end(), less_type()); m_has_boundary = find_odd_count(m_endpoints.begin(), m_endpoints.end()); } @@ -225,7 +232,7 @@ private: template static inline std::size_t count_equal(It first, It last, Point const& point) { - std::pair rng = std::equal_range(first, last, point, geometry::less<>()); + std::pair rng = std::equal_range(first, last, point, less_type()); return (std::size_t)std::distance(rng.first, rng.second); } @@ -261,7 +268,7 @@ private: for ( ; first != last ; ++first, ++prev ) { // the end of the equal points subrange - if ( ! equals::equals_point_point(*first, *prev) ) + if ( ! equals::equals_point_point(*first, *prev, EqPPStrategy()) ) { // odd count -> boundary if ( count % 2 != 0 ) @@ -298,40 +305,35 @@ private: mutable std::vector m_endpoints; }; -template -struct topology_check +struct topology_check_areal { static const char interior = '2'; static const char boundary = '1'; + static bool has_interior() { return true; } + static bool has_boundary() { return true; } +}; + +template +struct topology_check + : topology_check_areal +{ topology_check(Ring const&) {} - - static bool has_interior() { return true; } - static bool has_boundary() { return true; } }; -template -struct topology_check +template +struct topology_check + : topology_check_areal { - static const char interior = '2'; - static const char boundary = '1'; - topology_check(Polygon const&) {} - - static bool has_interior() { return true; } - static bool has_boundary() { return true; } }; -template -struct topology_check +template +struct topology_check + : topology_check_areal { - static const char interior = '2'; - static const char boundary = '1'; - topology_check(MultiPolygon const&) {} - - static bool has_interior() { return true; } - static bool has_boundary() { return true; } + template static bool check_boundary_point(Point const& ) { return true; } }; diff --git a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp index d854c6714..b720c5ed6 100644 --- a/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp +++ b/include/boost/geometry/algorithms/detail/sections/sectionalize.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -57,6 +57,7 @@ #include #include +#include namespace boost { namespace geometry { @@ -329,9 +330,9 @@ struct assign_loop template struct box_first_in_section { - template + template static inline void apply(Box & box, Point const& prev, Point const& curr, - Strategy const& strategy) + EnvelopeStrategy const& strategy) { geometry::model::referring_segment seg(prev, curr); geometry::envelope(seg, box, strategy); @@ -341,9 +342,9 @@ struct box_first_in_section template <> struct box_first_in_section { - template + template static inline void apply(Box & box, Point const& prev, Point const& curr, - Strategy const& ) + ExpandStrategy const& ) { geometry::envelope(prev, box); geometry::expand(box, curr); @@ -398,11 +399,20 @@ struct sectionalize_part { typedef typename strategy::envelope::services::default_strategy < + segment_tag, typename cs_tag::type >::type envelope_strategy_type; + typedef typename strategy::expand::services::default_strategy + < + segment_tag, + typename cs_tag::type + >::type expand_strategy_type; + apply(sections, begin, end, - robust_policy, envelope_strategy_type(), + robust_policy, + envelope_strategy_type(), + expand_strategy_type(), ring_id, max_count); } @@ -411,12 +421,14 @@ struct sectionalize_part typename Iterator, typename RobustPolicy, typename Sections, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > static inline void apply(Sections& sections, Iterator begin, Iterator end, RobustPolicy const& robust_policy, - EnvelopeStrategy const& strategy, + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, ring_identifier ring_id, std::size_t max_count) { @@ -534,14 +546,14 @@ struct sectionalize_part // In cartesian this is envelope of previous point expanded with current point // in non-cartesian this is envelope of a segment box_first_in_section::type> - ::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy); + ::apply(section.bounding_box, previous_robust_point, current_robust_point, envelope_strategy); } else { // In cartesian this is expand with current point // in non-cartesian this is expand with a segment box_next_in_section::type> - ::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy); + ::apply(section.bounding_box, previous_robust_point, current_robust_point, expand_strategy); } section.end_index = index + 1; @@ -587,12 +599,14 @@ struct sectionalize_range typename Range, typename RobustPolicy, typename Sections, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > static inline void apply(Range const& range, RobustPolicy const& robust_policy, Sections& sections, - EnvelopeStrategy const& strategy, + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, ring_identifier ring_id, std::size_t max_count) { @@ -621,7 +635,8 @@ struct sectionalize_range sectionalize_part::apply(sections, boost::begin(view), boost::end(view), - robust_policy, strategy, ring_id, max_count); + robust_policy, envelope_strategy, expand_strategy, + ring_id, max_count); } }; @@ -637,12 +652,14 @@ struct sectionalize_polygon typename Polygon, typename RobustPolicy, typename Sections, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > static inline void apply(Polygon const& poly, RobustPolicy const& robust_policy, Sections& sections, - EnvelopeStrategy const& strategy, + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, ring_identifier ring_id, std::size_t max_count) { @@ -654,7 +671,8 @@ struct sectionalize_polygon > per_range; ring_id.ring_index = -1; - per_range::apply(exterior_ring(poly), robust_policy, sections, strategy, ring_id, max_count); + per_range::apply(exterior_ring(poly), robust_policy, sections, + envelope_strategy, expand_strategy, ring_id, max_count); ring_id.ring_index++; typename interior_return_type::type @@ -662,7 +680,8 @@ struct sectionalize_polygon for (typename detail::interior_iterator::type it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index) { - per_range::apply(*it, robust_policy, sections, strategy, ring_id, max_count); + per_range::apply(*it, robust_policy, sections, + envelope_strategy, expand_strategy, ring_id, max_count); } } }; @@ -675,12 +694,14 @@ struct sectionalize_box typename Box, typename RobustPolicy, typename Sections, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > static inline void apply(Box const& box, RobustPolicy const& robust_policy, Sections& sections, - EnvelopeStrategy const& , + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, ring_identifier const& ring_id, std::size_t max_count) { typedef typename point_type::type point_type; @@ -713,7 +734,7 @@ struct sectionalize_box point_type, DimensionVector >::apply(points, robust_policy, sections, - strategy::envelope::cartesian_segment<>(), + envelope_strategy, expand_strategy, ring_id, max_count); } }; @@ -726,12 +747,14 @@ struct sectionalize_multi typename MultiGeometry, typename RobustPolicy, typename Sections, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > static inline void apply(MultiGeometry const& multi, RobustPolicy const& robust_policy, Sections& sections, - EnvelopeStrategy const& strategy, + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, ring_identifier ring_id, std::size_t max_count) { @@ -741,7 +764,9 @@ struct sectionalize_multi it != boost::end(multi); ++it, ++ring_id.multi_index) { - Policy::apply(*it, robust_policy, sections, strategy, ring_id, max_count); + Policy::apply(*it, robust_policy, sections, + envelope_strategy, expand_strategy, + ring_id, max_count); } } }; @@ -914,12 +939,14 @@ template typename Geometry, typename Sections, typename RobustPolicy, - typename EnvelopeStrategy + typename EnvelopeStrategy, + typename ExpandStrategy > inline void sectionalize(Geometry const& geometry, RobustPolicy const& robust_policy, Sections& sections, - EnvelopeStrategy const& strategy, + EnvelopeStrategy const& envelope_strategy, + ExpandStrategy const& expand_strategy, int source_index = 0, std::size_t max_count = 10) { @@ -958,7 +985,9 @@ inline void sectionalize(Geometry const& geometry, Geometry, Reverse, DimensionVector - >::apply(geometry, robust_policy, sections, strategy, ring_id, max_count); + >::apply(geometry, robust_policy, sections, + envelope_strategy, expand_strategy, + ring_id, max_count); detail::sectionalize::enlarge_sections(sections); } @@ -980,14 +1009,27 @@ inline void sectionalize(Geometry const& geometry, { typedef typename strategy::envelope::services::default_strategy < + typename tag::type, typename cs_tag::type >::type envelope_strategy_type; + typedef typename strategy::expand::services::default_strategy + < + typename boost::mpl::if_c + < + boost::is_same::type, box_tag>::value, + box_tag, + segment_tag + >::type, + typename cs_tag::type + >::type expand_strategy_type; + boost::geometry::sectionalize < Reverse, DimensionVector >(geometry, robust_policy, sections, envelope_strategy_type(), + expand_strategy_type(), source_index, max_count); } diff --git a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp index a24f4d21e..4617630ad 100644 --- a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013, 2014, 2015, 2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -45,6 +45,11 @@ namespace boost { namespace geometry { #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace within { +template +inline bool equals_point_point(Point1 const& p1, Point2 const& p2, Strategy const& strategy) +{ + return equals::equals_point_point(p1, p2, strategy.get_equals_point_point_strategy()); +} // TODO: is this needed? inline int check_result_type(int result) @@ -139,8 +144,8 @@ struct point_in_geometry return -1; // exterior // if the point is equal to the one of the terminal points - if ( detail::equals::equals_point_point(point, p0) - || detail::equals::equals_point_point(point, p1) ) + if ( detail::within::equals_point_point(point, p0, strategy) + || detail::within::equals_point_point(point, p1, strategy) ) return 0; // boundary else return 1; // interior @@ -161,11 +166,11 @@ struct point_in_geometry return -1; // exterior // if the linestring doesn't have a boundary - if (detail::equals::equals_point_point(range::front(linestring), range::back(linestring))) + if (detail::within::equals_point_point(range::front(linestring), range::back(linestring), strategy)) return 1; // interior // else if the point is equal to the one of the terminal points - else if (detail::equals::equals_point_point(point, range::front(linestring)) - || detail::equals::equals_point_point(point, range::back(linestring))) + else if (detail::within::equals_point_point(point, range::front(linestring), strategy) + || detail::within::equals_point_point(point, range::back(linestring), strategy)) return 0; // boundary else return 1; // interior @@ -304,12 +309,12 @@ struct point_in_geometry point_type const& back = range::back(*it); // is closed_ring - no boundary - if ( detail::equals::equals_point_point(front, back) ) + if ( detail::within::equals_point_point(front, back, strategy) ) continue; // is point on boundary - if ( detail::equals::equals_point_point(point, front) - || detail::equals::equals_point_point(point, back) ) + if ( detail::within::equals_point_point(point, front, strategy) + || detail::within::equals_point_point(point, back, strategy) ) { ++boundaries; } diff --git a/include/boost/geometry/algorithms/is_convex.hpp b/include/boost/geometry/algorithms/is_convex.hpp index 4a9251b27..1df778d1b 100644 --- a/include/boost/geometry/algorithms/is_convex.hpp +++ b/include/boost/geometry/algorithms/is_convex.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -45,6 +45,9 @@ struct ring_is_convex template static inline bool apply(Ring const& ring, SideStrategy const& strategy) { + typename SideStrategy::equals_point_point_strategy_type + eq_pp_strategy = strategy.get_equals_point_point_strategy(); + std::size_t n = boost::size(ring); if (boost::size(ring) < core_detail::closure::minimum_ring_size < @@ -67,7 +70,8 @@ struct ring_is_convex current++; std::size_t index = 1; - while (equals::equals_point_point(*current, *previous) && index < n) + while (equals::equals_point_point(*current, *previous, eq_pp_strategy) + && index < n) { current++; index++; @@ -81,7 +85,7 @@ struct ring_is_convex it_type next = current; next++; - while (equals::equals_point_point(*current, *next)) + while (equals::equals_point_point(*current, *next, eq_pp_strategy)) { next++; } @@ -105,7 +109,7 @@ struct ring_is_convex // Advance next to next different point // (because there are non-equal points, this loop is not infinite) next++; - while (equals::equals_point_point(*current, *next)) + while (equals::equals_point_point(*current, *next, eq_pp_strategy)) { next++; } diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 298f9c640..4e1884ea5 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -4,6 +4,11 @@ // Copyright (c) 2008-2015 Bruno Lalande, Paris, France. // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018 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. @@ -53,12 +58,13 @@ namespace boost { namespace geometry namespace detail { namespace simplify { -template -inline bool is_degenerate(Range const& range) +template +inline bool is_degenerate(Range const& range, EqualsStrategy const& strategy) { return boost::size(range) == 2 && detail::equals::equals_point_point(geometry::range::front(range), - geometry::range::back(range)); + geometry::range::back(range), + strategy); } struct simplify_range_insert @@ -67,9 +73,12 @@ struct simplify_range_insert static inline void apply(Range const& range, OutputIterator out, Distance const& max_distance, Strategy const& strategy) { + typedef Strategy::distance_strategy_type::equals_point_point_strategy_type + equals_strategy_type; + boost::ignore_unused(strategy); - if (is_degenerate(range)) + if (is_degenerate(range, equals_strategy_type())) { std::copy(boost::begin(range), boost::begin(range) + 1, out); } @@ -107,6 +116,9 @@ struct simplify_range static inline void apply(RangeIn const& range, RangeOut& out, Distance const& max_distance, Strategy const& strategy) { + typedef Strategy::distance_strategy_type::equals_point_point_strategy_type + equals_strategy_type; + // For a RING: // Note that, especially if max_distance is too large, // the output ring might be self intersecting while the input ring is @@ -126,7 +138,7 @@ struct simplify_range // Verify the two remaining points are equal. If so, remove one of them. // This can cause the output being under the minimum size - if (is_degenerate(out)) + if (is_degenerate(out, equals_strategy_type())) { range::resize(out, 1); } diff --git a/include/boost/geometry/algorithms/union.hpp b/include/boost/geometry/algorithms/union.hpp index d3a2daf66..d1d04d404 100644 --- a/include/boost/geometry/algorithms/union.hpp +++ b/include/boost/geometry/algorithms/union.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2014, 2017. -// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2017, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -279,9 +279,10 @@ struct union_ { typedef typename boost::range_value::type geometry_out; - typedef typename strategy::intersection::services::default_strategy + typedef typename strategy::relate::services::default_strategy < - typename cs_tag::type + Geometry1, + Geometry2 >::type strategy_type; dispatch::union_insert From c7e85409269b9bf9b76ee0944b7af8af19787b81 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:32:58 +0200 Subject: [PATCH 10/35] [io] In wkt read/write use default P/P equals strategy. --- include/boost/geometry/io/wkt/read.hpp | 19 +++++++++++++++---- include/boost/geometry/io/wkt/write.hpp | 17 ++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/include/boost/geometry/io/wkt/read.hpp b/include/boost/geometry/io/wkt/read.hpp index 9caa36cb4..414024b46 100644 --- a/include/boost/geometry/io/wkt/read.hpp +++ b/include/boost/geometry/io/wkt/read.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015. -// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #include @@ -295,7 +295,7 @@ struct stateful_range_appender should_append = is_next_expected || pt_index < core_detail::closure::minimum_ring_size::value - || !detail::equals::equals_point_point(point, first_point); + || disjoint(point, first_point); } ++pt_index; @@ -306,6 +306,17 @@ struct stateful_range_appender } private: + static inline bool disjoint(point_type const& p1, point_type const& p2) + { + // TODO: pass strategy + typedef typename strategy::disjoint::services::default_strategy + < + point_type, point_type + >::type strategy_type; + + return detail::disjoint::disjoint_point_point(p1, p2, strategy_type()); + } + size_type pt_index; point_type first_point; }; diff --git a/include/boost/geometry/io/wkt/write.hpp b/include/boost/geometry/io/wkt/write.hpp index 34af432fc..62d1d6cb4 100644 --- a/include/boost/geometry/io/wkt/write.hpp +++ b/include/boost/geometry/io/wkt/write.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2017 Mateusz Loskot, London, UK. // Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2015. -// 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 Menelaos Karavelas, on behalf of Oracle @@ -162,7 +162,7 @@ struct wkt_range if (ForceClosurePossible && force_closure && boost::size(range) > 1 - && detail::disjoint::disjoint_point_point(*begin, *(end - 1))) + && wkt_range::disjoint(*begin, *(end - 1))) { os << ","; stream_type::apply(os, *begin); @@ -174,6 +174,17 @@ struct wkt_range private: typedef typename boost::range_value::type point_type; + + static inline bool disjoint(point_type const& p1, point_type const& p2) + { + // TODO: pass strategy + typedef typename strategy::disjoint::services::default_strategy + < + point_type, point_type + >::type strategy_type; + + return detail::disjoint::disjoint_point_point(p1, p2, strategy_type()); + } }; /*! From dcaadf6257e2b60fd45edc5e86209b05b673a636 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:34:35 +0200 Subject: [PATCH 11/35] [test][envelope][strategies] Update strategies used for testing. --- .../envelope_expand/envelope_on_spheroid.cpp | 31 ++++++++++++++----- test/strategies/segment_envelope.cpp | 6 ++-- 2 files changed, 26 insertions(+), 11 deletions(-) diff --git a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp b/test/algorithms/envelope_expand/envelope_on_spheroid.cpp index 6b26eeacb..dc0bd559d 100644 --- a/test/algorithms/envelope_expand/envelope_on_spheroid.cpp +++ b/test/algorithms/envelope_expand/envelope_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 @@ -65,14 +65,29 @@ struct test_envelope static inline void apply(Geometry& geometry, Box& detected) { - bg::strategy::envelope::geographic_segment - < - FormulaPolicy, - bg::srs::spheroid, - double - > envelope_geographic_segment_strategy; + typedef bg::strategy::envelope::spherical_point point_strategy_t; + typedef bg::strategy::envelope::spherical_multipoint multi_point_strategy_t; + typedef bg::strategy::envelope::spherical_box box_strategy_t; + typedef bg::strategy::envelope::geographic, double> strategy_t; - bg::envelope(geometry, detected, envelope_geographic_segment_strategy); + typename boost::mpl::if_c + < + boost::is_same::type, bg::point_tag>::value, + point_strategy_t, + typename boost::mpl::if_c + < + boost::is_same::type, bg::multi_point_tag>::value, + multi_point_strategy_t, + typename boost::mpl::if_c + < + boost::is_same::type, bg::box_tag>::value, + box_strategy_t, + strategy_t + >::type + >::type + >::type strategy; + + bg::envelope(geometry, detected, strategy); } }; diff --git a/test/strategies/segment_envelope.cpp b/test/strategies/segment_envelope.cpp index 7ece77686..09610e3c0 100644 --- a/test/strategies/segment_envelope.cpp +++ b/test/strategies/segment_envelope.cpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016-2017 Oracle and/or its affiliates. +// Copyright (c) 2016-2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -41,9 +41,9 @@ void test_strategies_lat(P p1, P p2, CT expected_max, CT expected_min, BOOST_CHECK_CLOSE(p_max_degree_geo, expected_max, error); BOOST_CHECK_CLOSE(p_min_degree_geo, expected_min, error); - bg::strategy::envelope::spherical_segment strategy_sph; + typedef bg::strategy::envelope::spherical_segment strategy_sph_t; - strategy_sph.apply(p1, p2, box); + strategy_sph_t::apply(p1, p2, box); CT p_min_degree_sph = bg::get<0, 1>(box); CT p_max_degree_sph = bg::get<1, 1>(box); From 9ebdda95cc80cd38c8cf8766d90227664935eabc Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 03:35:33 +0200 Subject: [PATCH 12/35] [test][is_valid] Add test case failing with Midpoint passed to point_on_border. --- test/algorithms/is_valid.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/algorithms/is_valid.cpp b/test/algorithms/is_valid.cpp index e6b84ff4d..a3fac0a8d 100644 --- a/test/algorithms/is_valid.cpp +++ b/test/algorithms/is_valid.cpp @@ -1,7 +1,7 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2014-2015, Oracle and/or its affiliates. +// Copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -869,6 +869,9 @@ inline void test_open_multipolygons() test::apply("mpg09", "MULTIPOLYGON(((0 0,10 0,10 10,0 10)),((0 0,9 1,9 2)))", false); + test::apply("mpg09_2", + "MULTIPOLYGON(((0 0,5 1,10 0,10 10,0 10)),((1 1,9 1,9 2)))", + false); // one polygon inside another and boundaries not touching test::apply("mpg10", From 5847581734cc5a2e1643d079cdbe67814d593aa1 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 17:35:47 +0200 Subject: [PATCH 13/35] [algorithms] Fix copyright date. --- include/boost/geometry/algorithms/detail/point_on_border.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/geometry/algorithms/detail/point_on_border.hpp b/include/boost/geometry/algorithms/detail/point_on_border.hpp index 7116586a4..b3e14fecb 100644 --- a/include/boost/geometry/algorithms/detail/point_on_border.hpp +++ b/include/boost/geometry/algorithms/detail/point_on_border.hpp @@ -5,7 +5,7 @@ // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. // This file was modified by Oracle on 2017, 2018. -// Modifications copyright (c) 2018 Oracle and/or its affiliates. +// Modifications copyright (c) 2017-2018 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 From fbe8f51cd1849fad8ad2dcfd19d49c773ffa98dd Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 19:39:28 +0200 Subject: [PATCH 14/35] [is_valid] Fix overlapping interiors condition (replace 2x point_on_border with relate). --- .../detail/is_valid/multipolygon.hpp | 2 +- .../algorithms/detail/is_valid/polygon.hpp | 26 +++++++------------ 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index ed24b1381..b0b638a2b 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -128,7 +128,7 @@ private: = strategy.get_envelope_strategy(); // call partition to check if polygons are disjoint from each other - typename base::template item_visitor_type item_visitor(within_strategy); + typename base::template item_visitor_type item_visitor(strategy); geometry::partition < diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index b3f6c8228..b7d00f7eb 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -217,25 +217,19 @@ protected: , m_strategy(strategy) {} - template - inline bool is_within(Item const& first, Item const& second) - { - typename point_type::type point; - - // TODO: this should check for a point on the interior, instead - // of on border. Or it should check using the overlap function. - - return geometry::point_on_border(point, first) - && geometry::within(point, second, m_strategy); - } - template inline bool apply(partition_item const& item1, partition_item const& item2) { - if (! items_overlap - && (is_within(*item1.get(), *item2.get()) - || is_within(*item2.get(), *item1.get()))) + typedef boost::mpl::vector + < + geometry::de9im::static_mask<'T'>, + geometry::de9im::static_mask<'*', 'T'>, + geometry::de9im::static_mask<'*', '*', '*', 'T'> + > relate_mask_t; + + if ( ! items_overlap + && geometry::relate(*item1.get(), *item2.get(), relate_mask_t(), m_strategy) ) { items_overlap = true; return false; // interrupt @@ -337,7 +331,7 @@ protected: // call partition to check if interior rings are disjoint from // each other - item_visitor_type item_visitor(in_interior_strategy); + item_visitor_type item_visitor(strategy); geometry::partition < From c15b32944d711b39b4d3875d36cb32137dfaead5 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Fri, 12 Oct 2018 19:40:29 +0200 Subject: [PATCH 15/35] [test][is_valid] Add test failing with midpoint in point_on_border. --- test/algorithms/is_valid_failure.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/algorithms/is_valid_failure.cpp b/test/algorithms/is_valid_failure.cpp index cbdd29180..96a2af0e6 100644 --- a/test/algorithms/is_valid_failure.cpp +++ b/test/algorithms/is_valid_failure.cpp @@ -1,9 +1,10 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) // Unit Test -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Licensed under the Boost Software License version 1.0. // http://www.boost.org/users/license.html @@ -851,6 +852,9 @@ void test_open_multipolygons() test::apply("mpg09", "MULTIPOLYGON(((0 0,10 0,10 10,0 10)),((0 0,9 1,9 2)))", bg::failure_intersecting_interiors); + test::apply("mpg09_2", + "MULTIPOLYGON(((0 0,5 1,10 0,10 10,0 10)),((1 1,9 1,9 2)))", + bg::failure_intersecting_interiors); // one polygon inside another and boundaries not touching test::apply("mpg10", From 4ac1f450ff3be712b8637d7ef305bff91eab1335 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 13 Oct 2018 12:46:01 +0200 Subject: [PATCH 16/35] [algorithms][strategies] Move disjoint Box/Box CS- specific code to strategies and use these strategies in algorithms. --- .../buffer/buffered_piece_collection.hpp | 25 +++- .../detail/buffer/get_piece_turns.hpp | 7 +- .../buffer/turn_in_original_visitor.hpp | 8 +- .../detail/buffer/turn_in_piece_visitor.hpp | 8 +- .../algorithms/detail/disjoint/box_box.hpp | 136 +++--------------- .../detail/disjoint/multipoint_geometry.hpp | 13 +- .../detail/disjoint/segment_box.hpp | 31 +++- .../detail/overlay/assign_parents.hpp | 15 +- .../algorithms/detail/overlay/get_turns.hpp | 11 +- .../detail/overlay/self_turn_points.hpp | 11 +- .../detail/relate/multi_point_geometry.hpp | 11 +- .../detail/sections/section_box_policies.hpp | 8 +- .../strategies/cartesian/disjoint_box_box.hpp | 111 ++++++++++++++ .../strategies/cartesian/intersection.hpp | 8 ++ .../cartesian/point_in_poly_winding.hpp | 7 + .../boost/geometry/strategies/disjoint.hpp | 9 +- .../geographic/disjoint_segment_box.hpp | 5 +- .../geographic/distance_segment_box.hpp | 7 +- .../strategies/geographic/intersection.hpp | 8 ++ .../strategies/spherical/disjoint_box_box.hpp | 134 +++++++++++++++++ .../spherical/disjoint_segment_box.hpp | 8 +- .../spherical/distance_segment_box.hpp | 15 +- .../strategies/spherical/intersection.hpp | 8 ++ .../spherical/point_in_poly_winding.hpp | 11 +- 24 files changed, 442 insertions(+), 173 deletions(-) create mode 100644 include/boost/geometry/strategies/cartesian/disjoint_box_box.hpp create mode 100644 include/boost/geometry/strategies/spherical/disjoint_box_box.hpp diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index ba824243c..b1bd62dac 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2016-2017. -// Modifications copyright (c) 2016-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2016-2018. +// Modifications copyright (c) 2016-2018 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, @@ -635,6 +635,11 @@ struct buffered_piece_collection { // Check if a turn is inside any of the originals + typedef original_ovelaps_box + < + typename IntersectionStrategy::disjoint_box_box_strategy_type + > original_ovelaps_box_type; + turn_in_original_visitor visitor(m_turns); geometry::partition < @@ -643,7 +648,7 @@ struct buffered_piece_collection detail::partition::include_all_policy >::apply(m_turns, robust_originals, visitor, turn_get_box(), turn_in_original_ovelaps_box(), - original_get_box(), original_ovelaps_box()); + original_get_box(), original_ovelaps_box_type()); bool const deflate = distance_strategy.negative(); @@ -906,12 +911,17 @@ struct buffered_piece_collection > visitor(m_pieces, offsetted_rings, m_turns, m_intersection_strategy, m_robust_policy); + typedef detail::section::overlaps_section_box + < + typename IntersectionStrategy::disjoint_box_box_strategy_type + > overlaps_section_box_type; + geometry::partition < robust_box_type >::apply(monotonic_sections, visitor, detail::section::get_section_box(), - detail::section::overlaps_section_box()); + overlaps_section_box_type()); } insert_rescaled_piece_turns(); @@ -929,12 +939,17 @@ struct buffered_piece_collection turn_vector_type, piece_vector_type > visitor(m_turns, m_pieces); + typedef piece_ovelaps_box + < + typename IntersectionStrategy::disjoint_box_box_strategy_type + > piece_ovelaps_box_type; + geometry::partition < robust_box_type >::apply(m_turns, m_pieces, visitor, turn_get_box(), turn_ovelaps_box(), - piece_get_box(), piece_ovelaps_box()); + piece_get_box(), piece_ovelaps_box_type()); } } 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 506ff5847..f7e85aaca 100644 --- a/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/get_piece_turns.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 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, @@ -292,7 +292,8 @@ public: || is_adjacent(piece1, piece2) || is_on_same_convex_ring(piece1, piece2) || detail::disjoint::disjoint_box_box(section1.bounding_box, - section2.bounding_box) ) + section2.bounding_box, + m_intersection_strategy.get_disjoint_box_box_strategy()) ) { return true; } diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp index 70053536f..9f5335f10 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2016, 2018. +// Modifications copyright (c) 2016-2018 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, @@ -38,12 +38,14 @@ struct original_get_box } }; +template struct original_ovelaps_box { template static inline bool apply(Box const& box, Original const& original) { - return ! detail::disjoint::disjoint_box_box(box, original.m_box); + return ! detail::disjoint::disjoint_box_box(box, original.m_box, + DisjointBoxBoxStrategy()); } }; diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp index e066c27f3..bdf1aa9f8 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2016. -// Modifications copyright (c) 2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2016, 2018. +// Modifications copyright (c) 2016-2018 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, @@ -58,6 +58,7 @@ struct piece_get_box } }; +template struct piece_ovelaps_box { template @@ -73,7 +74,8 @@ struct piece_ovelaps_box return false; } - return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope); + return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope, + DisjointBoxBoxStrategy()); } }; diff --git a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp index 87618939b..67f063321 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/box_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2013-2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -23,139 +23,30 @@ #include -#include -#include - #include -#include -#include - +// For backward compatibility +#include +#include namespace boost { namespace geometry { + #ifndef DOXYGEN_NO_DETAIL namespace detail { namespace disjoint { -template -< - typename Box1, typename Box2, - std::size_t Dimension = 0, - std::size_t DimensionCount = dimension::value, - typename CSTag = typename tag_cast - < - typename cs_tag::type, - spherical_tag - >::type -> -struct box_box -{ - template - static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&) - { - return apply(box1, box2); - } - - static inline bool apply(Box1 const& box1, Box2 const& box2) - { - if (get(box1) < get(box2)) - { - return true; - } - if (get(box1) > get(box2)) - { - return true; - } - return box_box - < - Box1, Box2, - Dimension + 1, DimensionCount - >::apply(box1, box2); - } -}; - - -template -struct box_box -{ - static inline bool apply(Box1 const& , Box2 const& ) - { - return false; - } -}; - - -template -struct box_box -{ - template - static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&) - { - return apply(box1, box2); - } - - static inline bool apply(Box1 const& box1, Box2 const& box2) - { - typedef typename geometry::select_most_precise - < - typename coordinate_type::type, - typename coordinate_type::type - >::type calc_t; - typedef typename coordinate_system::type::units units_t; - typedef math::detail::constants_on_spheroid constants; - - calc_t const b1_min = get(box1); - calc_t const b1_max = get(box1); - calc_t const b2_min = get(box2); - calc_t const b2_max = get(box2); - - // min <= max <=> diff >= 0 - calc_t const diff1 = b1_max - b1_min; - calc_t const diff2 = b2_max - b2_min; - - // check the intersection if neither box cover the whole globe - if (diff1 < constants::period() && diff2 < constants::period()) - { - // calculate positive longitude translation with b1_min as origin - calc_t const diff_min = math::longitude_distance_unsigned(b1_min, b2_min); - calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min - calc_t b2_max_transl = b2_min_transl - constants::period() + diff2; - - // if the translation is too close then use the original point - // note that math::abs(b2_max_transl - b2_max) takes values very - // close to k*2*constants::period() for k=0,1,2,... - if (math::abs(b2_max_transl - b2_max) < constants::period() / 2) - { - b2_max_transl = b2_max; - } - - if (b2_min_transl > b1_max // b2_min right of b1_max - && b2_max_transl < b1_min) // b2_max left of b1_min - { - return true; - } - } - - return box_box - < - Box1, Box2, - 1, DimensionCount - >::apply(box1, box2); - } -}; - /*! \brief Internal utility function to detect if boxes are disjoint \note Is used from other algorithms, declared separately to avoid circular references */ -template -inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2) +template +inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const&) { - return box_box::apply(box1, box2); + return Strategy::apply(box1, box2); } @@ -170,8 +61,13 @@ namespace dispatch template struct disjoint - : detail::disjoint::box_box -{}; +{ + template + static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&) + { + return Strategy::apply(box1, box2); + } +}; } // namespace dispatch diff --git a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp index d7aa9089e..9d3a76a62 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp @@ -1,8 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2014-2017, Oracle and/or its affiliates. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2014-2018, Oracle and/or its affiliates. // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -320,13 +320,15 @@ private: } }; + template struct overlaps_box_box_pair { template inline bool apply(Box const& box, BoxPair const& box_pair) const { // The default strategy is enough for Box/Box - return ! detail::disjoint::disjoint_box_box(box_pair.first, box); + return ! detail::disjoint::disjoint_box_box(box_pair.first, box, + DisjointBoxBoxStrategy()); } }; @@ -390,6 +392,11 @@ public: item_visitor_type visitor(multi_geometry, strategy); + typedef overlaps_box_box_pair + < + typename Strategy::disjoint_box_box_strategy_type + > overlaps_box_box_pair_type; + geometry::partition < box1_type @@ -397,7 +404,7 @@ public: expand_box_point(), overlaps_box_point(), expand_box_box_pair(), - overlaps_box_box_pair()); + overlaps_box_box_pair_type()); return ! visitor.intersection_found(); } diff --git a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index 9896245e8..d3af239a8 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -67,24 +67,41 @@ struct disjoint_segment_box_sphere_or_spheroid operator T () const; }; - template + template + < + typename Segment, typename Box, + typename AzimuthStrategy, + typename NormalizeStrategy, + typename DisjointBoxBoxStrategy + > static inline bool apply(Segment const& segment, Box const& box, AzimuthStrategy const& azimuth_strategy, - NormalizeStrategy const& normalize_strategy) + NormalizeStrategy const& normalize_strategy, + DisjointBoxBoxStrategy const& disjoint_box_box_strategy) { typedef typename point_type::type segment_point; segment_point vertex; - return apply(segment, box, vertex, azimuth_strategy, normalize_strategy) - != disjoint_info::intersect; + return apply(segment, box, vertex, + azimuth_strategy, + normalize_strategy, + disjoint_box_box_strategy) != disjoint_info::intersect; } - template + template + < + typename Segment, typename Box, + typename P, + typename AzimuthStrategy, + typename NormalizeStrategy, + typename DisjointBoxBoxStrategy + > static inline disjoint_info apply(Segment const& segment, Box const& box, P& vertex, AzimuthStrategy const& azimuth_strategy, - NormalizeStrategy const& ) + NormalizeStrategy const& , + DisjointBoxBoxStrategy const& disjoint_box_box_strategy) { assert_dimension_equal(); @@ -141,7 +158,7 @@ struct disjoint_segment_box_sphere_or_spheroid azimuth_strategy, alp1); - if (disjoint_box_box(box, box_seg)) + if (disjoint_box_box(box, box_seg, disjoint_box_box_strategy)) { return disjoint_return_value; } diff --git a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp index 3be539348..7e9b1c22a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/assign_parents.hpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 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, @@ -135,12 +135,14 @@ struct ring_info_helper_get_box } }; +template struct ring_info_helper_ovelaps_box { template static inline bool apply(Box const& box, InputItem const& item) { - return ! geometry::detail::disjoint::disjoint_box_box(box, item.envelope); + return ! geometry::detail::disjoint::disjoint_box_box( + box, item.envelope, DisjointBoxBoxStrategy()); } }; @@ -328,11 +330,16 @@ inline void assign_parents(Geometry1 const& geometry1, Strategy > visitor(geometry1, geometry2, collection, ring_map, strategy, check_for_orientation); + typedef ring_info_helper_ovelaps_box + < + typename Strategy::disjoint_box_box_strategy_type + > overlaps_box_type; + geometry::partition < box_type >::apply(vector, visitor, ring_info_helper_get_box(), - ring_info_helper_ovelaps_box()); + overlaps_box_type()); } if (check_for_orientation) diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index 9cc0199fb..b6d161438 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -431,7 +431,9 @@ struct section_visitor template inline bool apply(Section const& sec1, Section const& sec2) { - if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)) + if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, + sec2.bounding_box, + m_intersection_strategy.get_disjoint_box_box_strategy())) { // false if interrupted return get_turns_in_sections @@ -510,12 +512,17 @@ public: intersection_strategy, robust_policy, turns, interrupt_policy); + typedef detail::section::overlaps_section_box + < + typename IntersectionStrategy::disjoint_box_box_strategy_type + > overlaps_section_box_type; + geometry::partition < box_type >::apply(sec1, sec2, visitor, detail::section::get_section_box(), - detail::section::overlaps_section_box()); + overlaps_section_box_type()); } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp index ba8d1c413..64b954d7a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp @@ -99,7 +99,9 @@ struct self_section_visitor template inline bool apply(Section const& sec1, Section const& sec2) { - if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box) + if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, + sec2.bounding_box, + m_intersection_strategy.get_disjoint_box_box_strategy()) && ! sec1.duplicate && ! sec2.duplicate) { @@ -163,13 +165,18 @@ struct get_turns Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent); + typedef detail::section::overlaps_section_box + < + typename IntersectionStrategy::disjoint_box_box_strategy_type + > overlaps_section_box_type; + // false if interrupted geometry::partition < box_type >::apply(sec, visitor, detail::section::get_section_box(), - detail::section::overlaps_section_box()); + overlaps_section_box_type()); return ! interrupt_policy.has_intersections; } diff --git a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp index e41bb9206..e53984dd1 100644 --- a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp @@ -283,13 +283,15 @@ class multi_point_multi_geometry_ii_ib } }; + template struct overlaps_box_box_pair { template static inline bool apply(Box const& box, BoxPair const& box_pair) { // The default strategy is enough for Box/Box - return ! detail::disjoint::disjoint_box_box(box_pair.first, box); + return ! detail::disjoint::disjoint_box_box(box_pair.first, box, + DisjointBoxBoxStrategy()); } }; @@ -377,6 +379,11 @@ public: { item_visitor_type visitor(multi_geometry, tc, result, strategy); + typedef overlaps_box_box_pair + < + Strategy::disjoint_box_box_strategy_type + > overlaps_box_box_pair_type; + geometry::partition < box1_type @@ -384,7 +391,7 @@ public: expand_box_point(), overlaps_box_point(), expand_box_box_pair(), - overlaps_box_box_pair()); + overlaps_box_box_pair_type()); } }; diff --git a/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp b/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp index cf0670030..0d61f5444 100644 --- a/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp +++ b/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp @@ -2,6 +2,10 @@ // Copyright (c) 2015 Barend Gehrels, 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 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) @@ -30,12 +34,14 @@ struct get_section_box } }; +template struct overlaps_section_box { template static inline bool apply(Box const& box, Section const& section) { - return ! detail::disjoint::disjoint_box_box(box, section.bounding_box); + return ! detail::disjoint::disjoint_box_box(box, section.bounding_box, + DisjointBoxBoxStrategy()); } }; diff --git a/include/boost/geometry/strategies/cartesian/disjoint_box_box.hpp b/include/boost/geometry/strategies/cartesian/disjoint_box_box.hpp new file mode 100644 index 000000000..da8ae7b1d --- /dev/null +++ b/include/boost/geometry/strategies/cartesian/disjoint_box_box.hpp @@ -0,0 +1,111 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, 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. + +// 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_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP + +#include + +#include +#include + +#include + + +namespace boost { namespace geometry { namespace strategy { namespace disjoint +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +template +< + typename Box1, typename Box2, + std::size_t Dimension = 0, + std::size_t DimensionCount = dimension::value +> +struct box_box +{ + static inline bool apply(Box1 const& box1, Box2 const& box2) + { + if (get(box1) < get(box2)) + { + return true; + } + if (get(box1) > get(box2)) + { + return true; + } + return box_box + < + Box1, Box2, + Dimension + 1, DimensionCount + >::apply(box1, box2); + } +}; + + +template +struct box_box +{ + static inline bool apply(Box1 const& , Box2 const& ) + { + return false; + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +struct cartesian_box_box +{ + template + static inline bool apply(Box1 const& box1, Box2 const& box2) + { + return detail::box_box::apply(box1, box2); + } +}; + + +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +namespace services +{ + +template +struct default_strategy +{ + typedef disjoint::cartesian_box_box type; +}; + + +} // namespace services + + +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + + +}}}} // namespace boost::geometry::strategy::disjoint + + +#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index 576994ba3..ac357875f 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -34,6 +34,7 @@ #include #include +#include #include #include #include @@ -162,6 +163,13 @@ struct cartesian_segments return equals_point_point_strategy_type(); } + typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type; + + static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy() + { + return disjoint_box_box_strategy_type(); + } + template struct segment_intersection_info { diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index d7546d710..ddba9212d 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -109,6 +110,12 @@ public: return side_strategy_type::get_equals_point_point_strategy(); } + typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type; + static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy() + { + return disjoint_box_box_strategy_type(); + } + // Typedefs and static methods to fulfill the concept typedef Point point_type; typedef PointOfSegment segment_point_type; diff --git a/include/boost/geometry/strategies/disjoint.hpp b/include/boost/geometry/strategies/disjoint.hpp index 23d2cede4..c111d2b8f 100644 --- a/include/boost/geometry/strategies/disjoint.hpp +++ b/include/boost/geometry/strategies/disjoint.hpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2017, Oracle and/or its affiliates. +// Copyright (c) 2017-2018, Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -77,13 +77,6 @@ struct default_strategy > {}; -template -struct default_strategy -{ - // dummy strategy which will be ignored - typedef geometry::default_strategy type; -}; - } // namespace services #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS diff --git a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp index 963e280d7..99279630e 100644 --- a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp @@ -34,6 +34,8 @@ #include #include #include +#include +#include namespace boost { namespace geometry { namespace strategy { namespace disjoint @@ -95,7 +97,8 @@ public: geographic_tag >::apply(segment, box, azimuth_geographic, - strategy::normalize::spherical_point()); + strategy::normalize::spherical_point(), + strategy::disjoint::spherical_box_box()); } private: diff --git a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp index 34b3797e7..c59db0dd2 100644 --- a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp @@ -2,6 +2,7 @@ // Copyright (c) 2018 Oracle and/or its affiliates. // Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle +// 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 @@ -18,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include @@ -118,7 +122,8 @@ struct geographic_segment_box >(p0,p1,top_left,top_right,bottom_left,bottom_right, geographic_segment_box(), az_strategy, es_strategy, - normalize::spherical_point()); + normalize::spherical_point(), + disjoint::spherical_box_box()); } template diff --git a/include/boost/geometry/strategies/geographic/intersection.hpp b/include/boost/geometry/strategies/geographic/intersection.hpp index e77d8b104..1ff84ac5c 100644 --- a/include/boost/geometry/strategies/geographic/intersection.hpp +++ b/include/boost/geometry/strategies/geographic/intersection.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,13 @@ struct geographic_segments return equals_point_point_strategy_type(); } + typedef disjoint::spherical_box_box disjoint_box_box_strategy_type; + + static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy() + { + return disjoint_box_box_strategy_type(); + } + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; template diff --git a/include/boost/geometry/strategies/spherical/disjoint_box_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_box_box.hpp new file mode 100644 index 000000000..f0504a8b1 --- /dev/null +++ b/include/boost/geometry/strategies/spherical/disjoint_box_box.hpp @@ -0,0 +1,134 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) + +// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. +// Copyright (c) 2008-2015 Bruno Lalande, Paris, France. +// Copyright (c) 2009-2015 Mateusz Loskot, London, UK. +// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. + +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. + +// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle +// Contributed and/or modified by Menelaos Karavelas, 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. + +// 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_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP +#define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP + +#include + +#include + +#include +#include + +#include +#include + + +namespace boost { namespace geometry { namespace strategy { namespace disjoint +{ + +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + +struct box_box_on_spheroid +{ + template + static inline bool apply(Box1 const& box1, Box2 const& box2) + { + typedef typename geometry::select_most_precise + < + typename coordinate_type::type, + typename coordinate_type::type + >::type calc_t; + typedef typename geometry::detail::cs_angular_units::type units_t; + typedef math::detail::constants_on_spheroid constants; + + calc_t const b1_min = get(box1); + calc_t const b1_max = get(box1); + calc_t const b2_min = get(box2); + calc_t const b2_max = get(box2); + + // min <= max <=> diff >= 0 + calc_t const diff1 = b1_max - b1_min; + calc_t const diff2 = b2_max - b2_min; + + // check the intersection if neither box cover the whole globe + if (diff1 < constants::period() && diff2 < constants::period()) + { + // calculate positive longitude translation with b1_min as origin + calc_t const diff_min = math::longitude_distance_unsigned(b1_min, b2_min); + calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min + calc_t b2_max_transl = b2_min_transl - constants::period() + diff2; + + // if the translation is too close then use the original point + // note that math::abs(b2_max_transl - b2_max) takes values very + // close to k*2*constants::period() for k=0,1,2,... + if (math::abs(b2_max_transl - b2_max) < constants::period() / 2) + { + b2_max_transl = b2_max; + } + + if (b2_min_transl > b1_max // b2_min right of b1_max + && b2_max_transl < b1_min) // b2_max left of b1_min + { + return true; + } + } + + return box_box + < + Box1, Box2, 1 + >::apply(box1, box2); + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + +struct spherical_box_box +{ + template + static inline bool apply(Box1 const& box1, Box2 const& box2) + { + return detail::box_box_on_spheroid::apply(box1, box2); + } +}; + + +namespace services +{ + +template +struct default_strategy +{ + typedef disjoint::spherical_box_box type; +}; + +template +struct default_strategy +{ + typedef disjoint::spherical_box_box type; +}; + +template +struct default_strategy +{ + typedef disjoint::spherical_box_box type; +}; + +} // namespace services + +}}}} // namespace boost::geometry::strategy::disjoint + + +#endif // BOOST_GEOMETRY_STRATEGIES_SPHERICAL_DISJOINT_BOX_BOX_HPP diff --git a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp index 1432f7d89..945851b97 100644 --- a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp @@ -29,8 +29,11 @@ #include #include -#include #include +#include +#include +#include + namespace boost { namespace geometry { namespace strategy { namespace disjoint { @@ -71,7 +74,8 @@ struct segment_box_spherical spherical_equatorial_tag >::apply(segment, box, azimuth_strategy, - strategy::normalize::spherical_point()); + strategy::normalize::spherical_point(), + strategy::disjoint::spherical_box_box()); } }; diff --git a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp index b334a921d..020c291ab 100644 --- a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp @@ -13,6 +13,10 @@ #include +#include +#include +#include + namespace boost { namespace geometry { @@ -31,7 +35,8 @@ struct generic_segment_box typename SegmentBoxStrategy, typename AzimuthStrategy, typename EnvelopeSegmentStrategy, - typename NormalizePointStrategy + typename NormalizePointStrategy, + typename DisjointBoxBoxStrategy > static inline ReturnType segment_below_of_box( SegmentPoint const& p0, @@ -43,7 +48,8 @@ struct generic_segment_box SegmentBoxStrategy const& sb_strategy, AzimuthStrategy const& az_strategy, EnvelopeSegmentStrategy const& es_strategy, - NormalizePointStrategy const& np_strategy) + NormalizePointStrategy const& np_strategy, + DisjointBoxBoxStrategy const& dbb_strategy) { ReturnType result; typename LessEqual::other less_equal; @@ -69,7 +75,7 @@ struct generic_segment_box SegmentPoint p_max; disjoint_info_type disjoint_result = disjoint_sb:: - apply(seg, input_box, p_max, az_strategy, np_strategy); + apply(seg, input_box, p_max, az_strategy, np_strategy, dbb_strategy); if (disjoint_result == disjoint_info_type::intersect) //intersect { @@ -226,7 +232,8 @@ struct spherical_segment_box >(p0,p1,top_left,top_right,bottom_left,bottom_right, spherical_segment_box(), az_strategy, es_strategy, - normalize::spherical_point()); + normalize::spherical_point(), + disjoint::spherical_box_box()); } template diff --git a/include/boost/geometry/strategies/spherical/intersection.hpp b/include/boost/geometry/strategies/spherical/intersection.hpp index 2141e626a..be7558ad6 100644 --- a/include/boost/geometry/strategies/spherical/intersection.hpp +++ b/include/boost/geometry/strategies/spherical/intersection.hpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,13 @@ struct ecef_segments return equals_point_point_strategy_type(); } + typedef disjoint::spherical_box_box disjoint_box_box_strategy_type; + + static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy() + { + return disjoint_box_box_strategy_type(); + } + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; // segment_intersection_info cannot outlive relate_ecef_segments diff --git a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp index 803559a5f..0cbe40df9 100644 --- a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -63,7 +64,7 @@ class spherical_winding_base CalculationType >::type calculation_type; - typedef typename coordinate_system::type::units units_t; + typedef typename geometry::detail::cs_angular_units::type units_t; typedef math::detail::constants_on_spheroid constants; /*! subclass to keep state */ @@ -146,6 +147,12 @@ public: return m_side_strategy.get_equals_point_point_strategy(); } + typedef disjoint::spherical_box_box disjoint_box_box_strategy_type; + static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy() + { + return disjoint_box_box_strategy_type(); + } + spherical_winding_base() {} @@ -440,7 +447,7 @@ private: count_info const& ci) const { typedef typename coordinate_type::type scoord_t; - typedef typename coordinate_system::type::units units_t; + typedef typename geometry::detail::cs_angular_units::type units_t; if (math::equals(get<1>(point), get<1>(se))) { From bcd6e69b41428ce546280c2c35a64a6d09117364 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 13 Oct 2018 12:46:33 +0200 Subject: [PATCH 17/35] [test][partition] Use disjoint Box/Box strategy in partition test. --- test/algorithms/detail/partition.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/algorithms/detail/partition.cpp b/test/algorithms/detail/partition.cpp index fc899631d..9d63668d8 100644 --- a/test/algorithms/detail/partition.cpp +++ b/test/algorithms/detail/partition.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland. // -// This file was modified by Oracle on 2017. -// Modifications copyright (c) 2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2017, 2018. +// Modifications copyright (c) 2017-2018 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, @@ -65,7 +65,12 @@ struct ovelaps_box template static inline bool apply(Box const& box, InputItem const& item) { - return ! bg::detail::disjoint::disjoint_box_box(box, item.box); + typename bg::strategy::disjoint::services::default_strategy + < + Box, Box + >::type strategy; + + return ! bg::detail::disjoint::disjoint_box_box(box, item.box, strategy); } }; From 7d45cae67b9ed43d5ee9881da1d39c2a6ce427dd Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 13 Oct 2018 13:04:58 +0200 Subject: [PATCH 18/35] [algorithms][strategies] Fix several compilation errors. Shadowing of template parameters, missing typename keywords, missing includes. --- .../boost/geometry/algorithms/detail/disjoint/point_point.hpp | 2 +- .../boost/geometry/algorithms/detail/envelope/multipoint.hpp | 2 +- include/boost/geometry/algorithms/detail/envelope/range.hpp | 2 +- include/boost/geometry/algorithms/detail/expand/box.hpp | 2 +- include/boost/geometry/algorithms/detail/expand/point.hpp | 4 ++-- include/boost/geometry/algorithms/detail/expand/segment.hpp | 2 +- include/boost/geometry/algorithms/simplify.hpp | 2 +- .../boost/geometry/strategies/spherical/envelope_segment.hpp | 2 ++ 8 files changed, 10 insertions(+), 8 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp index 33c1397e0..f91712934 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_point.hpp @@ -66,7 +66,7 @@ namespace dispatch template struct disjoint { - template + template static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& ) { diff --git a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp index 7d9216e20..ce112e4d7 100644 --- a/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/multipoint.hpp @@ -33,7 +33,7 @@ namespace dispatch template struct envelope { - template + template static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& ) { Strategy::apply(multipoint, mbr); diff --git a/include/boost/geometry/algorithms/detail/envelope/range.hpp b/include/boost/geometry/algorithms/detail/envelope/range.hpp index b834eaf94..e1fdb950d 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range.hpp @@ -102,7 +102,7 @@ struct envelope_multi_range Box& mbr, Strategy const& strategy) { - Strategy::template multi_state state; + typename Strategy::template multi_state state; for (; it != last; ++it) { if (! geometry::is_empty(*it)) diff --git a/include/boost/geometry/algorithms/detail/expand/box.hpp b/include/boost/geometry/algorithms/detail/expand/box.hpp index 4a2bfa1d2..41571dba6 100644 --- a/include/boost/geometry/algorithms/detail/expand/box.hpp +++ b/include/boost/geometry/algorithms/detail/expand/box.hpp @@ -48,7 +48,7 @@ struct expand box_tag, box_tag > { - template + template static inline void apply(BoxOut& box_out, BoxIn const& box_in, Strategy const& ) diff --git a/include/boost/geometry/algorithms/detail/expand/point.hpp b/include/boost/geometry/algorithms/detail/expand/point.hpp index e46f5c973..d4a9097cb 100644 --- a/include/boost/geometry/algorithms/detail/expand/point.hpp +++ b/include/boost/geometry/algorithms/detail/expand/point.hpp @@ -51,8 +51,8 @@ struct expand box_tag, point_tag > { - template - static inline void apply(Box& box, + template + static inline void apply(BoxOut& box, Point const& point, Strategy const& ) { diff --git a/include/boost/geometry/algorithms/detail/expand/segment.hpp b/include/boost/geometry/algorithms/detail/expand/segment.hpp index 61894ae43..3f6f19602 100644 --- a/include/boost/geometry/algorithms/detail/expand/segment.hpp +++ b/include/boost/geometry/algorithms/detail/expand/segment.hpp @@ -49,7 +49,7 @@ struct expand box_tag, segment_tag > { - template + template static inline void apply(Box& box, Segment const& segment, Strategy const& strategy) diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index 4e1884ea5..a96b8a1e7 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -73,7 +73,7 @@ struct simplify_range_insert static inline void apply(Range const& range, OutputIterator out, Distance const& max_distance, Strategy const& strategy) { - typedef Strategy::distance_strategy_type::equals_point_point_strategy_type + typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type equals_strategy_type; boost::ignore_unused(strategy); diff --git a/include/boost/geometry/strategies/spherical/envelope_segment.hpp b/include/boost/geometry/strategies/spherical/envelope_segment.hpp index ce202965b..33e6173e5 100644 --- a/include/boost/geometry/strategies/spherical/envelope_segment.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_segment.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #include #include #include From 7af8085f75c69745006ce37ca62677fb93112109 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sat, 13 Oct 2018 22:43:12 +0200 Subject: [PATCH 19/35] [algorithms][strategies] Move CS-specific code of envelope_segment from algorithms details to strategies. This fixes circular dependencies. --- .../detail/disjoint/segment_box.hpp | 18 +- .../algorithms/detail/envelope/segment.hpp | 404 ----------------- .../strategies/cartesian/envelope_segment.hpp | 53 ++- .../geographic/envelope_segment.hpp | 24 +- .../strategies/spherical/envelope_segment.hpp | 429 +++++++++++++++++- 5 files changed, 478 insertions(+), 450 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index d3af239a8..9e08ac6bf 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -39,6 +39,9 @@ #include +// Temporary, for envelope_segment_impl +#include + namespace boost { namespace geometry { @@ -151,12 +154,15 @@ struct disjoint_segment_box_sphere_or_spheroid geometry::model::box box_seg; - geometry::detail::envelope::envelope_segment_impl - ::template apply(lon1, lat1, - lon2, lat2, - box_seg, - azimuth_strategy, - alp1); + // TODO: Shouldn't CSTag be taken from the caller, not from the segment? + strategy::envelope::detail::envelope_segment_impl + < + segment_cs_type + >::template apply(lon1, lat1, + lon2, lat2, + box_seg, + azimuth_strategy, + alp1); if (disjoint_box_box(box, box_seg, disjoint_box_box_strategy)) { diff --git a/include/boost/geometry/algorithms/detail/envelope/segment.hpp b/include/boost/geometry/algorithms/detail/envelope/segment.hpp index 051d40b8e..af79f3450 100644 --- a/include/boost/geometry/algorithms/detail/envelope/segment.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/segment.hpp @@ -19,31 +19,10 @@ #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP #include -#include -#include -#include - -#include -#include -#include -#include -#include -#include #include -#include - -#include - -#include -#include - #include -#include -#include -#include - #include // For backward compatibility @@ -58,384 +37,6 @@ namespace boost { namespace geometry namespace detail { namespace envelope { -template -struct envelope_segment_call_vertex_latitude -{ - template - static inline CalculationType apply(T1 const& lat1, - T2 const& alp1, - Strategy const& ) - { - return geometry::formula::vertex_latitude - ::apply(lat1, alp1); - } -}; - -template -struct envelope_segment_call_vertex_latitude -{ - template - static inline CalculationType apply(T1 const& lat1, - T2 const& alp1, - Strategy const& strategy) - { - return geometry::formula::vertex_latitude - ::apply(lat1, alp1, strategy.model()); - } -}; - -template -struct envelope_segment_convert_polar -{ - template - static inline void pre(T & , T & ) {} - - template - static inline void post(T & , T & ) {} -}; - -template -struct envelope_segment_convert_polar -{ - template - static inline void pre(T & lat1, T & lat2) - { - lat1 = math::latitude_convert_ep(lat1); - lat2 = math::latitude_convert_ep(lat2); - } - - template - static inline void post(T & lat1, T & lat2) - { - lat1 = math::latitude_convert_ep(lat1); - lat2 = math::latitude_convert_ep(lat2); - std::swap(lat1, lat2); - } -}; - -template -class envelope_segment_impl -{ -private: - - // degrees or radians - template - static inline void swap(CalculationType& lon1, - CalculationType& lat1, - CalculationType& lon2, - CalculationType& lat2) - { - std::swap(lon1, lon2); - std::swap(lat1, lat2); - } - - // radians - template - static inline bool contains_pi_half(CalculationType const& a1, - CalculationType const& a2) - { - // azimuths a1 and a2 are assumed to be in radians - BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2)); - - static CalculationType const pi_half = math::half_pi(); - - return (a1 < a2) - ? (a1 < pi_half && pi_half < a2) - : (a1 > pi_half && pi_half > a2); - } - - // radians or degrees - template - static inline bool crosses_antimeridian(CoordinateType const& lon1, - CoordinateType const& lon2) - { - typedef math::detail::constants_on_spheroid - < - CoordinateType, Units - > constants; - - return math::abs(lon1 - lon2) > constants::half_period(); // > pi - } - - // degrees or radians - template - static inline void compute_box_corners(CalculationType& lon1, - CalculationType& lat1, - CalculationType& lon2, - CalculationType& lat2, - CalculationType a1, - CalculationType a2, - Strategy const& strategy) - { - // coordinates are assumed to be in radians - BOOST_GEOMETRY_ASSERT(lon1 <= lon2); - boost::ignore_unused(lon1, lon2); - - CalculationType lat1_rad = math::as_radian(lat1); - CalculationType lat2_rad = math::as_radian(lat2); - - if (math::equals(a1, a2)) - { - // the segment must lie on the equator or is very short or is meridian - return; - } - - if (lat1 > lat2) - { - std::swap(lat1, lat2); - std::swap(lat1_rad, lat2_rad); - std::swap(a1, a2); - } - - if (contains_pi_half(a1, a2)) - { - CalculationType p_max = envelope_segment_call_vertex_latitude - ::apply(lat1_rad, a1, strategy); - - CalculationType const mid_lat = lat1 + lat2; - if (mid_lat < 0) - { - // update using min latitude - CalculationType const lat_min_rad = -p_max; - CalculationType const lat_min - = math::from_radian(lat_min_rad); - - if (lat1 > lat_min) - { - lat1 = lat_min; - } - } - else - { - // update using max latitude - CalculationType const lat_max_rad = p_max; - CalculationType const lat_max - = math::from_radian(lat_max_rad); - - if (lat2 < lat_max) - { - lat2 = lat_max; - } - } - } - } - - template - static inline void special_cases(CalculationType& lon1, - CalculationType& lat1, - CalculationType& lon2, - CalculationType& lat2) - { - typedef math::detail::constants_on_spheroid - < - CalculationType, Units - > constants; - - bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude()); - bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude()); - - if (is_pole1 && is_pole2) - { - // both points are poles; nothing more to do: - // longitudes are already normalized to 0 - // but just in case - lon1 = 0; - lon2 = 0; - } - else if (is_pole1 && !is_pole2) - { - // first point is a pole, second point is not: - // make the longitude of the first point the same as that - // of the second point - lon1 = lon2; - } - else if (!is_pole1 && is_pole2) - { - // second point is a pole, first point is not: - // make the longitude of the second point the same as that - // of the first point - lon2 = lon1; - } - - if (lon1 == lon2) - { - // segment lies on a meridian - if (lat1 > lat2) - { - std::swap(lat1, lat2); - } - return; - } - - BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2); - - if (lon1 > lon2) - { - swap(lon1, lat1, lon2, lat2); - } - - if (crosses_antimeridian(lon1, lon2)) - { - lon1 += constants::period(); - swap(lon1, lat1, lon2, lat2); - } - } - - template - < - typename Units, - typename CalculationType, - typename Box - > - static inline void create_box(CalculationType lon1, - CalculationType lat1, - CalculationType lon2, - CalculationType lat2, - Box& mbr) - { - typedef typename coordinate_type::type box_coordinate_type; - - typedef typename helper_geometry - < - Box, box_coordinate_type, Units - >::type helper_box_type; - - helper_box_type helper_mbr; - - geometry::set - < - min_corner, 0 - >(helper_mbr, boost::numeric_cast(lon1)); - - geometry::set - < - min_corner, 1 - >(helper_mbr, boost::numeric_cast(lat1)); - - geometry::set - < - max_corner, 0 - >(helper_mbr, boost::numeric_cast(lon2)); - - geometry::set - < - max_corner, 1 - >(helper_mbr, boost::numeric_cast(lat2)); - - transform_units(helper_mbr, mbr); - } - - - template - static inline void apply(CalculationType& lon1, - CalculationType& lat1, - CalculationType& lon2, - CalculationType& lat2, - Strategy const& strategy) - { - special_cases(lon1, lat1, lon2, lat2); - - CalculationType lon1_rad = math::as_radian(lon1); - CalculationType lat1_rad = math::as_radian(lat1); - CalculationType lon2_rad = math::as_radian(lon2); - CalculationType lat2_rad = math::as_radian(lat2); - CalculationType alp1, alp2; - strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2); - - compute_box_corners(lon1, lat1, lon2, lat2, alp1, alp2, strategy); - } - - template - static inline void apply(CalculationType& lon1, - CalculationType& lat1, - CalculationType& lon2, - CalculationType& lat2, - Strategy const& strategy, - CalculationType alp1) - { - special_cases(lon1, lat1, lon2, lat2); - - CalculationType lon1_rad = math::as_radian(lon1); - CalculationType lat1_rad = math::as_radian(lat1); - CalculationType lon2_rad = math::as_radian(lon2); - CalculationType lat2_rad = math::as_radian(lat2); - CalculationType alp2; - strategy.apply_reverse(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp2); - - compute_box_corners(lon1, lat1, lon2, lat2, alp1, alp2, strategy); - } - -public: - template - < - typename Units, - typename CalculationType, - typename Box, - typename Strategy - > - static inline void apply(CalculationType lon1, - CalculationType lat1, - CalculationType lon2, - CalculationType lat2, - Box& mbr, - Strategy const& strategy) - { - typedef envelope_segment_convert_polar::type> convert_polar; - - convert_polar::pre(lat1, lat2); - - apply(lon1, lat1, lon2, lat2, strategy); - - convert_polar::post(lat1, lat2); - - create_box(lon1, lat1, lon2, lat2, mbr); - } - - template - < - typename Units, - typename CalculationType, - typename Box, - typename Strategy - > - static inline void apply(CalculationType lon1, - CalculationType lat1, - CalculationType lon2, - CalculationType lat2, - Box& mbr, - Strategy const& strategy, - CalculationType alp1) - { - typedef envelope_segment_convert_polar::type> convert_polar; - - convert_polar::pre(lat1, lat2); - - apply(lon1, lat1, lon2, lat2, strategy, alp1); - - convert_polar::post(lat1, lat2); - - create_box(lon1, lat1, lon2, lat2, mbr); - } -}; - -template -struct envelope_one_segment -{ - template - static inline void apply(Point const& p1, - Point const& p2, - Box& mbr) - { - envelope_one_point::apply(p1, mbr); - strategy::expand::detail::point_loop - < - Dimension, - DimensionCount - >::apply(mbr, p2); - } -}; - - template struct envelope_segment { @@ -445,12 +46,7 @@ struct envelope_segment Box& mbr, Strategy const& strategy) { - // first compute the envelope range for the first two coordinates strategy.apply(p1, p2, mbr); - - // now compute the envelope range for coordinates of - // dimension 2 and higher - envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr); } template diff --git a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp index 6bd5c15c4..cd52775da 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_segment.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_segment.hpp @@ -11,20 +11,46 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP #define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP +#include + #include #include -#include - +#include +#include #include - -namespace boost { namespace geometry +namespace boost { namespace geometry { namespace strategy { namespace envelope { -namespace strategy { namespace envelope +#ifndef DOXYGEN_NO_DETAIL +namespace detail { +template +struct envelope_one_segment +{ + template + static inline void apply(Point const& p1, + Point const& p2, + Box& mbr) + { + geometry::detail::envelope::envelope_one_point + < + Dimension, DimensionCount + >::apply(p1, mbr); + + strategy::expand::detail::point_loop + < + Dimension, DimensionCount + >::apply(mbr, p2); + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + template < typename CalculationType = void @@ -32,17 +58,14 @@ template class cartesian_segment { public: - template - static inline void apply(Point1 const& point1, Point2 const& point2, Box& box) + template + static inline void apply(Point const& point1, Point const& point2, Box& box) { - geometry::detail::envelope::envelope_one_segment - < - 0, - dimension::value - > - ::apply(point1, - point2, - box); + strategy::envelope::detail::envelope_one_segment + < + 0, + dimension::value + >::apply(point1, point2, box); } }; diff --git a/include/boost/geometry/strategies/geographic/envelope_segment.hpp b/include/boost/geometry/strategies/geographic/envelope_segment.hpp index ffe1a1a00..fda7868af 100644 --- a/include/boost/geometry/strategies/geographic/envelope_segment.hpp +++ b/include/boost/geometry/strategies/geographic/envelope_segment.hpp @@ -12,14 +12,14 @@ #define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP -#include -#include - #include +#include #include #include #include +#include +#include #include namespace boost { namespace geometry @@ -53,12 +53,11 @@ public: return box_expand_strategy_type(); } - template - inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const + template + inline void apply(Point const& point1, Point const& point2, Box& box) const { - Point1 p1_normalized; + Point p1_normalized, p2_normalized; strategy::normalize::spherical_point::apply(point1, p1_normalized); - Point2 p2_normalized; strategy::normalize::spherical_point::apply(point2, p2_normalized); geometry::strategy::azimuth::geographic @@ -70,10 +69,11 @@ public: typedef typename geometry::detail::cs_angular_units < - Point1 + Point >::type units_type; - detail::envelope::envelope_segment_impl + // first compute the envelope range for the first two coordinates + strategy::envelope::detail::envelope_segment_impl < geographic_tag >::template apply(geometry::get<0>(p1_normalized), @@ -83,6 +83,12 @@ public: box, azimuth_geographic); + // now compute the envelope range for coordinates of + // dimension 2 and higher + strategy::envelope::detail::envelope_one_segment + < + 2, dimension::value + >::apply(point1, point2, box); } private: diff --git a/include/boost/geometry/strategies/spherical/envelope_segment.hpp b/include/boost/geometry/strategies/spherical/envelope_segment.hpp index 33e6173e5..a35922271 100644 --- a/include/boost/geometry/strategies/spherical/envelope_segment.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_segment.hpp @@ -11,20 +11,409 @@ #ifndef BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP #define BOOST_GEOMETRY_STRATEGIES_SPHERICAL_ENVELOPE_SEGMENT_HPP -#include -#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include #include +#include +#include #include + +#include +#include + +#include + +#include #include +#include #include #include -namespace boost { namespace geometry +#include + +namespace boost { namespace geometry { namespace strategy { namespace envelope { -namespace strategy { namespace envelope +#ifndef DOXYGEN_NO_DETAIL +namespace detail { +template +struct envelope_segment_call_vertex_latitude +{ + template + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& ) + { + return geometry::formula::vertex_latitude + ::apply(lat1, alp1); + } +}; + +template +struct envelope_segment_call_vertex_latitude +{ + template + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& strategy) + { + return geometry::formula::vertex_latitude + ::apply(lat1, alp1, strategy.model()); + } +}; + +template +struct envelope_segment_convert_polar +{ + template + static inline void pre(T & , T & ) {} + + template + static inline void post(T & , T & ) {} +}; + +template +struct envelope_segment_convert_polar +{ + template + static inline void pre(T & lat1, T & lat2) + { + lat1 = math::latitude_convert_ep(lat1); + lat2 = math::latitude_convert_ep(lat2); + } + + template + static inline void post(T & lat1, T & lat2) + { + lat1 = math::latitude_convert_ep(lat1); + lat2 = math::latitude_convert_ep(lat2); + std::swap(lat1, lat2); + } +}; + +template +class envelope_segment_impl +{ +private: + + // degrees or radians + template + static inline void swap(CalculationType& lon1, + CalculationType& lat1, + CalculationType& lon2, + CalculationType& lat2) + { + std::swap(lon1, lon2); + std::swap(lat1, lat2); + } + + // radians + template + static inline bool contains_pi_half(CalculationType const& a1, + CalculationType const& a2) + { + // azimuths a1 and a2 are assumed to be in radians + BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2)); + + static CalculationType const pi_half = math::half_pi(); + + return (a1 < a2) + ? (a1 < pi_half && pi_half < a2) + : (a1 > pi_half && pi_half > a2); + } + + // radians or degrees + template + static inline bool crosses_antimeridian(CoordinateType const& lon1, + CoordinateType const& lon2) + { + typedef math::detail::constants_on_spheroid + < + CoordinateType, Units + > constants; + + return math::abs(lon1 - lon2) > constants::half_period(); // > pi + } + + // degrees or radians + template + static inline void compute_box_corners(CalculationType& lon1, + CalculationType& lat1, + CalculationType& lon2, + CalculationType& lat2, + CalculationType a1, + CalculationType a2, + Strategy const& strategy) + { + // coordinates are assumed to be in radians + BOOST_GEOMETRY_ASSERT(lon1 <= lon2); + boost::ignore_unused(lon1, lon2); + + CalculationType lat1_rad = math::as_radian(lat1); + CalculationType lat2_rad = math::as_radian(lat2); + + if (math::equals(a1, a2)) + { + // the segment must lie on the equator or is very short or is meridian + return; + } + + if (lat1 > lat2) + { + std::swap(lat1, lat2); + std::swap(lat1_rad, lat2_rad); + std::swap(a1, a2); + } + + if (contains_pi_half(a1, a2)) + { + CalculationType p_max = envelope_segment_call_vertex_latitude + ::apply(lat1_rad, a1, strategy); + + CalculationType const mid_lat = lat1 + lat2; + if (mid_lat < 0) + { + // update using min latitude + CalculationType const lat_min_rad = -p_max; + CalculationType const lat_min + = math::from_radian(lat_min_rad); + + if (lat1 > lat_min) + { + lat1 = lat_min; + } + } + else + { + // update using max latitude + CalculationType const lat_max_rad = p_max; + CalculationType const lat_max + = math::from_radian(lat_max_rad); + + if (lat2 < lat_max) + { + lat2 = lat_max; + } + } + } + } + + template + static inline void special_cases(CalculationType& lon1, + CalculationType& lat1, + CalculationType& lon2, + CalculationType& lat2) + { + typedef math::detail::constants_on_spheroid + < + CalculationType, Units + > constants; + + bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude()); + bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude()); + + if (is_pole1 && is_pole2) + { + // both points are poles; nothing more to do: + // longitudes are already normalized to 0 + // but just in case + lon1 = 0; + lon2 = 0; + } + else if (is_pole1 && !is_pole2) + { + // first point is a pole, second point is not: + // make the longitude of the first point the same as that + // of the second point + lon1 = lon2; + } + else if (!is_pole1 && is_pole2) + { + // second point is a pole, first point is not: + // make the longitude of the second point the same as that + // of the first point + lon2 = lon1; + } + + if (lon1 == lon2) + { + // segment lies on a meridian + if (lat1 > lat2) + { + std::swap(lat1, lat2); + } + return; + } + + BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2); + + if (lon1 > lon2) + { + swap(lon1, lat1, lon2, lat2); + } + + if (crosses_antimeridian(lon1, lon2)) + { + lon1 += constants::period(); + swap(lon1, lat1, lon2, lat2); + } + } + + template + < + typename Units, + typename CalculationType, + typename Box + > + static inline void create_box(CalculationType lon1, + CalculationType lat1, + CalculationType lon2, + CalculationType lat2, + Box& mbr) + { + typedef typename coordinate_type::type box_coordinate_type; + + typedef typename helper_geometry + < + Box, box_coordinate_type, Units + >::type helper_box_type; + + helper_box_type helper_mbr; + + geometry::set + < + min_corner, 0 + >(helper_mbr, boost::numeric_cast(lon1)); + + geometry::set + < + min_corner, 1 + >(helper_mbr, boost::numeric_cast(lat1)); + + geometry::set + < + max_corner, 0 + >(helper_mbr, boost::numeric_cast(lon2)); + + geometry::set + < + max_corner, 1 + >(helper_mbr, boost::numeric_cast(lat2)); + + geometry::detail::envelope::transform_units(helper_mbr, mbr); + } + + + template + static inline void apply(CalculationType& lon1, + CalculationType& lat1, + CalculationType& lon2, + CalculationType& lat2, + Strategy const& strategy) + { + special_cases(lon1, lat1, lon2, lat2); + + CalculationType lon1_rad = math::as_radian(lon1); + CalculationType lat1_rad = math::as_radian(lat1); + CalculationType lon2_rad = math::as_radian(lon2); + CalculationType lat2_rad = math::as_radian(lat2); + CalculationType alp1, alp2; + strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2); + + compute_box_corners(lon1, lat1, lon2, lat2, alp1, alp2, strategy); + } + + template + static inline void apply(CalculationType& lon1, + CalculationType& lat1, + CalculationType& lon2, + CalculationType& lat2, + Strategy const& strategy, + CalculationType alp1) + { + special_cases(lon1, lat1, lon2, lat2); + + CalculationType lon1_rad = math::as_radian(lon1); + CalculationType lat1_rad = math::as_radian(lat1); + CalculationType lon2_rad = math::as_radian(lon2); + CalculationType lat2_rad = math::as_radian(lat2); + CalculationType alp2; + strategy.apply_reverse(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp2); + + compute_box_corners(lon1, lat1, lon2, lat2, alp1, alp2, strategy); + } + +public: + template + < + typename Units, + typename CalculationType, + typename Box, + typename Strategy + > + static inline void apply(CalculationType lon1, + CalculationType lat1, + CalculationType lon2, + CalculationType lat2, + Box& mbr, + Strategy const& strategy) + { + typedef envelope_segment_convert_polar::type> convert_polar; + + convert_polar::pre(lat1, lat2); + + apply(lon1, lat1, lon2, lat2, strategy); + + convert_polar::post(lat1, lat2); + + create_box(lon1, lat1, lon2, lat2, mbr); + } + + template + < + typename Units, + typename CalculationType, + typename Box, + typename Strategy + > + static inline void apply(CalculationType lon1, + CalculationType lat1, + CalculationType lon2, + CalculationType lat2, + Box& mbr, + Strategy const& strategy, + CalculationType alp1) + { + typedef envelope_segment_convert_polar::type> convert_polar; + + convert_polar::pre(lat1, lat2); + + apply(lon1, lat1, lon2, lat2, strategy, alp1); + + convert_polar::post(lat1, lat2); + + create_box(lon1, lat1, lon2, lat2, mbr); + } +}; + +} // namespace detail +#endif // DOXYGEN_NO_DETAIL + + template < typename CalculationType = void @@ -38,27 +427,35 @@ public: return box_expand_strategy_type(); } - template - static inline void apply(Point1 const& point1, Point2 const& point2, + template + static inline void apply(Point const& point1, Point const& point2, Box& box) { - Point1 p1_normalized; + Point p1_normalized, p2_normalized; strategy::normalize::spherical_point::apply(point1, p1_normalized); - Point2 p2_normalized; strategy::normalize::spherical_point::apply(point2, p2_normalized); geometry::strategy::azimuth::spherical azimuth_spherical; - typedef typename geometry::detail::cs_angular_units::type units_type; + typedef typename geometry::detail::cs_angular_units::type units_type; - geometry::detail::envelope::envelope_segment_impl - ::template apply(geometry::get<0>(p1_normalized), - geometry::get<1>(p1_normalized), - geometry::get<0>(p2_normalized), - geometry::get<1>(p2_normalized), - box, - azimuth_spherical); + // first compute the envelope range for the first two coordinates + strategy::envelope::detail::envelope_segment_impl + < + spherical_equatorial_tag + >::template apply(geometry::get<0>(p1_normalized), + geometry::get<1>(p1_normalized), + geometry::get<0>(p2_normalized), + geometry::get<1>(p2_normalized), + box, + azimuth_spherical); + // now compute the envelope range for coordinates of + // dimension 2 and higher + strategy::envelope::detail::envelope_one_segment + < + 2, dimension::value + >::apply(point1, point2, box); } }; From 7dc81a98ddb32d7dc384637e0e691359ba437d24 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 14 Oct 2018 00:09:31 +0200 Subject: [PATCH 20/35] [algorithms] Add missing typename keywords. --- .../geometry/algorithms/detail/relate/multi_point_geometry.hpp | 2 +- include/boost/geometry/algorithms/simplify.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp index e53984dd1..64bb53bff 100644 --- a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp @@ -381,7 +381,7 @@ public: typedef overlaps_box_box_pair < - Strategy::disjoint_box_box_strategy_type + typename Strategy::disjoint_box_box_strategy_type > overlaps_box_box_pair_type; geometry::partition diff --git a/include/boost/geometry/algorithms/simplify.hpp b/include/boost/geometry/algorithms/simplify.hpp index a96b8a1e7..8daac6dda 100644 --- a/include/boost/geometry/algorithms/simplify.hpp +++ b/include/boost/geometry/algorithms/simplify.hpp @@ -116,7 +116,7 @@ struct simplify_range static inline void apply(RangeIn const& range, RangeOut& out, Distance const& max_distance, Strategy const& strategy) { - typedef Strategy::distance_strategy_type::equals_point_point_strategy_type + typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type equals_strategy_type; // For a RING: From fe63e8e27b8c30acfa9010adc364b20baae40d0a Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 14 Oct 2018 00:10:21 +0200 Subject: [PATCH 21/35] [index] In intersection_content() explicitly use disjoint B/B strategy. --- .../index/detail/algorithms/intersection_content.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp index 437f90b46..3baa5cb4e 100644 --- a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp +++ b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp @@ -24,7 +24,12 @@ namespace boost { namespace geometry { namespace index { namespace detail { template inline typename default_content_result::type intersection_content(Box const& box1, Box const& box2) { - bool const intersects = ! geometry::detail::disjoint::box_box::apply(box1, box2); + typedef strategy::disjoint::services::default_strategy + < + Box, Box + > strategy_type; + + bool const intersects = ! geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type()); if ( intersects ) { From 99293c814fbec7f7cbe4bfc884674bf12af2a963 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 14 Oct 2018 00:33:26 +0200 Subject: [PATCH 22/35] [is_valid] Fix unused variable warning. --- .../geometry/algorithms/detail/is_valid/multipolygon.hpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp index b0b638a2b..8fe580332 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/multipolygon.hpp @@ -116,13 +116,6 @@ private: } // prepare strategies - typedef typename std::iterator_traits::value_type polygon_type; - typedef typename Strategy::template point_in_geometry_strategy - < - polygon_type, polygon_type - >::type within_strategy_type; - within_strategy_type const within_strategy - = strategy.template get_point_in_geometry_strategy(); typedef typename Strategy::envelope_strategy_type envelope_strategy_type; envelope_strategy_type const envelope_strategy = strategy.get_envelope_strategy(); From 80ffb22901e9bdb5081338bec24945dfb3b1b005 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 14 Oct 2018 00:41:12 +0200 Subject: [PATCH 23/35] [strategies][envelope] Simplify envelope::cartesian_point strategy. This also makes template keywords unnecessary. --- .../boost/geometry/strategies/cartesian/envelope_point.hpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/include/boost/geometry/strategies/cartesian/envelope_point.hpp b/include/boost/geometry/strategies/cartesian/envelope_point.hpp index 51c006abf..3f900c718 100644 --- a/include/boost/geometry/strategies/cartesian/envelope_point.hpp +++ b/include/boost/geometry/strategies/cartesian/envelope_point.hpp @@ -77,12 +77,10 @@ struct cartesian_point template static inline void apply(Point const& point, Box& mbr) { - typedef geometry::detail::envelope::envelope_one_point + geometry::detail::envelope::envelope_one_point < 0, dimension::value - > per_corner; - per_corner::apply(point, mbr); - per_corner::apply(point, mbr); + >::apply(point, mbr); } }; From 12ff7a6b8e2518984408cd7225325c93025b1787 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 14 Oct 2018 00:50:04 +0200 Subject: [PATCH 24/35] [is_valid] Fix unused variable warning. --- .../boost/geometry/algorithms/detail/is_valid/polygon.hpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp index b7d00f7eb..834ce5af2 100644 --- a/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp +++ b/include/boost/geometry/algorithms/detail/is_valid/polygon.hpp @@ -319,12 +319,6 @@ protected: } // prepare strategies - typedef typename Strategy::template point_in_geometry_strategy - < - inter_ring_type, inter_ring_type - >::type in_interior_strategy_type; - in_interior_strategy_type const in_interior_strategy - = strategy.template get_point_in_geometry_strategy(); typedef typename Strategy::envelope_strategy_type envelope_strategy_type; envelope_strategy_type const envelope_strategy = strategy.get_envelope_strategy(); From 6c879b78ac5e33704cb29a40ca6848b4ed71c3f5 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Oct 2018 01:22:28 +0200 Subject: [PATCH 25/35] [algorithms][strategies] Implement separate cart/sph P/B within strategies. Change P/B within strategy concept (no struct template parameters). --- .../algorithms/detail/within/interface.hpp | 12 +- .../detail/within/point_in_geometry.hpp | 8 +- .../agnostic/point_in_box_by_side.hpp | 17 +- .../strategies/cartesian/point_in_box.hpp | 179 +++++++++++------- .../strategies/concepts/within_concept.hpp | 50 +++-- 5 files changed, 161 insertions(+), 105 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/within/interface.hpp b/include/boost/geometry/algorithms/detail/within/interface.hpp index 23263604c..048cc01f7 100644 --- a/include/boost/geometry/algorithms/detail/within/interface.hpp +++ b/include/boost/geometry/algorithms/detail/within/interface.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2013, 2014, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -70,13 +70,7 @@ struct within Geometry2 const& geometry2, Strategy const& strategy) { - concepts::within::check - < - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - Strategy - >(); + concepts::within::check(); return dispatch::within::apply(geometry1, geometry2, strategy); } diff --git a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp index 4617630ad..1509528d7 100644 --- a/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/within/point_in_geometry.hpp @@ -366,13 +366,7 @@ namespace detail { namespace within { template inline int point_in_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy) { - concepts::within::check - < - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - Strategy - >(); + concepts::within::check(); return detail_dispatch::within::point_in_geometry::apply(point, geometry, strategy); } diff --git a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp index 8493b57c3..80cad8523 100644 --- a/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp +++ b/include/boost/geometry/strategies/agnostic/point_in_box_by_side.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018 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. @@ -60,16 +64,17 @@ struct decide_covered_by // This strategy is not suitable for boxes in non-cartesian CSes having edges // longer than 180deg because e.g. the SSF formula picks the side of the closer // longitude, so for long edges the side is the opposite. -template +template struct point_in_box_by_side { - typedef typename strategy::side::services::default_strategy - < - typename cs_tag::type - >::type side_strategy_type; - + template static inline bool apply(Point const& point, Box const& box) { + typedef typename strategy::side::services::default_strategy + < + typename cs_tag::type + >::type side_strategy_type; + // Create (counterclockwise) array of points, the fifth one closes it // Every point should be on the LEFT side (=1), or ON the border (=0), // So >= 1 or >= 0 diff --git a/include/boost/geometry/strategies/cartesian/point_in_box.hpp b/include/boost/geometry/strategies/cartesian/point_in_box.hpp index 1c14125a6..36684a453 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_box.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_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-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 Adam Wulkiewicz, on behalf of Oracle @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -33,6 +34,10 @@ namespace boost { namespace geometry { namespace strategy namespace within { +#ifndef DOXYGEN_NO_DETAIL +namespace detail +{ + struct within_coord { template @@ -101,7 +106,7 @@ struct longitude_range < Value1, Value2 >::type calc_t; - typedef typename coordinate_system::type::units units_t; + typedef typename geometry::detail::cs_angular_units::type units_t; typedef math::detail::constants_on_spheroid constants; if (CoordCheck::apply(value, min_value, max_value)) @@ -142,18 +147,16 @@ struct covered_by_range template < template class SubStrategy, - typename Point, - typename Box, + typename CSTag, // cartesian_tag or spherical_tag std::size_t Dimension, std::size_t DimensionCount > struct relate_point_box_loop { + template static inline bool apply(Point const& point, Box const& box) { - typedef typename tag_cast::type, spherical_tag>::type cs_tag_t; - - if (! SubStrategy::apply(get(point), + if (! SubStrategy::apply(get(point), get(box), get(box)) ) @@ -164,7 +167,7 @@ struct relate_point_box_loop return relate_point_box_loop < SubStrategy, - Point, Box, + CSTag, Dimension + 1, DimensionCount >::apply(point, box); } @@ -174,78 +177,119 @@ struct relate_point_box_loop template < template class SubStrategy, - typename Point, - typename Box, + typename CSTag, std::size_t DimensionCount > -struct relate_point_box_loop +struct relate_point_box_loop { + template static inline bool apply(Point const& , Box const& ) { return true; } }; +} // namespace detail +#endif DOXYGEN_NO_DETAIL -template -< - typename Point, - typename Box, - template class SubStrategy = within_range -> -struct point_in_box +struct cartesian_point_box { + template static inline bool apply(Point const& point, Box const& box) { - return relate_point_box_loop + return detail::relate_point_box_loop < - SubStrategy, - Point, Box, - 0, dimension::type::value + detail::within_range, + cartesian_tag, + 0, dimension::value + >::apply(point, box); + } +}; + +struct spherical_point_box +{ + template + static inline bool apply(Point const& point, Box const& box) + { + return detail::relate_point_box_loop + < + detail::within_range, + spherical_tag, + 0, dimension::value >::apply(point, box); } }; +#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +namespace services +{ + +template +struct default_strategy + < + Point, Box, + point_tag, box_tag, + pointlike_tag, areal_tag, + cartesian_tag, cartesian_tag + > +{ + typedef within::cartesian_point_box type; +}; + +// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag +template +struct default_strategy + < + Point, Box, + point_tag, box_tag, + pointlike_tag, areal_tag, + spherical_tag, spherical_tag + > +{ + typedef within::spherical_point_box type; +}; + + +} // namespace services +#endif DOXYGEN_NO_STRATEGY_SPECIALIZATIONS + } // namespace within +namespace covered_by +{ + +struct cartesian_point_box +{ + template + static inline bool apply(Point const& point, Box const& box) + { + return within::detail::relate_point_box_loop + < + within::detail::covered_by_range, + cartesian_tag, + 0, dimension::value + >::apply(point, box); + } +}; + +struct spherical_point_box +{ + template + static inline bool apply(Point const& point, Box const& box) + { + return within::detail::relate_point_box_loop + < + within::detail::covered_by_range, + spherical_tag, + 0, dimension::value + >::apply(point, box); + } +}; + #ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS - - -namespace within { namespace services -{ - -template -struct default_strategy - < - Point, Box, - point_tag, box_tag, - pointlike_tag, areal_tag, - cartesian_tag, cartesian_tag - > -{ - typedef within::point_in_box type; -}; - -// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag -template -struct default_strategy - < - Point, Box, - point_tag, box_tag, - pointlike_tag, areal_tag, - spherical_tag, spherical_tag - > -{ - typedef within::point_in_box type; -}; - - -}} // namespace within::services - - -namespace covered_by { namespace services +namespace services { @@ -258,11 +302,7 @@ struct default_strategy cartesian_tag, cartesian_tag > { - typedef within::point_in_box - < - Point, Box, - within::covered_by_range - > type; + typedef covered_by::cartesian_point_box type; }; // spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag @@ -275,20 +315,17 @@ struct default_strategy spherical_tag, spherical_tag > { - typedef within::point_in_box - < - Point, Box, - within::covered_by_range - > type; + typedef covered_by::spherical_point_box type; }; -}} // namespace covered_by::services - - +} // namespace services #endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +} // namespace covered_by + + }}} // namespace boost::geometry::strategy diff --git a/include/boost/geometry/strategies/concepts/within_concept.hpp b/include/boost/geometry/strategies/concepts/within_concept.hpp index c02d0dc50..93680f693 100644 --- a/include/boost/geometry/strategies/concepts/within_concept.hpp +++ b/include/boost/geometry/strategies/concepts/within_concept.hpp @@ -4,6 +4,10 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. +// This file was modified by Oracle on 2018. +// Modifications copyright (c) 2018 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. @@ -20,6 +24,10 @@ #include #include +#include +#include +#include + #include @@ -107,7 +115,7 @@ public : #endif }; -template +template class WithinStrategyPointBox { #ifndef DOXYGEN_NO_CONCEPT_MEMBERS @@ -165,7 +173,7 @@ class WithinStrategyPointBox public : BOOST_CONCEPT_USAGE(WithinStrategyPointBox) { - checker::apply(&Strategy::apply); + checker::apply(&Strategy::template apply); } #endif }; @@ -241,26 +249,36 @@ namespace within namespace dispatch { -template +template +< + typename Geometry1, typename Geometry2, + typename FirstTag, typename SecondTag, typename CastedTag, + typename Strategy +> struct check_within {}; -template -struct check_within +template +< + typename Geometry1, typename Geometry2, + typename AnyTag, + typename Strategy +> +struct check_within { BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal) ); }; -template -struct check_within +template +struct check_within { - BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox) ); + BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox) ); }; -template -struct check_within +template +struct check_within { BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox) ); }; @@ -274,10 +292,18 @@ struct check_within \brief Checks, in compile-time, the concept of any within-strategy \ingroup concepts */ -template +template inline void check() { - dispatch::check_within c; + dispatch::check_within + < + Geometry1, + Geometry2, + typename tag::type, + typename tag::type, + typename tag_cast::type, areal_tag>::type, + Strategy + > c; boost::ignore_unused(c); } From a0eb54fc27cdc52324b3bbf9434c576d5cc10771 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Oct 2018 01:23:15 +0200 Subject: [PATCH 26/35] [test][within] Update P/B within strategies. --- test/algorithms/within/within.cpp | 8 ++++---- test/algorithms/within/within_sph_geo.cpp | 4 ++-- test/strategies/point_in_box.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/algorithms/within/within.cpp b/test/algorithms/within/within.cpp index 07cea8d58..b095d1752 100644 --- a/test/algorithms/within/within.cpp +++ b/test/algorithms/within/within.cpp @@ -3,8 +3,8 @@ // Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland. -// This file was modified by Oracle on 2014, 2015, 2016. -// Modifications copyright (c) 2014-2016 Oracle and/or its affiliates. +// This file was modified by Oracle on 2014, 2015, 2016, 2018. +// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -109,7 +109,7 @@ void test_strategy() box_type b0(point_type(0, 0), point_type(5, 0)); bool r = bg::within(p, b, - bg::strategy::within::point_in_box()); + bg::strategy::within::cartesian_point_box()); BOOST_CHECK_EQUAL(r, true); r = bg::within(b, b, @@ -121,7 +121,7 @@ void test_strategy() BOOST_CHECK_EQUAL(r, false); r = bg::within(p, b, - bg::strategy::within::point_in_box_by_side()); + bg::strategy::within::point_in_box_by_side<>()); BOOST_CHECK_EQUAL(r, true); } diff --git a/test/algorithms/within/within_sph_geo.cpp b/test/algorithms/within/within_sph_geo.cpp index 486fafb80..6b0fb1b2c 100644 --- a/test/algorithms/within/within_sph_geo.cpp +++ b/test/algorithms/within/within_sph_geo.cpp @@ -1,6 +1,6 @@ // Boost.Geometry -// Copyright (c) 2016 Oracle and/or its affiliates. +// Copyright (c) 2016-2018 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, @@ -19,7 +19,7 @@ void test_point_box_by_side() // Test spherical boxes // See also http://www.gcmap.com/mapui?P=1E45N-19E45N-19E55N-1E55N-1E45N,10E55.1N,10E45.1N typedef bg::model::box box_t; - bg::strategy::within::point_in_box_by_side by_side; + bg::strategy::within::point_in_box_by_side<> by_side; box_t box; bg::read_wkt("POLYGON((1 45,19 55))", box); BOOST_CHECK_EQUAL(bg::within(Point(10, 55.1), box, by_side), true); diff --git a/test/strategies/point_in_box.cpp b/test/strategies/point_in_box.cpp index 1c5e04879..50d5f65a3 100644 --- a/test/strategies/point_in_box.cpp +++ b/test/strategies/point_in_box.cpp @@ -34,8 +34,8 @@ void test_box_of(std::string const& wkt_point, std::string const& wkt_box, // Also test with the non-default agnostic side version namespace wi = bg::strategy::within; - wi::point_in_box_by_side within_strategy; - wi::point_in_box_by_side covered_by_strategy; + wi::point_in_box_by_side<> within_strategy; + wi::point_in_box_by_side covered_by_strategy; detected_within = bg::within(point, box, within_strategy); detected_covered_by = bg::covered_by(point, box, covered_by_strategy); From 37569190dbab8c5d713a66fb712b10505b02589c Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Oct 2018 01:24:30 +0200 Subject: [PATCH 27/35] [formulas] Replace coordinate_system<>::type::units with cs_angular_units<>::type. --- include/boost/geometry/formulas/spherical.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/geometry/formulas/spherical.hpp b/include/boost/geometry/formulas/spherical.hpp index 862600232..964e2de30 100644 --- a/include/boost/geometry/formulas/spherical.hpp +++ b/include/boost/geometry/formulas/spherical.hpp @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -98,7 +99,7 @@ static inline PointSph cart3d_to_sph(Point3d const& point_3d) math::normalize_spheroidal_coordinates < - typename coordinate_system::type::units, + typename detail::cs_angular_units::type, coord_t >(lon, lat); From 4d2c60d23f87c24fe0f8a8ed8c25937d6e541a5f Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 15 Oct 2018 01:26:17 +0200 Subject: [PATCH 28/35] [algorithms][strategies] Propagate disjoint(P,B) and expand(B,B) strategies into algorithms. --- .../buffer/buffered_piece_collection.hpp | 23 ++++++++++++--- .../buffer/turn_in_original_visitor.hpp | 3 +- .../detail/buffer/turn_in_piece_visitor.hpp | 4 ++- .../detail/covered_by/interface.hpp | 12 ++------ .../detail/disjoint/multipoint_geometry.hpp | 29 ++++++++++++++----- .../algorithms/detail/disjoint/point_box.hpp | 15 ++++------ .../detail/disjoint/segment_box.hpp | 8 ++++- .../algorithms/detail/overlay/get_turns.hpp | 6 +++- .../detail/overlay/self_turn_points.hpp | 6 +++- .../detail/relate/multi_point_geometry.hpp | 16 +++++++--- .../detail/relate/topology_check.hpp | 7 ++--- .../detail/sections/section_box_policies.hpp | 4 ++- .../detail/sections/section_functions.hpp | 8 +++-- .../strategies/cartesian/intersection.hpp | 4 +++ .../cartesian/point_in_poly_winding.hpp | 3 ++ .../geographic/disjoint_segment_box.hpp | 2 ++ .../geographic/distance_segment_box.hpp | 1 + .../strategies/geographic/intersection.hpp | 4 +++ .../spherical/disjoint_segment_box.hpp | 1 + .../spherical/distance_segment_box.hpp | 7 ++++- .../strategies/spherical/intersection.hpp | 4 +++ .../spherical/point_in_poly_winding.hpp | 3 ++ 22 files changed, 122 insertions(+), 48 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp index b1bd62dac..54c600d24 100644 --- a/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/buffered_piece_collection.hpp @@ -635,6 +635,10 @@ struct buffered_piece_collection { // Check if a turn is inside any of the originals + typedef turn_in_original_ovelaps_box + < + typename IntersectionStrategy::disjoint_point_box_strategy_type + > turn_in_original_ovelaps_box_type; typedef original_ovelaps_box < typename IntersectionStrategy::disjoint_box_box_strategy_type @@ -647,7 +651,7 @@ struct buffered_piece_collection include_turn_policy, detail::partition::include_all_policy >::apply(m_turns, robust_originals, visitor, - turn_get_box(), turn_in_original_ovelaps_box(), + turn_get_box(), turn_in_original_ovelaps_box_type(), original_get_box(), original_ovelaps_box_type()); bool const deflate = distance_strategy.negative(); @@ -911,6 +915,10 @@ struct buffered_piece_collection > visitor(m_pieces, offsetted_rings, m_turns, m_intersection_strategy, m_robust_policy); + typedef detail::section::get_section_box + < + typename IntersectionStrategy::expand_box_strategy_type + > get_section_box_type; typedef detail::section::overlaps_section_box < typename IntersectionStrategy::disjoint_box_box_strategy_type @@ -920,7 +928,7 @@ struct buffered_piece_collection < robust_box_type >::apply(monotonic_sections, visitor, - detail::section::get_section_box(), + get_section_box_type(), overlaps_section_box_type()); } @@ -939,6 +947,10 @@ struct buffered_piece_collection turn_vector_type, piece_vector_type > visitor(m_turns, m_pieces); + typedef turn_ovelaps_box + < + typename IntersectionStrategy::disjoint_point_box_strategy_type + > turn_ovelaps_box_type; typedef piece_ovelaps_box < typename IntersectionStrategy::disjoint_box_box_strategy_type @@ -948,7 +960,7 @@ struct buffered_piece_collection < robust_box_type >::apply(m_turns, m_pieces, visitor, - turn_get_box(), turn_ovelaps_box(), + turn_get_box(), turn_ovelaps_box_type(), piece_get_box(), piece_ovelaps_box_type()); } @@ -1415,6 +1427,8 @@ struct buffered_piece_collection inline bool point_coveredby_original(point_type const& point) { + typedef typename IntersectionStrategy::disjoint_point_box_strategy_type d_pb_strategy_type; + robust_point_type any_point; geometry::recalculate(any_point, point, m_robust_policy); @@ -1431,7 +1445,8 @@ struct buffered_piece_collection { robust_original const& original = *it; if (detail::disjoint::disjoint_point_box(any_point, - original.m_box)) + original.m_box, + d_pb_strategy_type())) { continue; } diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp index 9f5335f10..665d4e4be 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_original_visitor.hpp @@ -58,6 +58,7 @@ struct include_turn_policy } }; +template struct turn_in_original_ovelaps_box { template @@ -70,7 +71,7 @@ struct turn_in_original_ovelaps_box } return ! geometry::detail::disjoint::disjoint_point_box( - turn.robust_point, box); + turn.robust_point, box, DisjointPointBoxStrategy()); } }; diff --git a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp index bdf1aa9f8..759a7c92d 100644 --- a/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp +++ b/include/boost/geometry/algorithms/detail/buffer/turn_in_piece_visitor.hpp @@ -88,12 +88,14 @@ struct turn_get_box } }; +template struct turn_ovelaps_box { template static inline bool apply(Box const& box, Turn const& turn) { - return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box); + return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box, + DisjointPointBoxStrategy()); } }; diff --git a/include/boost/geometry/algorithms/detail/covered_by/interface.hpp b/include/boost/geometry/algorithms/detail/covered_by/interface.hpp index 659907821..bdc92db43 100644 --- a/include/boost/geometry/algorithms/detail/covered_by/interface.hpp +++ b/include/boost/geometry/algorithms/detail/covered_by/interface.hpp @@ -4,8 +4,8 @@ // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. -// This file was modified by Oracle on 2013, 2014, 2017. -// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates. +// This file was modified by Oracle on 2013, 2014, 2017, 2018. +// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -63,13 +63,7 @@ struct covered_by Geometry2 const& geometry2, Strategy const& strategy) { - concepts::within::check - < - typename tag::type, - typename tag::type, - typename tag_cast::type, areal_tag>::type, - Strategy - >(); + concepts::within::check(); concepts::check(); concepts::check(); assert_dimension_equal(); diff --git a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp index 9d3a76a62..029d68be5 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/multipoint_geometry.hpp @@ -138,13 +138,15 @@ private: EnvelopeStrategy const& m_strategy; }; + template struct overlaps_box_point { template static inline bool apply(Box const& box, Point const& point) { // The default strategy is enough in this case - return ! detail::disjoint::disjoint_point_box(point, box); + return ! detail::disjoint::disjoint_point_box(point, box, + DisjointPointBoxStrategy()); } }; @@ -225,6 +227,7 @@ public: typedef typename Strategy::envelope_strategy_type envelope_strategy_type; typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type; + typedef typename Strategy::disjoint_point_box_strategy_type disjoint_pb_strategy_type; // TODO: disjoint Segment/Box may be called in partition multiple times // possibly for non-cartesian segments which could be slow. We should consider @@ -236,7 +239,7 @@ public: geometry::model::box::type> >::apply(multipoint, segment_range(linear), visitor, expand_box_point(), - overlaps_box_point(), + overlaps_box_point(), expand_box_segment(strategy.get_envelope_strategy()), overlaps_box_segment(strategy.get_disjoint_strategy())); @@ -256,8 +259,12 @@ class multi_point_single_geometry { public: template - static inline bool apply(MultiPoint const& multi_point, SingleGeometry const& single_geometry, Strategy const& strategy) + static inline bool apply(MultiPoint const& multi_point, + SingleGeometry const& single_geometry, + Strategy const& strategy) { + typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type; + typedef typename point_type::type point1_type; typedef typename point_type::type point2_type; typedef model::box box2_type; @@ -270,7 +277,7 @@ public: for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it ) { // The default strategy is enough for Point/Box - if (! detail::disjoint::disjoint_point_box(*it, box2) + if (! detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type()) && ! dispatch::disjoint::apply(*it, single_geometry, strategy)) { return false; @@ -310,13 +317,15 @@ private: } }; + template struct overlaps_box_point { template static inline bool apply(Box const& box, Point const& point) { // The default strategy is enough for Point/Box - return ! detail::disjoint::disjoint_point_box(point, box); + return ! detail::disjoint::disjoint_point_box(point, box, + DisjointPointBoxStrategy()); } }; @@ -346,11 +355,13 @@ private: template inline bool apply(Point const& point, BoxPair const& box_pair) { + typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pb_strategy_type; + typedef typename boost::range_value::type single_type; // The default strategy is enough for Point/Box if (! m_intersection_found - && ! detail::disjoint::disjoint_point_box(point, box_pair.first) + && ! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pb_strategy_type()) && ! dispatch::disjoint::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy)) { m_intersection_found = true; @@ -392,6 +403,10 @@ public: item_visitor_type visitor(multi_geometry, strategy); + typedef overlaps_box_point + < + typename Strategy::disjoint_point_box_strategy_type + > overlaps_box_point_type; typedef overlaps_box_box_pair < typename Strategy::disjoint_box_box_strategy_type @@ -402,7 +417,7 @@ public: box1_type >::apply(multi_point, boxes, visitor, expand_box_point(), - overlaps_box_point(), + overlaps_box_point_type(), expand_box_box_pair(), overlaps_box_box_pair_type()); diff --git a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp index 2e6773d22..b4c402646 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/point_box.hpp @@ -5,8 +5,8 @@ // Copyright (c) 2009-2015 Mateusz Loskot, London, UK. // Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland -// This file was modified by Oracle on 2013-2017. -// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2013-2018. +// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle @@ -41,16 +41,11 @@ namespace detail { namespace disjoint /*! \brief Internal utility function to detect if point/box are disjoint */ -template -inline bool disjoint_point_box(Point const& point, Box const& box) +template +inline bool disjoint_point_box(Point const& point, Box const& box, Strategy const& ) { - typedef typename strategy::disjoint::services::default_strategy - < - Point, Box - >::type strategy_type; - // ! covered_by(point, box) - return ! strategy_type::apply(point, box); + return ! Strategy::apply(point, box); } diff --git a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp index 9e08ac6bf..d4d37725c 100644 --- a/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp +++ b/include/boost/geometry/algorithms/detail/disjoint/segment_box.hpp @@ -75,12 +75,14 @@ struct disjoint_segment_box_sphere_or_spheroid typename Segment, typename Box, typename AzimuthStrategy, typename NormalizeStrategy, + typename DisjointPointBoxStrategy, typename DisjointBoxBoxStrategy > static inline bool apply(Segment const& segment, Box const& box, AzimuthStrategy const& azimuth_strategy, NormalizeStrategy const& normalize_strategy, + DisjointPointBoxStrategy const& disjoint_point_box_strategy, DisjointBoxBoxStrategy const& disjoint_box_box_strategy) { typedef typename point_type::type segment_point; @@ -88,6 +90,7 @@ struct disjoint_segment_box_sphere_or_spheroid return apply(segment, box, vertex, azimuth_strategy, normalize_strategy, + disjoint_point_box_strategy, disjoint_box_box_strategy) != disjoint_info::intersect; } @@ -97,6 +100,7 @@ struct disjoint_segment_box_sphere_or_spheroid typename P, typename AzimuthStrategy, typename NormalizeStrategy, + typename DisjointPointBoxStrategy, typename DisjointBoxBoxStrategy > static inline disjoint_info apply(Segment const& segment, @@ -104,6 +108,7 @@ struct disjoint_segment_box_sphere_or_spheroid P& vertex, AzimuthStrategy const& azimuth_strategy, NormalizeStrategy const& , + DisjointPointBoxStrategy const& disjoint_point_box_strategy, DisjointBoxBoxStrategy const& disjoint_box_box_strategy) { assert_dimension_equal(); @@ -121,7 +126,8 @@ struct disjoint_segment_box_sphere_or_spheroid // Simplest cases first // Case 1: if box contains one of segment's endpoints then they are not disjoint - if (! disjoint_point_box(p0, box) || ! disjoint_point_box(p1, box)) + if ( ! disjoint_point_box(p0, box, disjoint_point_box_strategy) + || ! disjoint_point_box(p1, box, disjoint_point_box_strategy) ) { return disjoint_info::intersect; } diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp index b6d161438..3a8592e4a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turns.hpp @@ -512,6 +512,10 @@ public: intersection_strategy, robust_policy, turns, interrupt_policy); + typedef detail::section::get_section_box + < + typename IntersectionStrategy::expand_box_strategy_type + > get_section_box_type; typedef detail::section::overlaps_section_box < typename IntersectionStrategy::disjoint_box_box_strategy_type @@ -521,7 +525,7 @@ public: < box_type >::apply(sec1, sec2, visitor, - detail::section::get_section_box(), + get_section_box_type(), overlaps_section_box_type()); } }; diff --git a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp index 64b954d7a..a7a87a16a 100644 --- a/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/self_turn_points.hpp @@ -165,6 +165,10 @@ struct get_turns Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy > visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent); + typedef detail::section::get_section_box + < + typename IntersectionStrategy::expand_box_strategy_type + > get_section_box_type; typedef detail::section::overlaps_section_box < typename IntersectionStrategy::disjoint_box_box_strategy_type @@ -175,7 +179,7 @@ struct get_turns < box_type >::apply(sec, visitor, - detail::section::get_section_box(), + get_section_box_type(), overlaps_section_box_type()); return ! interrupt_policy.has_intersections; diff --git a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp index 64bb53bff..471dfe66e 100644 --- a/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/relate/multi_point_geometry.hpp @@ -170,6 +170,7 @@ struct multi_point_single_geometry typedef typename point_type::type point2_type; typedef model::box box2_type; typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type; + typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type; box2_type box2; geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy()); @@ -186,7 +187,7 @@ struct multi_point_single_geometry } // The default strategy is enough for Point/Box - if (detail::disjoint::disjoint_point_box(*it, box2)) + if (detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type())) { relate::set(result); } @@ -273,13 +274,15 @@ class multi_point_multi_geometry_ii_ib } }; + template struct overlaps_box_point { template static inline bool apply(Box const& box, Point const& point) { // The default strategy is enough for Point/Box - return ! detail::disjoint::disjoint_point_box(point, box); + return ! detail::disjoint::disjoint_point_box(point, box, + DisjointPointBoxStrategy()); } }; @@ -299,6 +302,7 @@ class multi_point_multi_geometry_ii_ib class item_visitor_type { typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type; + typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pp_strategy_type; typedef detail::relate::topology_check topology_check_type; public: @@ -316,7 +320,7 @@ class multi_point_multi_geometry_ii_ib inline bool apply(Point const& point, BoxPair const& box_pair) { // The default strategy is enough for Point/Box - if (! detail::disjoint::disjoint_point_box(point, box_pair.first)) + if (! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pp_strategy_type())) { typename boost::range_value::type const& single = range::at(m_multi_geometry, box_pair.second); @@ -379,6 +383,10 @@ public: { item_visitor_type visitor(multi_geometry, tc, result, strategy); + typedef overlaps_box_point + < + typename Strategy::disjoint_point_box_strategy_type + > overlaps_box_point_type; typedef overlaps_box_box_pair < typename Strategy::disjoint_box_box_strategy_type @@ -389,7 +397,7 @@ public: box1_type >::apply(multi_point, boxes, visitor, expand_box_point(), - overlaps_box_point(), + overlaps_box_point_type(), expand_box_box_pair(), overlaps_box_box_pair_type()); } diff --git a/include/boost/geometry/algorithms/detail/relate/topology_check.hpp b/include/boost/geometry/algorithms/detail/relate/topology_check.hpp index 3785f17b4..2dff68fe5 100644 --- a/include/boost/geometry/algorithms/detail/relate/topology_check.hpp +++ b/include/boost/geometry/algorithms/detail/relate/topology_check.hpp @@ -100,11 +100,10 @@ private: std::size_t count = boost::size(m_ls); m_has_interior = count > 0; // NOTE: Linestring with all points equal is treated as 1d linear ring - using detail::equals::equals_point_point; m_has_boundary = count > 1 - && ! equals_point_point(range::front(m_ls), - range::back(m_ls), - EqPPStrategy()); + && ! detail::equals::equals_point_point(range::front(m_ls), + range::back(m_ls), + EqPPStrategy()); m_is_initialized = true; } diff --git a/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp b/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp index 0d61f5444..e6342ff70 100644 --- a/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp +++ b/include/boost/geometry/algorithms/detail/sections/section_box_policies.hpp @@ -25,12 +25,14 @@ namespace boost { namespace geometry namespace detail { namespace section { +template struct get_section_box { template static inline void apply(Box& total, Section const& section) { - geometry::expand(total, section.bounding_box); + geometry::expand(total, section.bounding_box, + ExpandBoxStrategy()); } }; diff --git a/include/boost/geometry/algorithms/detail/sections/section_functions.hpp b/include/boost/geometry/algorithms/detail/sections/section_functions.hpp index d283784e2..33deb9474 100644 --- a/include/boost/geometry/algorithms/detail/sections/section_functions.hpp +++ b/include/boost/geometry/algorithms/detail/sections/section_functions.hpp @@ -2,8 +2,8 @@ // Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands. -// This file was modified by Oracle on 2015, 2017. -// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates. +// This file was modified by Oracle on 2015, 2017, 2018. +// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates. // Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -30,6 +30,8 @@ namespace boost { namespace geometry namespace detail { namespace section { +// TODO: This code is CS-specific, should be moved to strategies + template < std::size_t Dimension, @@ -68,7 +70,7 @@ struct preceding_check<0, Geometry, spherical_tag> calc_t const other_min = get(other_box); calc_t const other_max = get(other_box); - bool const pt_covered = strategy::within::covered_by_range + bool const pt_covered = strategy::within::detail::covered_by_range < Point, 0, spherical_tag >::apply(value, diff --git a/include/boost/geometry/strategies/cartesian/intersection.hpp b/include/boost/geometry/strategies/cartesian/intersection.hpp index ac357875f..fea98af1b 100644 --- a/include/boost/geometry/strategies/cartesian/intersection.hpp +++ b/include/boost/geometry/strategies/cartesian/intersection.hpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -170,6 +171,9 @@ struct cartesian_segments return disjoint_box_box_strategy_type(); } + typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type; + typedef expand::cartesian_box expand_box_strategy_type; + template struct segment_intersection_info { diff --git a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp index ddba9212d..d7f972758 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_poly_winding.hpp @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -116,6 +117,8 @@ public: return disjoint_box_box_strategy_type(); } + typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type; + // Typedefs and static methods to fulfill the concept typedef Point point_type; typedef PointOfSegment segment_point_type; diff --git a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp index 99279630e..49c80a5e7 100644 --- a/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/disjoint_segment_box.hpp @@ -35,6 +35,7 @@ #include #include #include +#include #include @@ -98,6 +99,7 @@ public: >::apply(segment, box, azimuth_geographic, strategy::normalize::spherical_point(), + strategy::covered_by::spherical_point_box(), strategy::disjoint::spherical_box_box()); } diff --git a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp index c59db0dd2..02168e649 100644 --- a/include/boost/geometry/strategies/geographic/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/geographic/distance_segment_box.hpp @@ -123,6 +123,7 @@ struct geographic_segment_box geographic_segment_box(), az_strategy, es_strategy, normalize::spherical_point(), + covered_by::spherical_point_box(), disjoint::spherical_box_box()); } diff --git a/include/boost/geometry/strategies/geographic/intersection.hpp b/include/boost/geometry/strategies/geographic/intersection.hpp index 1ff84ac5c..0bfa2f881 100644 --- a/include/boost/geometry/strategies/geographic/intersection.hpp +++ b/include/boost/geometry/strategies/geographic/intersection.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,9 @@ struct geographic_segments return disjoint_box_box_strategy_type(); } + typedef covered_by::spherical_point_box disjoint_point_box_strategy_type; + typedef expand::spherical_box expand_box_strategy_type; + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; template diff --git a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp index 945851b97..e7e449e22 100644 --- a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp @@ -75,6 +75,7 @@ struct segment_box_spherical >::apply(segment, box, azimuth_strategy, strategy::normalize::spherical_point(), + strategy::covered_by::spherical_point_box(), strategy::disjoint::spherical_box_box()); } }; diff --git a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp index 020c291ab..25adbeb46 100644 --- a/include/boost/geometry/strategies/spherical/distance_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/distance_segment_box.hpp @@ -16,6 +16,7 @@ #include #include #include +#include // spherical namespace boost { namespace geometry { @@ -36,6 +37,7 @@ struct generic_segment_box typename AzimuthStrategy, typename EnvelopeSegmentStrategy, typename NormalizePointStrategy, + typename DisjointPointBoxStrategy, typename DisjointBoxBoxStrategy > static inline ReturnType segment_below_of_box( @@ -49,6 +51,7 @@ struct generic_segment_box AzimuthStrategy const& az_strategy, EnvelopeSegmentStrategy const& es_strategy, NormalizePointStrategy const& np_strategy, + DisjointPointBoxStrategy const& dpb_strategy, DisjointBoxBoxStrategy const& dbb_strategy) { ReturnType result; @@ -75,7 +78,8 @@ struct generic_segment_box SegmentPoint p_max; disjoint_info_type disjoint_result = disjoint_sb:: - apply(seg, input_box, p_max, az_strategy, np_strategy, dbb_strategy); + apply(seg, input_box, p_max, + az_strategy, np_strategy, dpb_strategy, dbb_strategy); if (disjoint_result == disjoint_info_type::intersect) //intersect { @@ -233,6 +237,7 @@ struct spherical_segment_box spherical_segment_box(), az_strategy, es_strategy, normalize::spherical_point(), + covered_by::spherical_point_box(), disjoint::spherical_box_box()); } diff --git a/include/boost/geometry/strategies/spherical/intersection.hpp b/include/boost/geometry/strategies/spherical/intersection.hpp index be7558ad6..9142009fe 100644 --- a/include/boost/geometry/strategies/spherical/intersection.hpp +++ b/include/boost/geometry/strategies/spherical/intersection.hpp @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -188,6 +189,9 @@ struct ecef_segments return disjoint_box_box_strategy_type(); } + typedef covered_by::spherical_point_box disjoint_point_box_strategy_type; + typedef expand::spherical_box expand_box_strategy_type; + enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 }; // segment_intersection_info cannot outlive relate_ecef_segments diff --git a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp index 0cbe40df9..c283b5333 100644 --- a/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp +++ b/include/boost/geometry/strategies/spherical/point_in_poly_winding.hpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -153,6 +154,8 @@ public: return disjoint_box_box_strategy_type(); } + typedef covered_by::spherical_point_box disjoint_point_box_strategy_type; + spherical_winding_base() {} From 371767b248d7ed155ade3002893b0d5cf13a0196 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 16 Dec 2018 15:18:34 +0100 Subject: [PATCH 29/35] [get_turns] Remove unneeded comment. --- .../algorithms/detail/overlay/get_turn_info_la.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp index de39cd1e2..f8272794b 100644 --- a/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp +++ b/include/boost/geometry/algorithms/detail/overlay/get_turn_info_la.hpp @@ -738,14 +738,6 @@ struct get_turn_info_linear_areal } else { - // The code below should avoid using a side_calculator. - // Mainly because it is constructed with the wrong points. - // It should never be constructed other than pi,pj,pk / qi,qj,qk - // That side calculator might not be necessary here. - // Relevant sides can be passed to the method operations_and_equal - // (and that method can assign the operations, no need to return - // a pair, that is not done anywhere in all turns/operations) - // pi is the intersection point at qj or in the middle of q1 // so consider segments // 1. pi at qj: qi-qj-pj and qi-qj-qk From f6826c43b22d952e062431da8e8bfadadb4c6981 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Sun, 16 Dec 2018 15:41:39 +0100 Subject: [PATCH 30/35] [test][strategies] Rename envelope_segment test file. --- test/strategies/Jamfile.v2 | 6 +++--- .../{segment_envelope.cpp => envelope_segment.cpp} | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename test/strategies/{segment_envelope.cpp => envelope_segment.cpp} (100%) diff --git a/test/strategies/Jamfile.v2 b/test/strategies/Jamfile.v2 index 83026940a..10d281b38 100644 --- a/test/strategies/Jamfile.v2 +++ b/test/strategies/Jamfile.v2 @@ -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 2014, 2015, 2016, 2017. -# Modifications copyright (c) 2014-2017, Oracle and/or its affiliates. +# This file was modified by Oracle on 2014, 2015, 2016, 2017, 2018. +# Modifications copyright (c) 2014-2018, Oracle and/or its affiliates. # # Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle # Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle @@ -21,6 +21,7 @@ test-suite boost-geometry-strategies [ run crossings_multiply.cpp : : : : strategies_crossings_multiply ] [ run distance_default_result.cpp : : : : strategies_distance_default_result ] [ run douglas_peucker.cpp : : : : strategies_douglas_peucker ] + [ run envelope_segment.cpp : : : : strategies_envelope_segment ] [ run franklin.cpp : : : : strategies_franklin ] [ run haversine.cpp : : : : strategies_haversine ] [ run point_in_box.cpp : : : : strategies_point_in_box ] @@ -28,7 +29,6 @@ test-suite boost-geometry-strategies [ run projected_point_ax.cpp : : : : strategies_projected_point_ax ] [ run pythagoras.cpp : : : : strategies_pythagoras ] [ run pythagoras_point_box.cpp : : : : strategies_pythagoras_point_box ] - [ run segment_envelope.cpp : : : : strategies_segment_envelope ] [ run segment_intersection.cpp : : : : strategies_segment_intersection ] [ run segment_intersection_collinear.cpp : : : : strategies_segment_intersection_collinear ] [ run segment_intersection_geo.cpp : : : : strategies_segment_intersection_geo ] diff --git a/test/strategies/segment_envelope.cpp b/test/strategies/envelope_segment.cpp similarity index 100% rename from test/strategies/segment_envelope.cpp rename to test/strategies/envelope_segment.cpp From 9d5d5ae6e802de10f7d690644fd0768cbfa673a7 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 17 Dec 2018 01:38:48 +0100 Subject: [PATCH 31/35] [strategies] Fix warning, add missing comment at end of #endif. --- include/boost/geometry/strategies/cartesian/point_in_box.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/geometry/strategies/cartesian/point_in_box.hpp b/include/boost/geometry/strategies/cartesian/point_in_box.hpp index 36684a453..468e167c6 100644 --- a/include/boost/geometry/strategies/cartesian/point_in_box.hpp +++ b/include/boost/geometry/strategies/cartesian/point_in_box.hpp @@ -190,7 +190,7 @@ struct relate_point_box_loop }; } // namespace detail -#endif DOXYGEN_NO_DETAIL +#endif // DOXYGEN_NO_DETAIL struct cartesian_point_box { @@ -252,7 +252,7 @@ struct default_strategy } // namespace services -#endif DOXYGEN_NO_STRATEGY_SPECIALIZATIONS +#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS } // namespace within From cd863853c295f405b2b5f51b0faf2ec6d6ec732b Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 17 Dec 2018 01:45:32 +0100 Subject: [PATCH 32/35] [envelope] Add missing #include. --- include/boost/geometry/algorithms/detail/envelope/range.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/include/boost/geometry/algorithms/detail/envelope/range.hpp b/include/boost/geometry/algorithms/detail/envelope/range.hpp index e1fdb950d..2d33600d0 100644 --- a/include/boost/geometry/algorithms/detail/envelope/range.hpp +++ b/include/boost/geometry/algorithms/detail/envelope/range.hpp @@ -29,6 +29,7 @@ #include +#include #include #include #include From 92fb762a2c47eb80825371df9c91d6b0049ccdfe Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 17 Dec 2018 03:53:55 +0100 Subject: [PATCH 33/35] [strategy] Fix compilation errors in spherical strategies (missing includes and template keywords). --- .../spherical/disjoint_segment_box.hpp | 2 ++ .../strategies/spherical/envelope_point.hpp | 4 ++-- .../strategies/spherical/point_in_point.hpp | 18 ++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp index e7e449e22..9c6711dea 100644 --- a/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp +++ b/include/boost/geometry/strategies/spherical/disjoint_segment_box.hpp @@ -29,6 +29,8 @@ #include #include +// TODO: spherical_point_box currently defined in the same file as cartesian +#include #include #include #include diff --git a/include/boost/geometry/strategies/spherical/envelope_point.hpp b/include/boost/geometry/strategies/spherical/envelope_point.hpp index f09a39caa..8302d7e56 100644 --- a/include/boost/geometry/strategies/spherical/envelope_point.hpp +++ b/include/boost/geometry/strategies/spherical/envelope_point.hpp @@ -67,8 +67,8 @@ struct spherical_point < 2, dimension::value > per_corner; - per_corner::apply(normalized_point, mbr); - per_corner::apply(normalized_point, mbr); + per_corner::template apply(normalized_point, mbr); + per_corner::template apply(normalized_point, mbr); } }; diff --git a/include/boost/geometry/strategies/spherical/point_in_point.hpp b/include/boost/geometry/strategies/spherical/point_in_point.hpp index 1441ee650..372e9cfac 100644 --- a/include/boost/geometry/strategies/spherical/point_in_point.hpp +++ b/include/boost/geometry/strategies/spherical/point_in_point.hpp @@ -32,22 +32,20 @@ #include #include -#include -#include - -#include +#include +#include +#include #include -#include - -#include - -#include - +#include #include +#include #include +#include +#include + namespace boost { namespace geometry { From 247f657fe1bd63bc06419ca0ca1f4f314de15b76 Mon Sep 17 00:00:00 2001 From: Adam Wulkiewicz Date: Mon, 17 Dec 2018 14:04:10 +0100 Subject: [PATCH 34/35] [index] Fix compilation error in intersection_content(): wrong default strategy definition. --- .../index/detail/algorithms/intersection_content.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp index 3baa5cb4e..b8ef9e716 100644 --- a/include/boost/geometry/index/detail/algorithms/intersection_content.hpp +++ b/include/boost/geometry/index/detail/algorithms/intersection_content.hpp @@ -2,7 +2,7 @@ // // boxes union/intersection area/volume // -// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland. +// Copyright (c) 2011-2018 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,10 +24,10 @@ namespace boost { namespace geometry { namespace index { namespace detail { template inline typename default_content_result::type intersection_content(Box const& box1, Box const& box2) { - typedef strategy::disjoint::services::default_strategy + typedef typename strategy::disjoint::services::default_strategy < Box, Box - > strategy_type; + >::type strategy_type; bool const intersects = ! geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type()); From 4e9fac9eb76aed5aef084a9fa98bedf8744fdcbe Mon Sep 17 00:00:00 2001 From: Jared Jensen Date: Wed, 2 Jan 2019 23:10:44 +0000 Subject: [PATCH 35/35] Fix Segment View doc: Wrong output --- doc/src/examples/views/segment_view.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/examples/views/segment_view.cpp b/doc/src/examples/views/segment_view.cpp index 56f21d1f4..e02aab3c8 100644 --- a/doc/src/examples/views/segment_view.cpp +++ b/doc/src/examples/views/segment_view.cpp @@ -50,8 +50,8 @@ int main() /*` Output: [pre - (0, 0) (0, 4) (4, 4) (4, 0) (0, 0) -Area: 16 + (0, 0) (1, 1) +Length: 1.41421 ] */ //]