diff options
Diffstat (limited to 'boost/geometry/algorithms/detail/envelope')
9 files changed, 299 insertions, 185 deletions
diff --git a/boost/geometry/algorithms/detail/envelope/box.hpp b/boost/geometry/algorithms/detail/envelope/box.hpp index 3790262948..795f51392e 100644 --- a/boost/geometry/algorithms/detail/envelope/box.hpp +++ b/boost/geometry/algorithms/detail/envelope/box.hpp @@ -4,9 +4,10 @@ // 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, 2016. +// Modifications copyright (c) 2015-2016, 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 // Distributed under the Boost Software License, Version 1.0. @@ -97,8 +98,10 @@ struct envelope_indexed_box_on_spheroid struct envelope_box { - template<typename BoxIn, typename BoxOut> - static inline void apply(BoxIn const& box_in, BoxOut& mbr) + template<typename BoxIn, typename BoxOut, typename Strategy> + static inline void apply(BoxIn const& box_in, + BoxOut& mbr, + Strategy const&) { envelope_indexed_box < @@ -115,8 +118,10 @@ struct envelope_box struct envelope_box_on_spheroid { - template <typename BoxIn, typename BoxOut> - static inline void apply(BoxIn const& box_in, BoxOut& mbr) + template <typename BoxIn, typename BoxOut, typename Strategy> + static inline void apply(BoxIn const& box_in, + BoxOut& mbr, + Strategy const&) { BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in); diff --git a/boost/geometry/algorithms/detail/envelope/implementation.hpp b/boost/geometry/algorithms/detail/envelope/implementation.hpp index c1dbf8e589..d549700791 100644 --- a/boost/geometry/algorithms/detail/envelope/implementation.hpp +++ b/boost/geometry/algorithms/detail/envelope/implementation.hpp @@ -4,9 +4,10 @@ // 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, 2016. +// Modifications copyright (c) 2015-2016, 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -45,8 +46,8 @@ namespace detail { namespace envelope struct envelope_polygon { - template <typename Polygon, typename Box> - static inline void apply(Polygon const& polygon, Box& mbr) + template <typename Polygon, typename Box, typename Strategy> + static inline void apply(Polygon const& polygon, Box& mbr, Strategy const& strategy) { typename ring_return_type<Polygon const>::type ext_ring = exterior_ring(polygon); @@ -57,12 +58,12 @@ struct envelope_polygon envelope_multi_range < envelope_range - >::apply(interior_rings(polygon), mbr); + >::apply(interior_rings(polygon), mbr, strategy); } else { // otherwise, consider only the exterior ring - envelope_range::apply(ext_ring, mbr); + envelope_range::apply(ext_ring, mbr, strategy); } } }; diff --git a/boost/geometry/algorithms/detail/envelope/interface.hpp b/boost/geometry/algorithms/detail/envelope/interface.hpp index befe4e42db..8e9c35b395 100644 --- a/boost/geometry/algorithms/detail/envelope/interface.hpp +++ b/boost/geometry/algorithms/detail/envelope/interface.hpp @@ -4,10 +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. -// Modifications copyright (c) 2015, Oracle and/or its affiliates. +// 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. @@ -27,54 +29,124 @@ #include <boost/geometry/algorithms/dispatch/envelope.hpp> +#include <boost/geometry/strategies/default_strategy.hpp> +#include <boost/geometry/strategies/envelope.hpp> +#include <boost/geometry/strategies/cartesian/envelope_segment.hpp> +#include <boost/geometry/strategies/spherical/envelope_segment.hpp> +#include <boost/geometry/strategies/geographic/envelope_segment.hpp> namespace boost { namespace geometry { -namespace resolve_variant +namespace resolve_strategy { template <typename Geometry> struct envelope { + template <typename Box, typename Strategy> + static inline void apply(Geometry const& geometry, + Box& box, + Strategy const& strategy) + { + dispatch::envelope<Geometry>::apply(geometry, box, strategy); + } + template <typename Box> - static inline void apply(Geometry const& geometry, Box& box) + static inline void apply(Geometry const& geometry, + Box& box, + default_strategy) + { + typedef typename point_type<Geometry>::type point_type; + typedef typename coordinate_type<point_type>::type coordinate_type; + + typedef typename strategy::envelope::services::default_strategy + < + typename cs_tag<point_type>::type, + coordinate_type + >::type strategy_type; + + dispatch::envelope<Geometry>::apply(geometry, box, strategy_type()); + } +}; + +} // namespace resolve_strategy + +namespace resolve_variant +{ + +template <typename Geometry> +struct envelope +{ + template <typename Box, typename Strategy> + static inline void apply(Geometry const& geometry, + Box& box, + Strategy const& strategy) { concepts::check<Geometry const>(); concepts::check<Box>(); - dispatch::envelope<Geometry>::apply(geometry, box); + resolve_strategy::envelope<Geometry>::apply(geometry, box, strategy); } }; + template <BOOST_VARIANT_ENUM_PARAMS(typename T)> struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > { - template <typename Box> + template <typename Box, typename Strategy> struct visitor: boost::static_visitor<void> { Box& m_box; + Strategy const& m_strategy; - visitor(Box& box): m_box(box) {} + visitor(Box& box, Strategy const& strategy) + : m_box(box) + , m_strategy(strategy) + {} template <typename Geometry> void operator()(Geometry const& geometry) const { - envelope<Geometry>::apply(geometry, m_box); + envelope<Geometry>::apply(geometry, m_box, m_strategy); } }; - template <typename Box> + template <typename Box, typename Strategy> static inline void apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, - Box& box) + Box& box, + Strategy const& strategy) { - boost::apply_visitor(visitor<Box>(box), geometry); + boost::apply_visitor(visitor<Box, Strategy>(box, strategy), geometry); } }; } // namespace resolve_variant +/*! +\brief \brief_calc{envelope (with strategy)} +\ingroup envelope +\details \details_calc{envelope,\det_envelope}. +\tparam Geometry \tparam_geometry +\tparam Box \tparam_box +\tparam Strategy \tparam_strategy{Envelope} +\param geometry \param_geometry +\param mbr \param_box \param_set{envelope} +\param strategy \param_strategy{envelope} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/envelope.qbk]} +\qbk{ +[heading Example] +[envelope] [envelope_output] +} +*/ +template<typename Geometry, typename Box, typename Strategy> +inline void envelope(Geometry const& geometry, Box& mbr, Strategy const& strategy) +{ + resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy); +} /*! \brief \brief_calc{envelope} @@ -94,7 +166,7 @@ struct envelope<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > template<typename Geometry, typename Box> inline void envelope(Geometry const& geometry, Box& mbr) { - resolve_variant::envelope<Geometry>::apply(geometry, mbr); + resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy()); } @@ -104,6 +176,32 @@ inline void envelope(Geometry const& geometry, Box& mbr) \details \details_calc{return_envelope,\det_envelope}. \details_return{envelope} \tparam Box \tparam_box \tparam Geometry \tparam_geometry +\tparam Strategy \tparam_strategy{Envelope} +\param geometry \param_geometry +\param strategy \param_strategy{envelope} +\return \return_calc{envelope} + +\qbk{distinguish,with strategy} +\qbk{[include reference/algorithms/envelope.qbk]} +\qbk{ +[heading Example] +[return_envelope] [return_envelope_output] +} +*/ +template<typename Box, typename Geometry, typename Strategy> +inline Box return_envelope(Geometry const& geometry, Strategy const& strategy) +{ + Box mbr; + resolve_variant::envelope<Geometry>::apply(geometry, mbr, strategy); + return mbr; +} + +/*! +\brief \brief_calc{envelope} +\ingroup envelope +\details \details_calc{return_envelope,\det_envelope}. \details_return{envelope} +\tparam Box \tparam_box +\tparam Geometry \tparam_geometry \param geometry \param_geometry \return \return_calc{envelope} @@ -117,7 +215,7 @@ template<typename Box, typename Geometry> inline Box return_envelope(Geometry const& geometry) { Box mbr; - resolve_variant::envelope<Geometry>::apply(geometry, mbr); + resolve_variant::envelope<Geometry>::apply(geometry, mbr, default_strategy()); return mbr; } diff --git a/boost/geometry/algorithms/detail/envelope/linear.hpp b/boost/geometry/algorithms/detail/envelope/linear.hpp index 49c3cf3135..09d8a76da5 100644 --- a/boost/geometry/algorithms/detail/envelope/linear.hpp +++ b/boost/geometry/algorithms/detail/envelope/linear.hpp @@ -4,9 +4,10 @@ // 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, 2016. +// Modifications copyright (c) 2015-2016, 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 // Distributed under the Boost Software License, Version 1.0. @@ -36,12 +37,15 @@ namespace detail { namespace envelope struct envelope_linestring_on_spheroid { - template <typename Linestring, typename Box> - static inline void apply(Linestring const& linestring, Box& mbr) + template <typename Linestring, typename Box, typename Strategy> + static inline void apply(Linestring const& linestring, + Box& mbr, + Strategy const& strategy) { envelope_range::apply(geometry::segments_begin(linestring), geometry::segments_end(linestring), - mbr); + mbr, + strategy); } }; @@ -65,6 +69,11 @@ struct envelope<Linestring, linestring_tag, spherical_equatorial_tag> : detail::envelope::envelope_linestring_on_spheroid {}; +template <typename Linestring> +struct envelope<Linestring, linestring_tag, geographic_tag> + : detail::envelope::envelope_linestring_on_spheroid +{}; + template <typename MultiLinestring, typename CS_Tag> struct envelope @@ -86,6 +95,15 @@ struct envelope > {}; +template <typename MultiLinestring> +struct envelope + < + MultiLinestring, multi_linestring_tag, geographic_tag + > : detail::envelope::envelope_multi_range_on_spheroid + < + detail::envelope::envelope_linestring_on_spheroid + > +{}; } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH diff --git a/boost/geometry/algorithms/detail/envelope/multipoint.hpp b/boost/geometry/algorithms/detail/envelope/multipoint.hpp index 210debfdba..efee4701c9 100644 --- a/boost/geometry/algorithms/detail/envelope/multipoint.hpp +++ b/boost/geometry/algorithms/detail/envelope/multipoint.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2016, 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 // Distributed under the Boost Software License, Version 1.0. @@ -226,8 +227,8 @@ private: } public: - template <typename MultiPoint, typename Box> - static inline void apply(MultiPoint const& multipoint, Box& mbr) + template <typename MultiPoint, typename Box, typename Strategy> + static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy) { typedef typename point_type<MultiPoint>::type point_type; typedef typename coordinate_type<MultiPoint>::type coordinate_type; @@ -255,7 +256,7 @@ public: return dispatch::envelope < typename boost::range_value<MultiPoint>::type - >::apply(range::front(multipoint), mbr); + >::apply(range::front(multipoint), mbr, strategy); } // analyze the points and put the non-pole ones in the @@ -329,7 +330,7 @@ public: // compute envelope for higher coordinates iterator_type it = boost::begin(multipoint); - envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr); + envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy); for (++it; it != boost::end(multipoint); ++it) { @@ -338,7 +339,7 @@ public: strategy::compare::default_strategy, strategy::compare::default_strategy, 2, dimension<Box>::value - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); } } }; diff --git a/boost/geometry/algorithms/detail/envelope/point.hpp b/boost/geometry/algorithms/detail/envelope/point.hpp index e914e7e8a0..ee0559bf5f 100644 --- a/boost/geometry/algorithms/detail/envelope/point.hpp +++ b/boost/geometry/algorithms/detail/envelope/point.hpp @@ -4,9 +4,10 @@ // 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, 2016. +// Modifications copyright (c) 2015-2016, 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 // Distributed under the Boost Software License, Version 1.0. @@ -58,8 +59,8 @@ struct envelope_one_point >::apply(point, box_corner); } - template <typename Point, typename Box> - static inline void apply(Point const& point, Box& mbr) + template <typename Point, typename Box, typename Strategy> + static inline void apply(Point const& point, Box& mbr, Strategy const&) { apply<min_corner>(point, mbr); apply<max_corner>(point, mbr); @@ -69,8 +70,8 @@ struct envelope_one_point struct envelope_point_on_spheroid { - template<typename Point, typename Box> - static inline void apply(Point const& point, Box& mbr) + template<typename Point, typename Box, typename Strategy> + static inline void apply(Point const& point, Box& mbr, Strategy const& strategy) { Point normalized_point = detail::return_normalized<Point>(point); @@ -88,7 +89,7 @@ struct envelope_point_on_spheroid envelope_one_point < 2, dimension<Point>::value - >::apply(normalized_point, mbr); + >::apply(normalized_point, mbr, strategy); } }; diff --git a/boost/geometry/algorithms/detail/envelope/range.hpp b/boost/geometry/algorithms/detail/envelope/range.hpp index 63b518114b..b5591f61ab 100644 --- a/boost/geometry/algorithms/detail/envelope/range.hpp +++ b/boost/geometry/algorithms/detail/envelope/range.hpp @@ -4,9 +4,10 @@ // 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, 2016. +// Modifications copyright (c) 2015-2016, 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 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library @@ -51,8 +52,11 @@ namespace detail { namespace envelope // implementation for simple ranges struct envelope_range { - template <typename Iterator, typename Box> - static inline void apply(Iterator first, Iterator last, Box& mbr) + template <typename Iterator, typename Box, typename Strategy> + static inline void apply(Iterator first, + Iterator last, + Box& mbr, + Strategy const& strategy) { typedef typename std::iterator_traits<Iterator>::value_type value_type; @@ -63,20 +67,20 @@ struct envelope_range if (it != last) { // initialize box with first element in range - dispatch::envelope<value_type>::apply(*it, mbr); + dispatch::envelope<value_type>::apply(*it, mbr, strategy); // consider now the remaining elements in the range (if any) for (++it; it != last; ++it) { - dispatch::expand<Box, value_type>::apply(mbr, *it); + dispatch::expand<Box, value_type>::apply(mbr, *it, strategy); } } } - template <typename Range, typename Box> - static inline void apply(Range const& range, Box& mbr) + template <typename Range, typename Box, typename Strategy> + static inline void apply(Range const& range, Box& mbr, Strategy const& strategy) { - return apply(boost::begin(range), boost::end(range), mbr); + return apply(boost::begin(range), boost::end(range), mbr, strategy); } }; @@ -85,8 +89,10 @@ struct envelope_range template <typename EnvelopePolicy> struct envelope_multi_range { - template <typename MultiRange, typename Box> - static inline void apply(MultiRange const& multirange, Box& mbr) + template <typename MultiRange, typename Box, typename Strategy> + static inline void apply(MultiRange const& multirange, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_iterator < @@ -103,14 +109,14 @@ struct envelope_multi_range if (initialized) { Box helper_mbr; - EnvelopePolicy::apply(*it, helper_mbr); + EnvelopePolicy::apply(*it, helper_mbr, strategy); - dispatch::expand<Box, Box>::apply(mbr, helper_mbr); + dispatch::expand<Box, Box>::apply(mbr, helper_mbr, strategy); } else { // compute the initial envelope - EnvelopePolicy::apply(*it, mbr); + EnvelopePolicy::apply(*it, mbr, strategy); initialized = true; } } @@ -129,8 +135,10 @@ struct envelope_multi_range template <typename EnvelopePolicy> struct envelope_multi_range_on_spheroid { - template <typename MultiRange, typename Box> - static inline void apply(MultiRange const& multirange, Box& mbr) + template <typename MultiRange, typename Box, typename Strategy> + static inline void apply(MultiRange const& multirange, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_iterator < @@ -147,7 +155,7 @@ struct envelope_multi_range_on_spheroid if (! geometry::is_empty(*it)) { Box helper_box; - EnvelopePolicy::apply(*it, helper_box); + EnvelopePolicy::apply(*it, helper_box, strategy); boxes.push_back(helper_box); } } @@ -159,7 +167,7 @@ struct envelope_multi_range_on_spheroid // and the MBR is simply initialized if (! boxes.empty()) { - envelope_range_of_boxes::apply(boxes, mbr); + envelope_range_of_boxes::apply(boxes, mbr, strategy); } else { diff --git a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp index 64bdb9b9cb..f61fc422de 100644 --- a/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp +++ b/boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp @@ -1,7 +1,8 @@ // Boost.Geometry (aka GGL, Generic Geometry Library) -// Copyright (c) 2015, Oracle and/or its affiliates. +// Copyright (c) 2015-2016, 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 // Distributed under the Boost Software License, Version 1.0. @@ -149,8 +150,10 @@ struct envelope_range_of_longitudes template <std::size_t Dimension, std::size_t DimensionCount> struct envelope_range_of_boxes_by_expansion { - template <typename RangeOfBoxes, typename Box> - static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) + template <typename RangeOfBoxes, typename Box, typename Strategy> + static inline void apply(RangeOfBoxes const& range_of_boxes, + Box& mbr, + Strategy const& strategy) { typedef typename boost::range_value<RangeOfBoxes>::type box_type; @@ -196,7 +199,7 @@ struct envelope_range_of_boxes_by_expansion min_corner, Dimension, DimensionCount - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); detail::expand::indexed_loop < @@ -205,7 +208,7 @@ struct envelope_range_of_boxes_by_expansion max_corner, Dimension, DimensionCount - >::apply(mbr, *it); + >::apply(mbr, *it, strategy); } } @@ -225,8 +228,10 @@ struct envelope_range_of_boxes } }; - template <typename RangeOfBoxes, typename Box> - static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr) + template <typename RangeOfBoxes, typename Box, typename Strategy> + static inline void apply(RangeOfBoxes const& range_of_boxes, + Box& mbr, + Strategy const& strategy) { // boxes in the range are assumed to be normalized already @@ -313,7 +318,7 @@ struct envelope_range_of_boxes envelope_range_of_boxes_by_expansion < 2, dimension<Box>::value - >::apply(range_of_boxes, mbr); + >::apply(range_of_boxes, mbr, strategy); } }; diff --git a/boost/geometry/algorithms/detail/envelope/segment.hpp b/boost/geometry/algorithms/detail/envelope/segment.hpp index 6186e72a3a..7631e84883 100644 --- a/boost/geometry/algorithms/detail/envelope/segment.hpp +++ b/boost/geometry/algorithms/detail/envelope/segment.hpp @@ -4,9 +4,10 @@ // 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-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 @@ -26,6 +27,7 @@ #include <boost/geometry/core/coordinate_system.hpp> #include <boost/geometry/core/coordinate_type.hpp> #include <boost/geometry/core/cs.hpp> +#include <boost/geometry/core/srs.hpp> #include <boost/geometry/core/point_type.hpp> #include <boost/geometry/core/radian_access.hpp> #include <boost/geometry/core/tags.hpp> @@ -34,10 +36,9 @@ #include <boost/geometry/geometries/helper_geometry.hpp> -#include <boost/geometry/strategies/compare.hpp> +#include <boost/geometry/formulas/vertex_latitude.hpp> #include <boost/geometry/algorithms/detail/assign_indexed_point.hpp> -#include <boost/geometry/algorithms/detail/normalize.hpp> #include <boost/geometry/algorithms/detail/envelope/point.hpp> #include <boost/geometry/algorithms/detail/envelope/transform_units.hpp> @@ -46,7 +47,6 @@ #include <boost/geometry/algorithms/dispatch/envelope.hpp> - namespace boost { namespace geometry { @@ -54,63 +54,36 @@ namespace boost { namespace geometry namespace detail { namespace envelope { - -template <std::size_t Dimension, std::size_t DimensionCount> -struct envelope_one_segment +template <typename CalculationType, typename CS_Tag> +struct envelope_segment_call_vertex_latitude { - template<typename Point, typename Box> - static inline void apply(Point const& p1, Point const& p2, Box& mbr) + template <typename T1, typename T2, typename Strategy> + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& ) { - envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr); - detail::expand::point_loop - < - strategy::compare::default_strategy, - strategy::compare::default_strategy, - Dimension, - DimensionCount - >::apply(mbr, p2); + return geometry::formula::vertex_latitude<CalculationType, CS_Tag> + ::apply(lat1, alp1); } }; - -// Computes the MBR of a segment given by (lon1, lat1) and (lon2, -// lat2), and with azimuths a1 and a2 at the two endpoints of the -// segment. -// It is assumed that the spherical coordinates of the segment are -// normalized and in radians. -// The longitudes and latitudes of the endpoints are overridden by -// those of the box. -class compute_mbr_of_segment +template <typename CalculationType> +struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag> { -private: - // computes the azimuths of the segment with endpoints (lon1, lat1) - // and (lon2, lat2) - // radians - template <typename CalculationType> - static inline void azimuths(CalculationType const& lon1, - CalculationType const& lat1, - CalculationType const& lon2, - CalculationType const& lat2, - CalculationType& a1, - CalculationType& a2) + template <typename T1, typename T2, typename Strategy> + static inline CalculationType apply(T1 const& lat1, + T2 const& alp1, + Strategy const& strategy) { - BOOST_GEOMETRY_ASSERT(lon1 <= lon2); - - CalculationType dlon = lon2 - lon1; - CalculationType sin_dlon = sin(dlon); - CalculationType cos_dlon = cos(dlon); - CalculationType cos_lat1 = cos(lat1); - CalculationType cos_lat2 = cos(lat2); - CalculationType sin_lat1 = sin(lat1); - CalculationType sin_lat2 = sin(lat2); - - a1 = atan2(sin_dlon * cos_lat2, - cos_lat1 * sin_lat2 - sin_lat1 * cos_lat2 * cos_dlon); - - a2 = atan2(-sin_dlon * cos_lat1, - cos_lat2 * sin_lat1 - sin_lat2 * cos_lat1 * cos_dlon); - a2 += math::pi<CalculationType>(); + return geometry::formula::vertex_latitude<CalculationType, geographic_tag> + ::apply(lat1, alp1, strategy.model()); } +}; + +template <typename CS_Tag> +class envelope_segment_impl +{ +private: // degrees or radians template <typename CalculationType> @@ -134,8 +107,8 @@ private: static CalculationType const pi_half = math::half_pi<CalculationType>(); return (a1 < a2) - ? (a1 < pi_half && pi_half < a2) - : (a1 > pi_half && pi_half > a2); + ? (a1 < pi_half && pi_half < a2) + : (a1 > pi_half && pi_half > a2); } // radians or degrees @@ -151,21 +124,13 @@ private: return math::abs(lon1 - lon2) > constants::half_period(); // > pi } - // radians - template <typename CalculationType> - static inline CalculationType max_latitude(CalculationType const& azimuth, - CalculationType const& latitude) - { - // azimuth and latitude are assumed to be in radians - return acos( math::abs(cos(latitude) * sin(azimuth)) ); - } - // degrees or radians - template <typename Units, typename CalculationType> + template <typename Units, typename CalculationType, typename Strategy> static inline void compute_box_corners(CalculationType& lon1, CalculationType& lat1, CalculationType& lon2, - CalculationType& lat2) + CalculationType& lat2, + Strategy const& strategy) { // coordinates are assumed to be in radians BOOST_GEOMETRY_ASSERT(lon1 <= lon2); @@ -175,13 +140,14 @@ private: CalculationType lon2_rad = math::as_radian<Units>(lon2); CalculationType lat2_rad = math::as_radian<Units>(lat2); - CalculationType a1 = 0, a2 = 0; - azimuths(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2); + CalculationType a1, a2; + strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, a1, a2); if (lat1 > lat2) { std::swap(lat1, lat2); std::swap(lat1_rad, lat2_rad); + std::swap(a1, a2); } if (math::equals(a1, a2)) @@ -192,12 +158,16 @@ private: if (contains_pi_half(a1, a2)) { + CalculationType p_max = envelope_segment_call_vertex_latitude + <CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy); + CalculationType const mid_lat = lat1 + lat2; if (mid_lat < 0) { // update using min latitude - CalculationType const lat_min_rad = -max_latitude(a1, lat1_rad); - CalculationType const lat_min = math::from_radian<Units>(lat_min_rad); + CalculationType const lat_min_rad = -p_max; + CalculationType const lat_min + = math::from_radian<Units>(lat_min_rad); if (lat1 > lat_min) { @@ -207,8 +177,9 @@ private: else if (mid_lat > 0) { // update using max latitude - CalculationType const lat_max_rad = max_latitude(a1, lat1_rad); - CalculationType const lat_max = math::from_radian<Units>(lat_max_rad); + CalculationType const lat_max_rad = p_max; + CalculationType const lat_max + = math::from_radian<Units>(lat_max_rad); if (lat2 < lat_max) { @@ -218,11 +189,12 @@ private: } } - template <typename Units, typename CalculationType> + template <typename Units, typename CalculationType, typename Strategy> static inline void apply(CalculationType& lon1, CalculationType& lat1, CalculationType& lon2, - CalculationType& lat2) + CalculationType& lat2, + Strategy const& strategy) { typedef math::detail::constants_on_spheroid < @@ -278,16 +250,22 @@ private: swap(lon1, lat1, lon2, lat2); } - compute_box_corners<Units>(lon1, lat1, lon2, lat2); + compute_box_corners<Units>(lon1, lat1, lon2, lat2, strategy); } public: - template <typename Units, typename CalculationType, typename Box> + template < + typename Units, + typename CalculationType, + typename Box, + typename Strategy + > static inline void apply(CalculationType lon1, CalculationType lat1, CalculationType lon2, CalculationType lat2, - Box& mbr) + Box& mbr, + Strategy const& strategy) { typedef typename coordinate_type<Box>::type box_coordinate_type; @@ -298,7 +276,7 @@ public: helper_box_type radian_mbr; - apply<Units>(lon1, lat1, lon2, lat2); + apply<Units>(lon1, lat1, lon2, lat2, strategy); geometry::set < @@ -324,29 +302,42 @@ public: } }; +template <std::size_t Dimension, std::size_t DimensionCount> +struct envelope_one_segment +{ + template<typename Point, typename Box, typename Strategy> + static inline void apply(Point const& p1, + Point const& p2, + Box& mbr, + Strategy const& strategy) + { + envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr, strategy); + detail::expand::point_loop + < + strategy::compare::default_strategy, + strategy::compare::default_strategy, + Dimension, + DimensionCount + >::apply(mbr, p2, strategy); + } +}; + template <std::size_t DimensionCount> -struct envelope_segment_on_sphere +struct envelope_segment { - template <typename Point, typename Box> - static inline void apply(Point const& p1, Point const& p2, Box& mbr) + template <typename Point, typename Box, typename Strategy> + static inline void apply(Point const& p1, + Point const& p2, + Box& mbr, + Strategy const& strategy) { // first compute the envelope range for the first two coordinates - Point p1_normalized = detail::return_normalized<Point>(p1); - Point p2_normalized = detail::return_normalized<Point>(p2); - - typedef typename coordinate_system<Point>::type::units units_type; - - compute_mbr_of_segment::template apply<units_type>( - geometry::get<0>(p1_normalized), - geometry::get<1>(p1_normalized), - geometry::get<0>(p2_normalized), - geometry::get<1>(p2_normalized), - mbr); + 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); + envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy); } template <typename Segment, typename Box> @@ -359,21 +350,6 @@ struct envelope_segment_on_sphere } }; - - -template <std::size_t DimensionCount, typename CS_Tag> -struct envelope_segment - : envelope_one_segment<0, DimensionCount> -{}; - - -template <std::size_t DimensionCount> -struct envelope_segment<DimensionCount, spherical_equatorial_tag> - : envelope_segment_on_sphere<DimensionCount> -{}; - - - }} // namespace detail::envelope #endif // DOXYGEN_NO_DETAIL @@ -383,23 +359,24 @@ namespace dispatch { -template <typename Segment, typename CS_Tag> -struct envelope<Segment, segment_tag, CS_Tag> +template <typename Segment> +struct envelope<Segment, segment_tag> { - template <typename Box> - static inline void apply(Segment const& segment, Box& mbr) + template <typename Box, typename Strategy> + static inline void apply(Segment const& segment, + Box& mbr, + Strategy const& strategy) { typename point_type<Segment>::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<Segment>::value, CS_Tag - >::apply(p[0], p[1], mbr); + dimension<Segment>::value + >::apply(p[0], p[1], mbr, strategy); } }; - } // namespace dispatch #endif // DOXYGEN_NO_DISPATCH |