summaryrefslogtreecommitdiff
path: root/boost/geometry/algorithms/detail/envelope
diff options
context:
space:
mode:
Diffstat (limited to 'boost/geometry/algorithms/detail/envelope')
-rw-r--r--boost/geometry/algorithms/detail/envelope/box.hpp17
-rw-r--r--boost/geometry/algorithms/detail/envelope/implementation.hpp13
-rw-r--r--boost/geometry/algorithms/detail/envelope/interface.hpp124
-rw-r--r--boost/geometry/algorithms/detail/envelope/linear.hpp28
-rw-r--r--boost/geometry/algorithms/detail/envelope/multipoint.hpp13
-rw-r--r--boost/geometry/algorithms/detail/envelope/point.hpp15
-rw-r--r--boost/geometry/algorithms/detail/envelope/range.hpp44
-rw-r--r--boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp21
-rw-r--r--boost/geometry/algorithms/detail/envelope/segment.hpp209
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