updated boost on windows
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
// Boost.Geometry
|
||||
|
||||
// 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
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_HPP
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/segment_iterator.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
struct envelope_polygon
|
||||
{
|
||||
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);
|
||||
|
||||
if (geometry::is_empty(ext_ring))
|
||||
{
|
||||
// if the exterior ring is empty, consider the interior rings
|
||||
envelope_multi_range
|
||||
<
|
||||
envelope_range
|
||||
>::apply(interior_rings(polygon), mbr, strategy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, consider only the exterior ring
|
||||
envelope_range::apply(ext_ring, mbr, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct envelope<Ring, ring_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
template <typename Polygon>
|
||||
struct envelope<Polygon, polygon_tag>
|
||||
: detail::envelope::envelope_polygon
|
||||
{};
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct envelope<MultiPolygon, multi_polygon_tag>
|
||||
: detail::envelope::envelope_multi_range
|
||||
<
|
||||
detail::envelope::envelope_polygon
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_AREAL_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-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,151 +18,32 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
|
||||
#include <boost/geometry/strategies/spherical/envelope_box.hpp>
|
||||
|
||||
|
||||
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 <typename BoxIn, typename BoxOut>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
|
||||
{
|
||||
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
|
||||
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
|
||||
|
||||
detail::conversion::point_to_point
|
||||
<
|
||||
detail::indexed_point_view<BoxIn const, Index>,
|
||||
detail::indexed_point_view<BoxOut, Index>,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(box_in_corner, mbr_corner);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
std::size_t Index,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct envelope_indexed_box_on_spheroid
|
||||
{
|
||||
template <typename BoxIn, typename BoxOut>
|
||||
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<BoxIn const, Index> box_in_corner(box_in);
|
||||
detail::indexed_point_view<BoxOut, Index> 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<BoxIn const, Index>,
|
||||
detail::indexed_point_view<BoxOut, Index>,
|
||||
2,
|
||||
DimensionCount
|
||||
>::apply(box_in_corner, mbr_corner);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_box
|
||||
{
|
||||
template<typename BoxIn, typename BoxOut, typename Strategy>
|
||||
static inline void apply(BoxIn const& box_in,
|
||||
BoxOut& mbr,
|
||||
Strategy const&)
|
||||
{
|
||||
envelope_indexed_box
|
||||
<
|
||||
min_corner, 0, dimension<BoxIn>::value
|
||||
>::apply(box_in, mbr);
|
||||
|
||||
envelope_indexed_box
|
||||
<
|
||||
max_corner, 0, dimension<BoxIn>::value
|
||||
>::apply(box_in, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_box_on_spheroid
|
||||
{
|
||||
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);
|
||||
|
||||
envelope_indexed_box_on_spheroid
|
||||
<
|
||||
min_corner, dimension<BoxIn>::value
|
||||
>::apply(box_in_normalized, mbr);
|
||||
|
||||
envelope_indexed_box_on_spheroid
|
||||
<
|
||||
max_corner, dimension<BoxIn>::value
|
||||
>::apply(box_in_normalized, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Box, typename CS_Tag>
|
||||
struct envelope<Box, box_tag, CS_Tag>
|
||||
: detail::envelope::envelope_box
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box>
|
||||
struct envelope<Box, box_tag, spherical_equatorial_tag>
|
||||
: detail::envelope::envelope_box_on_spheroid
|
||||
{};
|
||||
|
||||
|
||||
template <typename Box>
|
||||
struct envelope<Box, box_tag, geographic_tag>
|
||||
: detail::envelope::envelope_box_on_spheroid
|
||||
{};
|
||||
struct envelope<Box, box_tag>
|
||||
{
|
||||
template<typename BoxIn, typename BoxOut, typename Strategy>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& mbr, Strategy const& )
|
||||
{
|
||||
Strategy::apply(box_in, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/areal.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
|
||||
@@ -35,73 +36,4 @@
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_polygon
|
||||
{
|
||||
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);
|
||||
|
||||
if (geometry::is_empty(ext_ring))
|
||||
{
|
||||
// if the exterior ring is empty, consider the interior rings
|
||||
envelope_multi_range
|
||||
<
|
||||
envelope_range
|
||||
>::apply(interior_rings(polygon), mbr, strategy);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, consider only the exterior ring
|
||||
envelope_range::apply(ext_ring, mbr, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Ring>
|
||||
struct envelope<Ring, ring_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
|
||||
template <typename Polygon>
|
||||
struct envelope<Polygon, polygon_tag>
|
||||
: detail::envelope::envelope_polygon
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct envelope<MultiPolygon, multi_polygon_tag>
|
||||
: detail::envelope::envelope_multi_range
|
||||
<
|
||||
detail::envelope::envelope_polygon
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_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 <boost/variant/apply_visitor.hpp>
|
||||
#include <boost/variant/static_visitor.hpp>
|
||||
#include <boost/variant/variant_fwd.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.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>
|
||||
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -57,13 +62,15 @@ struct envelope
|
||||
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
|
||||
typename tag<Geometry>::type,
|
||||
typename cs_tag<Geometry>::type,
|
||||
typename select_most_precise
|
||||
<
|
||||
typename coordinate_type<Geometry>::type,
|
||||
typename coordinate_type<Box>::type
|
||||
>::type
|
||||
>::type strategy_type;
|
||||
|
||||
dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());
|
||||
|
||||
@@ -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,93 +18,40 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/segment_iterator.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/cartesian/envelope.hpp>
|
||||
#include <boost/geometry/strategies/spherical/envelope.hpp>
|
||||
#include <boost/geometry/strategies/geographic/envelope.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_linestring_on_spheroid
|
||||
{
|
||||
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,
|
||||
strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Linestring, typename CS_Tag>
|
||||
struct envelope<Linestring, linestring_tag, CS_Tag>
|
||||
template <typename Linestring>
|
||||
struct envelope<Linestring, linestring_tag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
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
|
||||
<
|
||||
MultiLinestring, multi_linestring_tag, CS_Tag
|
||||
> : detail::envelope::envelope_multi_range
|
||||
template <typename MultiLinestring>
|
||||
struct envelope<MultiLinestring, multi_linestring_tag>
|
||||
: detail::envelope::envelope_multi_range
|
||||
<
|
||||
detail::envelope::envelope_range
|
||||
>
|
||||
{};
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct envelope
|
||||
<
|
||||
MultiLinestring, multi_linestring_tag, spherical_equatorial_tag
|
||||
> : detail::envelope::envelope_multi_range_on_spheroid
|
||||
<
|
||||
detail::envelope::envelope_linestring_on_spheroid
|
||||
>
|
||||
{};
|
||||
|
||||
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
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015-2016, 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
|
||||
// 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
|
||||
@@ -12,363 +13,32 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/algorithm/minmax_element.hpp>
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/helper_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/point.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/cartesian/envelope_multipoint.hpp>
|
||||
#include <boost/geometry/strategies/spherical/envelope_multipoint.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
class envelope_multipoint_on_spheroid
|
||||
{
|
||||
private:
|
||||
template <std::size_t Dim>
|
||||
struct coordinate_less
|
||||
{
|
||||
template <typename Point>
|
||||
inline bool operator()(Point const& point1, Point const& point2) const
|
||||
{
|
||||
return math::smaller(geometry::get<Dim>(point1),
|
||||
geometry::get<Dim>(point2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Constants, typename MultiPoint, typename OutputIterator>
|
||||
static inline void analyze_point_coordinates(MultiPoint const& multipoint,
|
||||
bool& has_south_pole,
|
||||
bool& has_north_pole,
|
||||
OutputIterator oit)
|
||||
{
|
||||
typedef typename boost::range_value<MultiPoint>::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<point_type>(*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 <typename SortedRange, typename Value>
|
||||
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<iterator_type, iterator_type> 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<Iterator, Iterator> 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 <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;
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
MultiPoint const
|
||||
>::type iterator_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
<
|
||||
coordinate_type,
|
||||
typename coordinate_system<MultiPoint>::type::units
|
||||
> constants;
|
||||
|
||||
if (boost::empty(multipoint))
|
||||
{
|
||||
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
return;
|
||||
}
|
||||
|
||||
initialize<Box, 0, 2>::apply(mbr);
|
||||
|
||||
if (boost::size(multipoint) == 1)
|
||||
{
|
||||
return dispatch::envelope
|
||||
<
|
||||
typename boost::range_value<MultiPoint>::type
|
||||
>::apply(range::front(multipoint), mbr, strategy);
|
||||
}
|
||||
|
||||
// analyze the points and put the non-pole ones in the
|
||||
// points vector
|
||||
std::vector<point_type> points;
|
||||
bool has_north_pole = false, has_south_pole = false;
|
||||
|
||||
analyze_point_coordinates<constants>(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<constants>(points,
|
||||
coordinate_less<0>(),
|
||||
lon_min,
|
||||
lon_max);
|
||||
|
||||
get_min_max_latitudes<constants>(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<MultiPoint>::type::units
|
||||
>::type helper_box_type;
|
||||
|
||||
helper_box_type helper_mbr;
|
||||
|
||||
geometry::set<min_corner, 0>(helper_mbr, lon_min);
|
||||
geometry::set<min_corner, 1>(helper_mbr, lat_min);
|
||||
geometry::set<max_corner, 0>(helper_mbr, lon_max);
|
||||
geometry::set<max_corner, 1>(helper_mbr, lat_max);
|
||||
|
||||
// now transform to output MBR (per index)
|
||||
envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
|
||||
envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
|
||||
|
||||
// compute envelope for higher coordinates
|
||||
iterator_type it = boost::begin(multipoint);
|
||||
envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy);
|
||||
|
||||
for (++it; it != boost::end(multipoint); ++it)
|
||||
{
|
||||
detail::expand::point_loop
|
||||
<
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy,
|
||||
2, dimension<Box>::value
|
||||
>::apply(mbr, *it, strategy);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiPoint, typename CSTag>
|
||||
struct envelope<MultiPoint, multi_point_tag, CSTag>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
|
||||
: detail::envelope::envelope_multipoint_on_spheroid
|
||||
{};
|
||||
|
||||
template <typename MultiPoint>
|
||||
struct envelope<MultiPoint, multi_point_tag, geographic_tag>
|
||||
: detail::envelope::envelope_multipoint_on_spheroid
|
||||
{};
|
||||
struct envelope<MultiPoint, multi_point_tag>
|
||||
{
|
||||
template <typename Box, typename Strategy>
|
||||
static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& )
|
||||
{
|
||||
Strategy::apply(multipoint, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
@@ -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, 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
|
||||
@@ -17,23 +18,14 @@
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
|
||||
#include <boost/geometry/strategies/spherical/envelope_point.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -43,53 +35,12 @@ namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct envelope_one_point
|
||||
struct envelope_point
|
||||
{
|
||||
template <std::size_t Index, typename Point, typename Box>
|
||||
static inline void apply(Point const& point, Box& mbr)
|
||||
{
|
||||
detail::indexed_point_view<Box, Index> box_corner(mbr);
|
||||
detail::conversion::point_to_point
|
||||
<
|
||||
Point,
|
||||
detail::indexed_point_view<Box, Index>,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(point, box_corner);
|
||||
}
|
||||
|
||||
template <typename Point, typename Box, typename Strategy>
|
||||
static inline void apply(Point const& point, Box& mbr, Strategy const&)
|
||||
static inline void apply(Point const& point, Box& mbr, Strategy const& )
|
||||
{
|
||||
apply<min_corner>(point, mbr);
|
||||
apply<max_corner>(point, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_point_on_spheroid
|
||||
{
|
||||
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);
|
||||
|
||||
typename point_type<Box>::type box_point;
|
||||
|
||||
// transform units of input point to units of a box point
|
||||
transform_units(normalized_point, box_point);
|
||||
|
||||
geometry::set<min_corner, 0>(mbr, geometry::get<0>(box_point));
|
||||
geometry::set<min_corner, 1>(mbr, geometry::get<1>(box_point));
|
||||
|
||||
geometry::set<max_corner, 0>(mbr, geometry::get<0>(box_point));
|
||||
geometry::set<max_corner, 1>(mbr, geometry::get<1>(box_point));
|
||||
|
||||
envelope_one_point
|
||||
<
|
||||
2, dimension<Point>::value
|
||||
>::apply(normalized_point, mbr, strategy);
|
||||
Strategy::apply(point, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -102,21 +53,9 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Point, typename CS_Tag>
|
||||
struct envelope<Point, point_tag, CS_Tag>
|
||||
: detail::envelope::envelope_one_point<0, dimension<Point>::value>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct envelope<Point, point_tag, spherical_equatorial_tag>
|
||||
: detail::envelope::envelope_point_on_spheroid
|
||||
{};
|
||||
|
||||
|
||||
template <typename Point>
|
||||
struct envelope<Point, point_tag, geographic_tag>
|
||||
: detail::envelope::envelope_point_on_spheroid
|
||||
struct envelope<Point, point_tag>
|
||||
: detail::envelope::envelope_point
|
||||
{};
|
||||
|
||||
|
||||
|
||||
@@ -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,17 @@
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/segment.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -53,7 +48,7 @@ namespace detail { namespace envelope
|
||||
struct envelope_range
|
||||
{
|
||||
template <typename Iterator, typename Box, typename Strategy>
|
||||
static inline void apply(Iterator first,
|
||||
static inline void apply(Iterator it,
|
||||
Iterator last,
|
||||
Box& mbr,
|
||||
Strategy const& strategy)
|
||||
@@ -63,16 +58,21 @@ struct envelope_range
|
||||
// initialize MBR
|
||||
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
|
||||
Iterator it = first;
|
||||
if (it != last)
|
||||
{
|
||||
// initialize box with first element in range
|
||||
dispatch::envelope<value_type>::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<Box, value_type>::apply(mbr, *it, strategy);
|
||||
dispatch::expand
|
||||
<
|
||||
Box, value_type
|
||||
>::apply(mbr, *it, strategy.get_element_expand_strategy());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,7 @@ struct envelope_range
|
||||
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, strategy);
|
||||
return apply(Strategy::begin(range), Strategy::end(range), mbr, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -94,86 +94,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<Box, Box>::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<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
}
|
||||
apply(boost::begin(multirange), boost::end(multirange), mbr, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// implementation for multi-range on a spheroid (longitude is periodic)
|
||||
template <typename EnvelopePolicy>
|
||||
struct envelope_multi_range_on_spheroid
|
||||
{
|
||||
template <typename MultiRange, typename Box, typename Strategy>
|
||||
static inline void apply(MultiRange const& multirange,
|
||||
template <typename Iter, typename Box, typename Strategy>
|
||||
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<Box> boxes;
|
||||
for (iterator_type it = boost::begin(multirange);
|
||||
it != boost::end(multirange);
|
||||
++it)
|
||||
typename Strategy::template multi_state<Box> 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<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
}
|
||||
|
||||
state.result(mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015-2016, 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
|
||||
// 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
|
||||
@@ -19,17 +20,20 @@
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -150,10 +154,8 @@ 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, typename Strategy>
|
||||
static inline void apply(RangeOfBoxes const& range_of_boxes,
|
||||
Box& mbr,
|
||||
Strategy const& strategy)
|
||||
template <typename RangeOfBoxes, typename Box>
|
||||
static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
|
||||
{
|
||||
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
|
||||
|
||||
@@ -194,21 +196,17 @@ struct envelope_range_of_boxes_by_expansion
|
||||
{
|
||||
detail::expand::indexed_loop
|
||||
<
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy,
|
||||
min_corner,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(mbr, *it, strategy);
|
||||
>::apply(mbr, *it);
|
||||
|
||||
detail::expand::indexed_loop
|
||||
<
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy,
|
||||
max_corner,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(mbr, *it, strategy);
|
||||
>::apply(mbr, *it);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,24 +226,28 @@ struct envelope_range_of_boxes
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RangeOfBoxes, typename Box, typename Strategy>
|
||||
static inline void apply(RangeOfBoxes const& range_of_boxes,
|
||||
Box& mbr,
|
||||
Strategy const& strategy)
|
||||
template <typename RangeOfBoxes, typename Box>
|
||||
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<RangeOfBoxes>::type box_type;
|
||||
typedef typename coordinate_type<box_type>::type coordinate_type;
|
||||
typedef typename coordinate_system<box_type>::type::units units_type;
|
||||
typedef typename detail::cs_angular_units<box_type>::type units_type;
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
RangeOfBoxes const
|
||||
>::type iterator_type;
|
||||
|
||||
static const bool is_equatorial = ! boost::is_same
|
||||
<
|
||||
typename cs_tag<box_type>::type,
|
||||
spherical_polar_tag
|
||||
>::value;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
<
|
||||
coordinate_type, units_type
|
||||
coordinate_type, units_type, is_equatorial
|
||||
> constants;
|
||||
|
||||
typedef longitude_interval<coordinate_type> interval_type;
|
||||
@@ -269,6 +271,11 @@ struct envelope_range_of_boxes
|
||||
it != boost::end(range_of_boxes);
|
||||
++it)
|
||||
{
|
||||
if (is_inverse_spheroidal_coordinates(*it))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
coordinate_type lat_min = geometry::get<min_corner, 1>(*it);
|
||||
coordinate_type lat_max = geometry::get<max_corner, 1>(*it);
|
||||
if (math::equals(lat_min, constants::max_latitude())
|
||||
@@ -318,7 +325,7 @@ struct envelope_range_of_boxes
|
||||
envelope_range_of_boxes_by_expansion
|
||||
<
|
||||
2, dimension<Box>::value
|
||||
>::apply(range_of_boxes, mbr, strategy);
|
||||
>::apply(range_of_boxes, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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 Vissarion Fysikopoulos, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
@@ -19,34 +19,17 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#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>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/helper_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/formulas/vertex_latitude.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand/point.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#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
|
||||
{
|
||||
|
||||
@@ -54,275 +37,6 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
template <typename CalculationType, typename CS_Tag>
|
||||
struct envelope_segment_call_vertex_latitude
|
||||
{
|
||||
template <typename T1, typename T2, typename Strategy>
|
||||
static inline CalculationType apply(T1 const& lat1,
|
||||
T2 const& alp1,
|
||||
Strategy const& )
|
||||
{
|
||||
return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
|
||||
::apply(lat1, alp1);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CalculationType>
|
||||
struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
|
||||
{
|
||||
template <typename T1, typename T2, typename Strategy>
|
||||
static inline CalculationType apply(T1 const& lat1,
|
||||
T2 const& alp1,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
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>
|
||||
static inline void swap(CalculationType& lon1,
|
||||
CalculationType& lat1,
|
||||
CalculationType& lon2,
|
||||
CalculationType& lat2)
|
||||
{
|
||||
std::swap(lon1, lon2);
|
||||
std::swap(lat1, lat2);
|
||||
}
|
||||
|
||||
// radians
|
||||
template <typename CalculationType>
|
||||
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<CalculationType>();
|
||||
|
||||
return (a1 < a2)
|
||||
? (a1 < pi_half && pi_half < a2)
|
||||
: (a1 > pi_half && pi_half > a2);
|
||||
}
|
||||
|
||||
// radians or degrees
|
||||
template <typename Units, typename CoordinateType>
|
||||
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 <typename Units, typename CalculationType, typename Strategy>
|
||||
static inline void compute_box_corners(CalculationType& lon1,
|
||||
CalculationType& lat1,
|
||||
CalculationType& lon2,
|
||||
CalculationType& lat2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
// coordinates are assumed to be in radians
|
||||
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
|
||||
|
||||
CalculationType lon1_rad = math::as_radian<Units>(lon1);
|
||||
CalculationType lat1_rad = math::as_radian<Units>(lat1);
|
||||
CalculationType lon2_rad = math::as_radian<Units>(lon2);
|
||||
CalculationType lat2_rad = math::as_radian<Units>(lat2);
|
||||
|
||||
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))
|
||||
{
|
||||
// the segment must lie on the equator or is very short
|
||||
return;
|
||||
}
|
||||
|
||||
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 = -p_max;
|
||||
CalculationType const lat_min
|
||||
= math::from_radian<Units>(lat_min_rad);
|
||||
|
||||
if (lat1 > lat_min)
|
||||
{
|
||||
lat1 = lat_min;
|
||||
}
|
||||
}
|
||||
else if (mid_lat > 0)
|
||||
{
|
||||
// update using max latitude
|
||||
CalculationType const lat_max_rad = p_max;
|
||||
CalculationType const lat_max
|
||||
= math::from_radian<Units>(lat_max_rad);
|
||||
|
||||
if (lat2 < lat_max)
|
||||
{
|
||||
lat2 = lat_max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Units, typename CalculationType, typename Strategy>
|
||||
static inline void apply(CalculationType& lon1,
|
||||
CalculationType& lat1,
|
||||
CalculationType& lon2,
|
||||
CalculationType& lat2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
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<Units>(lon1, lon2))
|
||||
{
|
||||
lon1 += constants::period();
|
||||
swap(lon1, lat1, lon2, lat2);
|
||||
}
|
||||
|
||||
compute_box_corners<Units>(lon1, lat1, lon2, lat2, 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 typename coordinate_type<Box>::type box_coordinate_type;
|
||||
|
||||
typedef typename helper_geometry
|
||||
<
|
||||
Box, box_coordinate_type, Units
|
||||
>::type helper_box_type;
|
||||
|
||||
helper_box_type radian_mbr;
|
||||
|
||||
apply<Units>(lon1, lat1, lon2, lat2, strategy);
|
||||
|
||||
geometry::set
|
||||
<
|
||||
min_corner, 0
|
||||
>(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
|
||||
|
||||
geometry::set
|
||||
<
|
||||
min_corner, 1
|
||||
>(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
|
||||
|
||||
geometry::set
|
||||
<
|
||||
max_corner, 0
|
||||
>(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
|
||||
|
||||
geometry::set
|
||||
<
|
||||
max_corner, 1
|
||||
>(radian_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
|
||||
|
||||
transform_units(radian_mbr, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
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
|
||||
{
|
||||
@@ -332,21 +46,17 @@ 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, strategy);
|
||||
}
|
||||
|
||||
template <typename Segment, typename Box>
|
||||
static inline void apply(Segment const& segment, Box& mbr)
|
||||
template <typename Segment, 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]);
|
||||
apply(p[0], p[1], mbr);
|
||||
apply(p[0], p[1], mbr, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user