mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-01 20:42:10 +00:00
Merge branch 'develop' of https://github.com/boostorg/geometry into develop
This commit is contained in:
@@ -979,8 +979,7 @@ struct buffered_piece_collection
|
||||
return;
|
||||
}
|
||||
|
||||
geometry::detail::envelope::envelope_range<>::apply(pc.robust_ring,
|
||||
pc.robust_envelope);
|
||||
geometry::envelope(pc.robust_ring, pc.robust_envelope);
|
||||
|
||||
geometry::assign_inverse(pc.robust_offsetted_envelope);
|
||||
for (signed_size_type i = 0; i < pc.offsetted_count; i++)
|
||||
|
||||
@@ -9,25 +9,25 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_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/strategies/strategy_transform.hpp>
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/transform.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>
|
||||
|
||||
@@ -40,37 +40,97 @@ namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_box_on_spheroid
|
||||
template
|
||||
<
|
||||
std::size_t Index,
|
||||
std::size_t Dimension,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct envelope_indexed_box
|
||||
{
|
||||
template<typename BoxIn, typename BoxOut>
|
||||
template <typename BoxIn, typename BoxOut>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
|
||||
{
|
||||
BoxIn box_in_normalized = detail::return_normalized<BoxIn>(box_in);
|
||||
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
|
||||
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
|
||||
|
||||
geometry::transform(box_in_normalized, 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename CSTag>
|
||||
struct envelope_box
|
||||
{
|
||||
template<typename BoxIn, typename BoxOut>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
|
||||
{
|
||||
geometry::convert(box_in, mbr);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct envelope_box<spherical_equatorial_tag>
|
||||
: envelope_box_on_spheroid
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct envelope_box<geographic_tag>
|
||||
: envelope_box_on_spheroid
|
||||
{};
|
||||
struct envelope_box_on_spheroid
|
||||
{
|
||||
template <typename BoxIn, typename BoxOut>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
|
||||
{
|
||||
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
|
||||
@@ -81,14 +141,26 @@ 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>
|
||||
: detail::envelope::envelope_box<typename cs_tag<Box>::type>
|
||||
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
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
@@ -12,21 +12,21 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_IMPLEMENTATION_HPP
|
||||
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/linestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/multilinestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/multipoint.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
@@ -43,27 +43,28 @@ namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct exterior_ring_expand_policy
|
||||
{
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box& mbr, Geometry const& geometry)
|
||||
{
|
||||
Box ring_mbr;
|
||||
envelope_range<>::apply(exterior_ring(geometry), ring_mbr);
|
||||
geometry::expand(mbr, ring_mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_polygon
|
||||
{
|
||||
template <typename Polygon, typename Box>
|
||||
static inline void apply(Polygon const& poly, Box& mbr)
|
||||
static inline void apply(Polygon const& polygon, Box& mbr)
|
||||
{
|
||||
// For polygon, inspecting outer ring is sufficient
|
||||
envelope_range<>::apply(exterior_ring(poly), mbr);
|
||||
}
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise, consider only the exterior ring
|
||||
envelope_range::apply(ext_ring, mbr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -77,7 +78,7 @@ namespace dispatch
|
||||
|
||||
template <typename Ring>
|
||||
struct envelope<Ring, ring_tag>
|
||||
: detail::envelope::envelope_range<>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
|
||||
@@ -89,15 +90,16 @@ struct envelope<Polygon, polygon_tag>
|
||||
|
||||
template <typename MultiPolygon>
|
||||
struct envelope<MultiPolygon, multi_polygon_tag>
|
||||
: detail::envelope::envelope_range
|
||||
: detail::envelope::envelope_multi_range
|
||||
<
|
||||
detail::envelope::exterior_ring_expand_policy
|
||||
detail::envelope::envelope_polygon
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct initialize_loop
|
||||
{
|
||||
template <typename Box, typename CoordinateType>
|
||||
static inline void apply(Box& box,
|
||||
CoordinateType min_value,
|
||||
CoordinateType max_value)
|
||||
{
|
||||
geometry::set<min_corner, Dimension>(box, min_value);
|
||||
geometry::set<max_corner, Dimension>(box, max_value);
|
||||
|
||||
initialize_loop
|
||||
<
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box, min_value, max_value);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t DimensionCount>
|
||||
struct initialize_loop<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Box, typename CoordinateType>
|
||||
static inline void apply(Box&, CoordinateType, CoordinateType)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box,
|
||||
std::size_t Dimension = 0,
|
||||
std::size_t DimensionCount = dimension<Box>::value
|
||||
>
|
||||
struct initialize
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type coordinate_type;
|
||||
|
||||
static inline void apply(Box& box,
|
||||
coordinate_type min_value
|
||||
= boost::numeric::bounds<coordinate_type>::highest(),
|
||||
coordinate_type max_value
|
||||
= boost::numeric::bounds<coordinate_type>::lowest())
|
||||
{
|
||||
initialize_loop
|
||||
<
|
||||
Dimension, DimensionCount
|
||||
>::apply(box, min_value, max_value);
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INITIALIZE_HPP
|
||||
@@ -12,8 +12,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERSECTS_ANTIMERIDIAN_HPP
|
||||
|
||||
96
include/boost/geometry/algorithms/detail/envelope/linear.hpp
Normal file
96
include/boost/geometry/algorithms/detail/envelope/linear.hpp
Normal file
@@ -0,0 +1,96 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_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/algorithms/detail/envelope/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_linestring_on_spheroid
|
||||
{
|
||||
template <typename Linestring, typename Box>
|
||||
static inline void apply(Linestring const& linestring, Box& mbr)
|
||||
{
|
||||
envelope_range::apply(geometry::segments_begin(linestring),
|
||||
geometry::segments_end(linestring),
|
||||
mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // 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>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
template <typename Linestring>
|
||||
struct envelope<Linestring, linestring_tag, spherical_equatorial_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
|
||||
<
|
||||
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
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
|
||||
@@ -1,182 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINESTRING_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINESTRING_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#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/cs.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/segment_iterator.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/is_empty.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_linear_on_spheroid
|
||||
{
|
||||
template <typename Units, typename Longitude, typename OutputIterator>
|
||||
static inline OutputIterator push_interval(Longitude const& lon1,
|
||||
Longitude const& lon2,
|
||||
OutputIterator oit)
|
||||
{
|
||||
typedef longitude_interval<Longitude> interval_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
<
|
||||
Longitude, Units
|
||||
> constants;
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(lon1, lon2));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(lon1, constants::max_longitude()));
|
||||
|
||||
if (math::larger(lon2, constants::max_longitude()))
|
||||
{
|
||||
*oit++ = interval_type(lon1, constants::max_longitude());
|
||||
*oit++ = interval_type(constants::min_longitude(),
|
||||
lon2 - constants::period());
|
||||
}
|
||||
else
|
||||
{
|
||||
*oit++ = interval_type(lon1, lon2);
|
||||
}
|
||||
return oit;
|
||||
}
|
||||
|
||||
template <typename Linear, typename Box>
|
||||
static inline void apply(Linear const& linear, Box& mbr)
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type box_coordinate_type;
|
||||
typedef longitude_interval<box_coordinate_type> interval_type;
|
||||
|
||||
typedef typename geometry::segment_iterator
|
||||
<
|
||||
Linear const
|
||||
> iterator_type;
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(! geometry::is_empty(linear));
|
||||
|
||||
std::vector<interval_type> longitude_intervals;
|
||||
std::back_insert_iterator
|
||||
<
|
||||
std::vector<interval_type>
|
||||
> oit(longitude_intervals);
|
||||
|
||||
box_coordinate_type lat_min = 0, lat_max = 0;
|
||||
bool first = true;
|
||||
for (iterator_type seg_it = geometry::segments_begin(linear);
|
||||
seg_it != geometry::segments_end(linear);
|
||||
++seg_it, first = false)
|
||||
{
|
||||
Box segment_mbr;
|
||||
dispatch::envelope
|
||||
<
|
||||
typename std::iterator_traits<iterator_type>::value_type
|
||||
>::apply(*seg_it, segment_mbr);
|
||||
|
||||
oit = push_interval
|
||||
<
|
||||
typename coordinate_system<Box>::type::units
|
||||
>(geometry::get<min_corner, 0>(segment_mbr),
|
||||
geometry::get<max_corner, 0>(segment_mbr),
|
||||
oit);
|
||||
|
||||
if (first)
|
||||
{
|
||||
lat_min = geometry::get<min_corner, 1>(segment_mbr);
|
||||
lat_max = geometry::get<max_corner, 1>(segment_mbr);
|
||||
}
|
||||
|
||||
// update min and max latitude, if needed
|
||||
if (math::smaller(geometry::get<min_corner, 1>(segment_mbr),
|
||||
lat_min))
|
||||
{
|
||||
lat_min = geometry::get<min_corner, 1>(segment_mbr);
|
||||
}
|
||||
|
||||
if (math::larger(geometry::get<max_corner, 1>(segment_mbr),
|
||||
lat_max))
|
||||
{
|
||||
lat_max = geometry::get<max_corner, 1>(segment_mbr);
|
||||
}
|
||||
}
|
||||
|
||||
box_coordinate_type lon_min = 0, lon_max = 0;
|
||||
envelope_range_of_longitudes
|
||||
<
|
||||
typename coordinate_system<Box>::type::units
|
||||
>::apply(longitude_intervals, lon_min, lon_max);
|
||||
|
||||
assign_values(mbr, lon_min, lat_min, lon_max, lat_max);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename CSTag>
|
||||
struct envelope_linestring
|
||||
: envelope_range<>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct envelope_linestring<spherical_equatorial_tag>
|
||||
: envelope_linear_on_spheroid
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template <typename Linestring>
|
||||
struct envelope<Linestring, linestring_tag>
|
||||
: detail::envelope::envelope_linestring<typename cs_tag<Linestring>::type>
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINESTRING_HPP
|
||||
@@ -1,86 +0,0 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTILINESTRING_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTILINESTRING_HPP
|
||||
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/linestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct envelope_range_expand_policy
|
||||
{
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box& mbr, Geometry const& geometry)
|
||||
{
|
||||
Box mbr2;
|
||||
envelope_range<>::apply(geometry, mbr2);
|
||||
geometry::expand(mbr, mbr2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename CSTag>
|
||||
struct envelope_multilinestring
|
||||
: envelope_range<envelope_range_expand_policy>
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct envelope_multilinestring<spherical_equatorial_tag>
|
||||
: envelope_linear_on_spheroid
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename MultiLinestring>
|
||||
struct envelope<MultiLinestring, multi_linestring_tag>
|
||||
: detail::envelope::envelope_multilinestring
|
||||
<
|
||||
typename cs_tag<MultiLinestring>::type
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTILINESTRING_HPP
|
||||
@@ -4,12 +4,14 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
@@ -28,14 +30,13 @@
|
||||
|
||||
#include <boost/geometry/geometries/helper_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/transform.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>
|
||||
|
||||
|
||||
@@ -50,14 +51,14 @@ namespace detail { namespace envelope
|
||||
class envelope_multipoint_on_spheroid
|
||||
{
|
||||
private:
|
||||
template <std::size_t Dimension>
|
||||
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<Dimension>(point1),
|
||||
geometry::get<Dimension>(point2));
|
||||
return math::smaller(geometry::get<Dim>(point1),
|
||||
geometry::get<Dim>(point2));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -230,6 +231,10 @@ public:
|
||||
{
|
||||
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
|
||||
<
|
||||
@@ -237,12 +242,14 @@ public:
|
||||
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
|
||||
@@ -302,16 +309,37 @@ public:
|
||||
lat_max);
|
||||
}
|
||||
|
||||
typename helper_geometry
|
||||
typedef typename helper_geometry
|
||||
<
|
||||
Box,
|
||||
coordinate_type,
|
||||
typename coordinate_system<MultiPoint>::type::units
|
||||
>::type helper_mbr;
|
||||
>::type helper_box_type;
|
||||
|
||||
assign_values(helper_mbr, lon_min, lat_min, lon_max, lat_max);
|
||||
helper_box_type helper_mbr;
|
||||
|
||||
geometry::transform(helper_mbr, 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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -319,6 +347,8 @@ public:
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
@@ -326,7 +356,7 @@ namespace dispatch
|
||||
|
||||
template <typename MultiPoint, typename CSTag>
|
||||
struct envelope<MultiPoint, multi_point_tag, CSTag>
|
||||
: detail::envelope::envelope_range<>
|
||||
: detail::envelope::envelope_range
|
||||
{};
|
||||
|
||||
template <typename MultiPoint>
|
||||
@@ -341,7 +371,7 @@ struct envelope<MultiPoint, multi_point_tag, geographic_tag>
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
@@ -9,27 +9,28 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_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/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/convert.hpp>
|
||||
#include <boost/geometry/algorithms/transform.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>
|
||||
|
||||
|
||||
@@ -40,6 +41,32 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct envelope_one_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>
|
||||
static inline void apply(Point const& point, Box& mbr)
|
||||
{
|
||||
apply<min_corner>(point, mbr);
|
||||
apply<max_corner>(point, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_point_on_spheroid
|
||||
{
|
||||
template<typename Point, typename Box>
|
||||
@@ -49,34 +76,23 @@ struct envelope_point_on_spheroid
|
||||
|
||||
typename point_type<Box>::type box_point;
|
||||
|
||||
// transform input point to a point of the same type as box's point
|
||||
geometry::transform(normalized_point, box_point);
|
||||
// transform units of input point to units of a box point
|
||||
transform_units(normalized_point, box_point);
|
||||
|
||||
geometry::convert(box_point, mbr);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename CSTag>
|
||||
struct envelope_one_point
|
||||
{
|
||||
template<typename Point, typename Box>
|
||||
static inline void apply(Point const& point, Box& mbr)
|
||||
{
|
||||
geometry::convert(point, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct envelope_one_point<spherical_equatorial_tag>
|
||||
: envelope_point_on_spheroid
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct envelope_one_point<geographic_tag>
|
||||
: envelope_point_on_spheroid
|
||||
{};
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -85,14 +101,26 @@ 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>
|
||||
: detail::envelope::envelope_one_point<typename cs_tag<Point>::type>
|
||||
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
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
@@ -12,17 +12,30 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_HPP
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#include <boost/range.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/expand.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>
|
||||
|
||||
@@ -35,51 +48,124 @@ namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
struct default_expand_policy
|
||||
// implementation for simple ranges
|
||||
struct envelope_range
|
||||
{
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(Box& mbr, Geometry const& geometry)
|
||||
template <typename Iterator, typename Box>
|
||||
static inline void apply(Iterator first, Iterator last, Box& mbr)
|
||||
{
|
||||
geometry::expand(mbr, geometry);
|
||||
typedef typename std::iterator_traits<Iterator>::value_type value_type;
|
||||
|
||||
// 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);
|
||||
|
||||
// consider now the remaining elements in the range (if any)
|
||||
for (++it; it != last; ++it)
|
||||
{
|
||||
dispatch::expand<Box, value_type>::apply(mbr, *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Range, typename Box>
|
||||
static inline void apply(Range const& range, Box& mbr)
|
||||
{
|
||||
return apply(boost::begin(range), boost::end(range), mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename ExpandPolicy, typename Iterator, typename Box>
|
||||
inline void envelope_iterators(Iterator first, Iterator last, Box& mbr)
|
||||
// implementation for multi-ranges
|
||||
template <typename EnvelopePolicy>
|
||||
struct envelope_multi_range
|
||||
{
|
||||
for (Iterator it = first; it != last; ++it)
|
||||
template <typename MultiRange, typename Box>
|
||||
static inline void apply(MultiRange const& multirange, Box& mbr)
|
||||
{
|
||||
ExpandPolicy::apply(mbr, *it);
|
||||
}
|
||||
}
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
MultiRange const
|
||||
>::type iterator_type;
|
||||
|
||||
|
||||
template <typename ExpandPolicy = default_expand_policy>
|
||||
struct envelope_range
|
||||
{
|
||||
/// Calculate envelope of range using a strategy
|
||||
template <typename Range, typename Box>
|
||||
static inline void apply(Range const& range, Box& mbr)
|
||||
{
|
||||
typename boost::range_iterator<Range const>::type it
|
||||
= boost::begin(range);
|
||||
|
||||
if (it != boost::end(range))
|
||||
bool initialized = false;
|
||||
for (iterator_type it = boost::begin(multirange);
|
||||
it != boost::end(multirange);
|
||||
++it)
|
||||
{
|
||||
// initialize box with first element in range
|
||||
dispatch::envelope
|
||||
<
|
||||
typename boost::range_value<Range>::type
|
||||
>::apply(*it, mbr);
|
||||
if (! geometry::is_empty(*it))
|
||||
{
|
||||
if (initialized)
|
||||
{
|
||||
Box helper_mbr;
|
||||
EnvelopePolicy::apply(*it, helper_mbr);
|
||||
|
||||
// consider now the remaining elements in the range (if any)
|
||||
++it;
|
||||
envelope_iterators
|
||||
<
|
||||
ExpandPolicy
|
||||
>(it, boost::end(range), mbr);
|
||||
dispatch::expand<Box, Box>::apply(mbr, helper_mbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// compute the initial envelope
|
||||
EnvelopePolicy::apply(*it, mbr);
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (! initialized)
|
||||
{
|
||||
// if not already initialized, initialize MBR
|
||||
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// implementation for multi-range on a spheroid (longitude is periodic)
|
||||
template <typename EnvelopePolicy>
|
||||
struct envelope_multi_range_on_spheroid
|
||||
{
|
||||
template <typename MultiRange, typename Box>
|
||||
static inline void apply(MultiRange const& multirange, Box& mbr)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (! geometry::is_empty(*it))
|
||||
{
|
||||
Box helper_box;
|
||||
EnvelopePolicy::apply(*it, helper_box);
|
||||
boxes.push_back(helper_box);
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_RANGE_OF_BOXES_HPP
|
||||
@@ -23,9 +24,11 @@
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
#include <boost/geometry/util/range.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.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>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -92,8 +95,6 @@ struct envelope_range_of_longitudes
|
||||
|
||||
Longitude const zero = 0;
|
||||
Longitude const period = constants::period();
|
||||
Longitude const min_longitude = constants::min_longitude();
|
||||
Longitude const max_longitude = constants::max_longitude();
|
||||
|
||||
lon_min = lon_max = zero;
|
||||
|
||||
@@ -118,12 +119,17 @@ struct envelope_range_of_longitudes
|
||||
max_gap_right);
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(lon_min, lon_max));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(lon_max, max_longitude));
|
||||
BOOST_GEOMETRY_ASSERT(! math::smaller(lon_min, min_longitude));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::larger(lon_max, constants::max_longitude()));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::smaller(lon_min, constants::min_longitude()));
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(max_gap_left, max_gap_right));
|
||||
BOOST_GEOMETRY_ASSERT(! math::larger(max_gap_right, max_longitude));
|
||||
BOOST_GEOMETRY_ASSERT(! math::smaller(max_gap_left, min_longitude));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::larger(max_gap_left, max_gap_right));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::larger(max_gap_right, constants::max_longitude()));
|
||||
BOOST_GEOMETRY_ASSERT
|
||||
(! math::smaller(max_gap_left, constants::min_longitude()));
|
||||
|
||||
if (math::larger(max_gap, zero))
|
||||
{
|
||||
@@ -140,6 +146,72 @@ 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)
|
||||
{
|
||||
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
|
||||
|
||||
typedef typename boost::range_iterator
|
||||
<
|
||||
RangeOfBoxes const
|
||||
>::type iterator_type;
|
||||
|
||||
// first initialize MBR
|
||||
detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
|
||||
detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
|
||||
|
||||
detail::indexed_point_view<box_type const, min_corner>
|
||||
first_box_min(range::front(range_of_boxes));
|
||||
|
||||
detail::indexed_point_view<box_type const, max_corner>
|
||||
first_box_max(range::front(range_of_boxes));
|
||||
|
||||
detail::conversion::point_to_point
|
||||
<
|
||||
detail::indexed_point_view<box_type const, min_corner>,
|
||||
detail::indexed_point_view<Box, min_corner>,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(first_box_min, mbr_min);
|
||||
|
||||
detail::conversion::point_to_point
|
||||
<
|
||||
detail::indexed_point_view<box_type const, max_corner>,
|
||||
detail::indexed_point_view<Box, max_corner>,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(first_box_max, mbr_max);
|
||||
|
||||
// now expand using the remaining boxes
|
||||
iterator_type it = boost::begin(range_of_boxes);
|
||||
for (++it; it != boost::end(range_of_boxes); ++it)
|
||||
{
|
||||
detail::expand::indexed_loop
|
||||
<
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy,
|
||||
min_corner,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(mbr, *it);
|
||||
|
||||
detail::expand::indexed_loop
|
||||
<
|
||||
strategy::compare::default_strategy,
|
||||
strategy::compare::default_strategy,
|
||||
max_corner,
|
||||
Dimension,
|
||||
DimensionCount
|
||||
>::apply(mbr, *it);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct envelope_range_of_boxes
|
||||
{
|
||||
template <std::size_t Index>
|
||||
@@ -217,7 +289,8 @@ struct envelope_range_of_boxes
|
||||
}
|
||||
}
|
||||
|
||||
coordinate_type lon_min(0), lon_max(0);
|
||||
coordinate_type lon_min = 0;
|
||||
coordinate_type lon_max = 0;
|
||||
envelope_range_of_longitudes
|
||||
<
|
||||
units_type
|
||||
@@ -225,11 +298,22 @@ struct envelope_range_of_boxes
|
||||
|
||||
// do not convert units; conversion will be performed at a
|
||||
// higher level
|
||||
assign_values(mbr,
|
||||
lon_min,
|
||||
geometry::get<min_corner, 1>(*it_min),
|
||||
lon_max,
|
||||
geometry::get<max_corner, 1>(*it_max));
|
||||
|
||||
// assign now the min/max longitude/latitude values
|
||||
detail::indexed_point_view<Box, min_corner> mbr_min(mbr);
|
||||
detail::indexed_point_view<Box, max_corner> mbr_max(mbr);
|
||||
|
||||
geometry::set<0>(mbr_min, lon_min);
|
||||
geometry::set<1>(mbr_min, geometry::get<min_corner, 1>(*it_min));
|
||||
geometry::set<0>(mbr_max, lon_max);
|
||||
geometry::set<1>(mbr_max, geometry::get<max_corner, 1>(*it_max));
|
||||
|
||||
// what remains to be done is to compute the envelope range
|
||||
// for the remaining dimensions (if any)
|
||||
envelope_range_of_boxes_by_expansion
|
||||
<
|
||||
2, dimension<Box>::value
|
||||
>::apply(range_of_boxes, mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -9,16 +9,14 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
|
||||
#include <boost/numeric/conversion/cast.hpp>
|
||||
@@ -35,15 +33,15 @@
|
||||
|
||||
#include <boost/geometry/geometries/helper_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
#include <boost/geometry/strategies/compare.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>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand/point.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
|
||||
|
||||
@@ -55,6 +53,25 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct envelope_one_segment
|
||||
{
|
||||
template<typename Point, typename Box>
|
||||
static inline void apply(Point const& p1, Point const& p2, Box& mbr)
|
||||
{
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 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.
|
||||
@@ -255,29 +272,47 @@ public:
|
||||
{
|
||||
typedef typename coordinate_type<Box>::type box_coordinate_type;
|
||||
|
||||
typename helper_geometry
|
||||
typedef typename helper_geometry
|
||||
<
|
||||
Box, box_coordinate_type, radian
|
||||
>::type radian_mbr;
|
||||
>::type helper_box_type;
|
||||
|
||||
helper_box_type radian_mbr;
|
||||
|
||||
apply(lon1, lat1, lon2, lat2);
|
||||
|
||||
assign_values(radian_mbr,
|
||||
boost::numeric_cast<box_coordinate_type>(lon1),
|
||||
boost::numeric_cast<box_coordinate_type>(lat1),
|
||||
boost::numeric_cast<box_coordinate_type>(lon2),
|
||||
boost::numeric_cast<box_coordinate_type>(lat2));
|
||||
geometry::set
|
||||
<
|
||||
min_corner, 0
|
||||
>(radian_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
|
||||
|
||||
geometry::transform(radian_mbr, mbr);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct envelope_segment_on_spheroid
|
||||
template <std::size_t DimensionCount>
|
||||
struct envelope_segment_on_sphere
|
||||
{
|
||||
template <typename Point, typename Box>
|
||||
static inline void apply(Point const& p1, Point const& p2, Box& mbr)
|
||||
{
|
||||
// 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);
|
||||
|
||||
@@ -286,25 +321,37 @@ struct envelope_segment_on_spheroid
|
||||
geometry::get_as_radian<0>(p2_normalized),
|
||||
geometry::get_as_radian<1>(p2_normalized),
|
||||
mbr);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename CSTag>
|
||||
struct envelope_one_segment
|
||||
{
|
||||
template<typename Point, typename Box>
|
||||
static inline void apply(Point const& p1, Point const& p2, Box& mbr)
|
||||
// now compute the envelope range for coordinates of
|
||||
// dimension 2 and higher
|
||||
envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr);
|
||||
}
|
||||
|
||||
template <typename Segment, typename Box>
|
||||
static inline void apply(Segment const& segment, Box& mbr)
|
||||
{
|
||||
envelope_one_point<CSTag>::apply(p1, mbr);
|
||||
geometry::expand(mbr, p2);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct envelope_one_segment<spherical_equatorial_tag>
|
||||
: envelope_segment_on_spheroid
|
||||
|
||||
|
||||
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
|
||||
|
||||
@@ -314,8 +361,8 @@ namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
template <typename Segment>
|
||||
struct envelope<Segment, segment_tag>
|
||||
template <typename Segment, typename CS_Tag>
|
||||
struct envelope<Segment, segment_tag, CS_Tag>
|
||||
{
|
||||
template <typename Box>
|
||||
static inline void apply(Segment const& segment, Box& mbr)
|
||||
@@ -323,16 +370,16 @@ struct envelope<Segment, segment_tag>
|
||||
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_one_segment
|
||||
detail::envelope::envelope_segment
|
||||
<
|
||||
typename cs_tag<Segment>::type
|
||||
dimension<Segment>::value, CS_Tag
|
||||
>::apply(p[0], p[1], mbr);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
#include <boost/geometry/views/detail/two_dimensional_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace envelope
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryIn,
|
||||
typename GeometryOut,
|
||||
typename TagIn = typename tag<GeometryIn>::type,
|
||||
typename TagOut = typename tag<GeometryOut>::type
|
||||
>
|
||||
struct transform_units_impl
|
||||
: not_implemented<TagIn, TagOut>
|
||||
{};
|
||||
|
||||
template <typename PointIn, typename PointOut>
|
||||
struct transform_units_impl<PointIn, PointOut, point_tag, point_tag>
|
||||
{
|
||||
static inline void apply(PointIn const& point_in, PointOut& point_out)
|
||||
{
|
||||
detail::two_dimensional_view<PointIn const> view_in(point_in);
|
||||
detail::two_dimensional_view<PointOut> view_out(point_out);
|
||||
|
||||
geometry::transform(view_in, view_out);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename BoxIn, typename BoxOut>
|
||||
struct transform_units_impl<BoxIn, BoxOut, box_tag, box_tag>
|
||||
{
|
||||
template <std::size_t Index>
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& box_out)
|
||||
{
|
||||
typedef detail::indexed_point_view<BoxIn const, Index> view_in_type;
|
||||
typedef detail::indexed_point_view<BoxOut, Index> view_out_type;
|
||||
|
||||
view_in_type view_in(box_in);
|
||||
view_out_type view_out(box_out);
|
||||
|
||||
transform_units_impl
|
||||
<
|
||||
view_in_type, view_out_type
|
||||
>::apply(view_in, view_out);
|
||||
}
|
||||
|
||||
static inline void apply(BoxIn const& box_in, BoxOut& box_out)
|
||||
{
|
||||
apply<min_corner>(box_in, box_out);
|
||||
apply<max_corner>(box_in, box_out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Short utility to transform the units of the first two coordinates of
|
||||
// geometry_in to the units of geometry_out
|
||||
template <typename GeometryIn, typename GeometryOut>
|
||||
inline void transform_units(GeometryIn const& geometry_in,
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
transform_units_impl
|
||||
<
|
||||
GeometryIn, GeometryOut
|
||||
>::apply(geometry_in, geometry_out);
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::envelope
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
}} // namespace boost:geometry
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_TRANSFORM_UNITS_HPP
|
||||
@@ -10,24 +10,27 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/expand.hpp>
|
||||
|
||||
|
||||
@@ -72,10 +75,19 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, BoxIn, StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag, CSTagOut, CSTag
|
||||
> : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
||||
{};
|
||||
BoxOut, BoxIn,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag,
|
||||
CSTagOut, CSTag
|
||||
> : detail::expand::expand_indexed
|
||||
<
|
||||
0, dimension<BoxIn>::value, StrategyLess, StrategyGreater
|
||||
>
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
|
||||
COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
|
||||
(types<CSTagOut, CSTag>()));
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
@@ -84,8 +96,10 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, BoxIn, StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag, spherical_equatorial_tag, spherical_equatorial_tag
|
||||
BoxOut, BoxIn,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag,
|
||||
spherical_equatorial_tag, spherical_equatorial_tag
|
||||
> : detail::expand::box_on_spheroid
|
||||
{};
|
||||
|
||||
@@ -96,8 +110,10 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, BoxIn, StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag, geographic_tag, geographic_tag
|
||||
BoxOut, BoxIn,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, box_tag,
|
||||
geographic_tag, geographic_tag
|
||||
> : detail::expand::box_on_spheroid
|
||||
{};
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_IMPLEMENTATION_HPP
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INDEXED_HPP
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
@@ -113,6 +112,7 @@ struct indexed_loop
|
||||
// Changes a box such that the other box is also contained by the box
|
||||
template
|
||||
<
|
||||
std::size_t Dimension, std::size_t DimensionCount,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand_indexed
|
||||
@@ -123,13 +123,13 @@ struct expand_indexed
|
||||
indexed_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater,
|
||||
0, 0, dimension<Geometry>::type::value
|
||||
0, Dimension, DimensionCount
|
||||
>::apply(box, geometry);
|
||||
|
||||
indexed_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater,
|
||||
1, 0, dimension<Geometry>::type::value
|
||||
1, Dimension, DimensionCount
|
||||
>::apply(box, geometry);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_INTERFACE_HPP
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
|
||||
@@ -23,6 +23,9 @@
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
@@ -33,14 +36,10 @@
|
||||
#include <boost/geometry/util/select_coordinate_type.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/compare.hpp>
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/expand.hpp>
|
||||
|
||||
@@ -53,11 +52,81 @@ namespace detail { namespace expand
|
||||
{
|
||||
|
||||
|
||||
struct point_on_spheroid
|
||||
template
|
||||
<
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& box, Point const& source)
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Point, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Point, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type
|
||||
<
|
||||
Point, Box
|
||||
>::type coordinate_type;
|
||||
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
coordinate_type const coord = get<Dimension>(source);
|
||||
|
||||
if (less(coord, get<min_corner, Dimension>(box)))
|
||||
{
|
||||
set<min_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
if (greater(coord, get<max_corner, Dimension>(box)))
|
||||
{
|
||||
set<max_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
point_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater, Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater, DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box&, Point const&) {}
|
||||
};
|
||||
|
||||
|
||||
// implementation for the spherical equatorial and geographic coordinate systems
|
||||
template
|
||||
<
|
||||
typename StrategyLess,
|
||||
typename StrategyGreater,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop_on_spheroid
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& box, Point const& point)
|
||||
{
|
||||
typedef typename point_type<Box>::type box_point_type;
|
||||
typedef typename coordinate_type<Box>::type box_coordinate_type;
|
||||
|
||||
typedef math::detail::constants_on_spheroid
|
||||
@@ -70,9 +139,9 @@ struct point_on_spheroid
|
||||
Point p_normalized = detail::return_normalized<Point>(point);
|
||||
detail::normalize(box, box);
|
||||
|
||||
// transform input point to be the same type as the box point
|
||||
typename point_type<Box>::type box_point;
|
||||
geometry::transform(p_normalized, box_point);
|
||||
// transform input point to be of the same type as the box point
|
||||
box_point_type box_point;
|
||||
detail::envelope::transform_units(p_normalized, box_point);
|
||||
|
||||
box_coordinate_type p_lon = geometry::get<0>(box_point);
|
||||
box_coordinate_type p_lat = geometry::get<1>(box_point);
|
||||
@@ -89,11 +158,8 @@ struct point_on_spheroid
|
||||
// south pole; the only important coordinate here is the
|
||||
// pole's latitude, as the longitude can be anything;
|
||||
// we, thus, take into account the point's latitude only and return
|
||||
assign_values(box,
|
||||
b_lon_min,
|
||||
(std::min)(p_lat, b_lat_min),
|
||||
b_lon_max,
|
||||
(std::max)(p_lat, b_lat_max));
|
||||
geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
|
||||
geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -104,11 +170,10 @@ struct point_on_spheroid
|
||||
// the only important coordinate here is the pole's latitude,
|
||||
// as the longitude can be anything;
|
||||
// we thus take into account the box's latitude only and return
|
||||
assign_values(box,
|
||||
p_lon,
|
||||
(std::min)(p_lat, b_lat_min),
|
||||
p_lon,
|
||||
(std::max)(p_lat, b_lat_max));
|
||||
geometry::set<min_corner, 0>(box, p_lon);
|
||||
geometry::set<min_corner, 1>(box, (std::min)(p_lat, b_lat_min));
|
||||
geometry::set<max_corner, 0>(box, p_lon);
|
||||
geometry::set<max_corner, 1>(box, (std::max)(p_lat, b_lat_max));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -151,71 +216,19 @@ struct point_on_spheroid
|
||||
}
|
||||
}
|
||||
|
||||
assign_values(box, b_lon_min, b_lat_min, b_lon_max, b_lat_max);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename StrategyLess, typename StrategyGreater,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& box, Point const& source)
|
||||
{
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyLess, 1, Point, Dimension
|
||||
>::type less_type;
|
||||
|
||||
typedef typename strategy::compare::detail::select_strategy
|
||||
<
|
||||
StrategyGreater, -1, Point, Dimension
|
||||
>::type greater_type;
|
||||
|
||||
typedef typename select_coordinate_type<Point, Box>::type coordinate_type;
|
||||
|
||||
less_type less;
|
||||
greater_type greater;
|
||||
|
||||
coordinate_type const coord = get<Dimension>(source);
|
||||
|
||||
if (less(coord, get<min_corner, Dimension>(box)))
|
||||
{
|
||||
set<min_corner, Dimension>(box, coord);
|
||||
}
|
||||
|
||||
if (greater(coord, get<max_corner, Dimension>(box)))
|
||||
{
|
||||
set<max_corner, Dimension>(box, coord);
|
||||
}
|
||||
geometry::set<min_corner, 0>(box, b_lon_min);
|
||||
geometry::set<min_corner, 1>(box, b_lat_min);
|
||||
geometry::set<max_corner, 0>(box, b_lon_max);
|
||||
geometry::set<max_corner, 1>(box, b_lat_max);
|
||||
|
||||
point_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box, source);
|
||||
StrategyLess, StrategyGreater, 2, DimensionCount
|
||||
>::apply(box, point);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename StrategyLess, typename StrategyGreater, std::size_t DimensionCount
|
||||
>
|
||||
struct point_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater, DimensionCount, DimensionCount
|
||||
>
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box&, Point const&) {}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::expand
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -223,6 +236,7 @@ struct point_loop
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
|
||||
// Box + point -> new box containing also point
|
||||
template
|
||||
<
|
||||
@@ -232,12 +246,34 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, Point, StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag, CSTagOut, CSTag
|
||||
BoxOut, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag,
|
||||
CSTagOut, CSTag
|
||||
> : detail::expand::point_loop
|
||||
<
|
||||
StrategyLess, StrategyGreater,
|
||||
0, dimension<Point>::type::value
|
||||
StrategyLess, StrategyGreater, 0, dimension<Point>::value
|
||||
>
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
|
||||
COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
|
||||
(types<CSTagOut, CSTag>()));
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename BoxOut, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag,
|
||||
spherical_equatorial_tag, spherical_equatorial_tag
|
||||
> : detail::expand::point_loop_on_spheroid
|
||||
<
|
||||
StrategyLess, StrategyGreater, dimension<Point>::value
|
||||
>
|
||||
{};
|
||||
|
||||
@@ -248,22 +284,16 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, Point, StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag, spherical_equatorial_tag, spherical_equatorial_tag
|
||||
> : detail::expand::point_on_spheroid
|
||||
BoxOut, Point,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag,
|
||||
geographic_tag, geographic_tag
|
||||
> : detail::expand::point_loop_on_spheroid
|
||||
<
|
||||
StrategyLess, StrategyGreater, dimension<Point>::value
|
||||
>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename BoxOut, typename Point,
|
||||
typename StrategyLess, typename StrategyGreater
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
BoxOut, Point, StrategyLess, StrategyGreater,
|
||||
box_tag, point_tag, geographic_tag, geographic_tag
|
||||
> : detail::expand::point_on_spheroid
|
||||
{};
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
@@ -10,21 +10,25 @@
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_SEGMENT_HPP
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
|
||||
#include <boost/geometry/algorithms/detail/expand/box.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/expand.hpp>
|
||||
|
||||
|
||||
@@ -36,14 +40,24 @@ namespace detail { namespace expand
|
||||
{
|
||||
|
||||
|
||||
struct segment_on_spheroid
|
||||
struct segment_on_sphere
|
||||
{
|
||||
template <typename Box, typename Segment>
|
||||
static inline void apply(Box& box, Segment const& segment)
|
||||
{
|
||||
Box segment_envelope;
|
||||
dispatch::envelope<Segment>::apply(segment, segment_envelope);
|
||||
box_on_spheroid::apply(box, segment_envelope);
|
||||
Box mbrs[2];
|
||||
|
||||
// compute the envelope of the segment
|
||||
detail::envelope::envelope_segment_on_sphere
|
||||
<
|
||||
dimension<Segment>::value
|
||||
>::apply(segment, mbrs[0]);
|
||||
|
||||
// normalize the box
|
||||
detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1]);
|
||||
|
||||
// compute the envelope of the two boxes
|
||||
detail::envelope::envelope_range_of_boxes::apply(mbrs, box);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -64,10 +78,19 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
Box, Segment, StrategyLess, StrategyGreater,
|
||||
box_tag, segment_tag, CSTagOut, CSTag
|
||||
> : detail::expand::expand_indexed<StrategyLess, StrategyGreater>
|
||||
{};
|
||||
Box, Segment,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, segment_tag,
|
||||
CSTagOut, CSTag
|
||||
> : detail::expand::expand_indexed
|
||||
<
|
||||
0, dimension<Segment>::value, StrategyLess, StrategyGreater
|
||||
>
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((boost::is_same<CSTagOut, CSTag>::value),
|
||||
COORDINATE_SYSTEMS_MUST_BE_THE_SAME,
|
||||
(types<CSTagOut, CSTag>()));
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
@@ -76,10 +99,11 @@ template
|
||||
>
|
||||
struct expand
|
||||
<
|
||||
Box, Segment, StrategyLess, StrategyGreater,
|
||||
Box, Segment,
|
||||
StrategyLess, StrategyGreater,
|
||||
box_tag, segment_tag,
|
||||
spherical_equatorial_tag, spherical_equatorial_tag
|
||||
> : detail::expand::segment_on_spheroid
|
||||
> : detail::expand::segment_on_sphere
|
||||
{};
|
||||
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <boost/range.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/assert.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
@@ -77,13 +78,24 @@ struct not_equal_to
|
||||
template <typename Range, closure_selector Closure>
|
||||
struct has_spikes
|
||||
{
|
||||
template <typename Iterator>
|
||||
static inline Iterator find_different_from_first(Iterator first,
|
||||
Iterator last)
|
||||
{
|
||||
typedef not_equal_to<typename point_type<Range>::type> not_equal;
|
||||
|
||||
BOOST_GEOMETRY_ASSERT(first != last);
|
||||
|
||||
Iterator second = first;
|
||||
++second;
|
||||
return std::find_if(second, last, not_equal(*first));
|
||||
}
|
||||
|
||||
template <typename VisitPolicy>
|
||||
static inline bool apply(Range const& range, VisitPolicy& visitor)
|
||||
{
|
||||
boost::ignore_unused(visitor);
|
||||
|
||||
typedef not_equal_to<typename point_type<Range>::type> not_equal;
|
||||
|
||||
typedef typename closeable_view<Range const, Closure>::type view_type;
|
||||
typedef typename boost::range_iterator<view_type const>::type iterator;
|
||||
|
||||
@@ -94,23 +106,23 @@ struct has_spikes
|
||||
|
||||
iterator prev = boost::begin(view);
|
||||
|
||||
iterator cur = std::find_if(prev, boost::end(view), not_equal(*prev));
|
||||
if ( cur == boost::end(view) )
|
||||
iterator cur = find_different_from_first(prev, boost::end(view));
|
||||
if (cur == boost::end(view))
|
||||
{
|
||||
// the range has only one distinct point, so it
|
||||
// cannot have a spike
|
||||
return ! visitor.template apply<no_failure>();
|
||||
}
|
||||
|
||||
iterator next = std::find_if(cur, boost::end(view), not_equal(*cur));
|
||||
if ( next == boost::end(view) )
|
||||
iterator next = find_different_from_first(cur, boost::end(view));
|
||||
if (next == boost::end(view))
|
||||
{
|
||||
// the range has only two distinct points, so it
|
||||
// cannot have a spike
|
||||
return ! visitor.template apply<no_failure>();
|
||||
}
|
||||
|
||||
while ( next != boost::end(view) )
|
||||
while (next != boost::end(view))
|
||||
{
|
||||
if ( geometry::detail::point_is_spike_or_equal(*prev,
|
||||
*next,
|
||||
@@ -121,20 +133,19 @@ struct has_spikes
|
||||
}
|
||||
prev = cur;
|
||||
cur = next;
|
||||
next = std::find_if(cur, boost::end(view), not_equal(*cur));
|
||||
next = find_different_from_first(cur, boost::end(view));
|
||||
}
|
||||
|
||||
if ( geometry::equals(range::front(view), range::back(view)) )
|
||||
if (geometry::equals(range::front(view), range::back(view)))
|
||||
{
|
||||
iterator cur = boost::begin(view);
|
||||
typename boost::range_reverse_iterator
|
||||
<
|
||||
view_type const
|
||||
>::type prev = std::find_if(boost::rbegin(view),
|
||||
boost::rend(view),
|
||||
not_equal(range::back(view)));
|
||||
iterator next =
|
||||
std::find_if(cur, boost::end(view), not_equal(*cur));
|
||||
>::type prev = find_different_from_first(boost::rbegin(view),
|
||||
boost::rend(view));
|
||||
|
||||
iterator next = find_different_from_first(cur, boost::end(view));
|
||||
if (detail::point_is_spike_or_equal(*prev, *next, *cur))
|
||||
{
|
||||
return
|
||||
|
||||
@@ -217,7 +217,9 @@ public:
|
||||
: base_t(pi, pj, pk, qi, qj, qk, robust_policy)
|
||||
, m_result(strategy::apply(segment_type1(pi, pj),
|
||||
segment_type2(qi, qj),
|
||||
robust_policy))
|
||||
robust_policy,
|
||||
base_t::rpi(), base_t::rpj(),
|
||||
base_t::rqi(), base_t::rqj()))
|
||||
, m_robust_policy(robust_policy)
|
||||
{}
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DISPATCH_ENVELOPE_HPP
|
||||
@@ -36,7 +36,7 @@ template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename tag<Geometry>::type,
|
||||
typename CSTag = typename cs_tag<Geometry>::type
|
||||
typename CS_Tag = typename cs_tag<Geometry>::type
|
||||
>
|
||||
struct envelope : not_implemented<Tag>
|
||||
{};
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_DISPATCH_EXPAND_HPP
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_ENVELOPE_HPP
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
|
||||
// Use, modification and distribution is subject to the Boost Software License,
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_GEOMETRY_ALGORITHMS_EXPAND_HPP
|
||||
|
||||
@@ -119,15 +119,10 @@ struct relate_cartesian_segments
|
||||
|
||||
boost::ignore_unused_variable_warning(robust_policy);
|
||||
|
||||
typedef typename select_calculation_type
|
||||
<Segment1, Segment2, CalculationType>::type coordinate_type;
|
||||
|
||||
using geometry::detail::equals::equals_point_point;
|
||||
bool const a_is_point = equals_point_point(robust_a1, robust_a2);
|
||||
bool const b_is_point = equals_point_point(robust_b1, robust_b2);
|
||||
|
||||
typedef side::side_by_triangle<coordinate_type> side;
|
||||
|
||||
if(a_is_point && b_is_point)
|
||||
{
|
||||
return equals_point_point(robust_a1, robust_b2)
|
||||
@@ -136,20 +131,32 @@ struct relate_cartesian_segments
|
||||
;
|
||||
}
|
||||
|
||||
typedef typename select_calculation_type
|
||||
<Segment1, Segment2, CalculationType>::type coordinate_type;
|
||||
|
||||
typedef side::side_by_triangle<coordinate_type> side;
|
||||
|
||||
side_info sides;
|
||||
sides.set<0>(side::apply(robust_b1, robust_b2, robust_a1),
|
||||
side::apply(robust_b1, robust_b2, robust_a2));
|
||||
sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
|
||||
side::apply(robust_a1, robust_a2, robust_b2));
|
||||
|
||||
bool collinear = sides.collinear();
|
||||
|
||||
if (sides.same<0>() || sides.same<1>())
|
||||
if (sides.same<0>())
|
||||
{
|
||||
// Both points are at same side of other segment, we can leave
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
sides.set<1>(side::apply(robust_a1, robust_a2, robust_b1),
|
||||
side::apply(robust_a1, robust_a2, robust_b2));
|
||||
|
||||
if (sides.same<1>())
|
||||
{
|
||||
// Both points are at same side of other segment, we can leave
|
||||
return Policy::disjoint();
|
||||
}
|
||||
|
||||
bool collinear = sides.collinear();
|
||||
|
||||
typedef typename select_most_precise
|
||||
<
|
||||
coordinate_type, double
|
||||
|
||||
194
include/boost/geometry/views/detail/two_dimensional_view.hpp
Normal file
194
include/boost/geometry/views/detail/two_dimensional_view.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
|
||||
#define BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_type.hpp>
|
||||
#include <boost/geometry/core/coordinate_system.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/not_implemented.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
std::size_t Dimension1 = 0,
|
||||
std::size_t Dimension2 = 1,
|
||||
typename Tag = typename tag<Geometry>::type
|
||||
>
|
||||
struct two_dimensional_view
|
||||
: not_implemented<Tag>
|
||||
{};
|
||||
|
||||
|
||||
// View that enables to choose two dimensions of a point and see it as
|
||||
// a two-dimensional point
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct two_dimensional_view<Point, Dimension1, Dimension2, point_tag>
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG((Dimension1 < dimension<Point>::value),
|
||||
COORDINATE_DIMENSION1_IS_LARGER_THAN_POINT_DIMENSION,
|
||||
(boost::mpl::int_<Dimension1>));
|
||||
|
||||
BOOST_MPL_ASSERT_MSG((Dimension2 < dimension<Point>::value),
|
||||
COORDINATE_DIMENSION2_IS_LARGER_THAN_POINT_DIMENSION,
|
||||
(boost::mpl::int_<Dimension2>));
|
||||
|
||||
two_dimensional_view(Point& point)
|
||||
: m_point(point)
|
||||
{}
|
||||
|
||||
Point& m_point;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
namespace traits
|
||||
{
|
||||
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct tag
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>
|
||||
>
|
||||
{
|
||||
typedef point_tag type;
|
||||
};
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct coordinate_system
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>
|
||||
> : coordinate_system<typename geometry::point_type<Point>::type>
|
||||
{};
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct coordinate_type
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>
|
||||
> : coordinate_type<typename geometry::point_type<Point>::type>
|
||||
{};
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct dimension
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>
|
||||
> : boost::mpl::int_<2>
|
||||
{};
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct point_type
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>
|
||||
>
|
||||
{
|
||||
typedef typename geometry::point_type<Point>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct access
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>,
|
||||
0
|
||||
>
|
||||
{
|
||||
typedef typename geometry::coordinate_type<Point>::type coordinate_type;
|
||||
typedef geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
> view_type;
|
||||
|
||||
static inline coordinate_type get(view_type const& view)
|
||||
{
|
||||
return geometry::get<Dimension1>(view.m_point);
|
||||
}
|
||||
|
||||
static inline void set(view_type& view, coordinate_type const& value)
|
||||
{
|
||||
geometry::set<Dimension1>(view.m_point, value);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point, std::size_t Dimension1, std::size_t Dimension2>
|
||||
struct access
|
||||
<
|
||||
geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
>,
|
||||
1
|
||||
>
|
||||
{
|
||||
typedef typename geometry::coordinate_type<Point>::type coordinate_type;
|
||||
typedef geometry::detail::two_dimensional_view
|
||||
<
|
||||
Point, Dimension1, Dimension2, point_tag
|
||||
> view_type;
|
||||
|
||||
static inline coordinate_type get(view_type const& view)
|
||||
{
|
||||
return geometry::get<Dimension2>(view.m_point);
|
||||
}
|
||||
|
||||
static inline void set(view_type& view, coordinate_type const& value)
|
||||
{
|
||||
geometry::set<Dimension2>(view.m_point, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace traits
|
||||
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_VIEWS_DETAIL_TWO_DIMENSIONAL_VIEW_HPP
|
||||
@@ -1,9 +1,14 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
||||
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
|
||||
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
|
||||
|
||||
// This file was modified by Oracle on 2015.
|
||||
// Modifications copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -12,6 +17,7 @@
|
||||
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
|
||||
#include <algorithms/test_envelope.hpp>
|
||||
|
||||
@@ -57,6 +63,144 @@ void test_3d()
|
||||
test_envelope<bg::model::box<P> >("BOX(1 1 1,3 3 3)", 1, 3, 1, 3, 1, 3);
|
||||
}
|
||||
|
||||
template <typename Geometry>
|
||||
void test_empty_geometry(std::string const& wkt)
|
||||
{
|
||||
typedef typename bg::coordinate_type<Geometry>::type ct;
|
||||
ct high_val = boost::numeric::bounds<ct>::highest();
|
||||
ct low_val = boost::numeric::bounds<ct>::lowest();
|
||||
|
||||
test_envelope<Geometry>(wkt, high_val, low_val, high_val, low_val);
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_empty()
|
||||
{
|
||||
test_empty_geometry<bg::model::linestring<P> >("LINESTRING()");
|
||||
test_empty_geometry<bg::model::ring<P> >("POLYGON(())");
|
||||
|
||||
test_empty_geometry<bg::model::polygon<P> >("POLYGON(())");
|
||||
|
||||
test_empty_geometry<bg::model::multi_point<P> >("MULTIPOINT()");
|
||||
|
||||
test_empty_geometry
|
||||
<
|
||||
bg::model::multi_linestring<bg::model::linestring<P> >
|
||||
>("MULTILINESTRING()");
|
||||
|
||||
test_empty_geometry
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON()");
|
||||
}
|
||||
|
||||
template <typename P>
|
||||
void test_invalid()
|
||||
{
|
||||
// polygon with empty exterior and interior rings
|
||||
test_empty_geometry<bg::model::polygon<P> >("POLYGON((),(),())");
|
||||
|
||||
// polygon with empty interior rings
|
||||
test_envelope
|
||||
<
|
||||
bg::model::polygon<P>
|
||||
>("POLYGON((1 2,1 20,22 20,22 2,1 2),(),())",
|
||||
1, 22, 2, 20);
|
||||
|
||||
// another polygon with empty interior rings
|
||||
test_envelope
|
||||
<
|
||||
bg::model::polygon<P>
|
||||
>("POLYGON((1 2,1 20,22 20,22 2,1 2),(),(3 4,19 4,19 18,3 18,3 4),())",
|
||||
1, 22, 2, 20);
|
||||
|
||||
// polygon with empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::polygon<P>
|
||||
>("POLYGON((),(),(3 4,19 4,19 18,3 18,3 4),())",
|
||||
3, 19, 4, 18);
|
||||
|
||||
// another polygon with empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::polygon<P>
|
||||
>("POLYGON((),(),(3 4,19 4,19 18,3 18,3 4),(4 5,18 5,18 17,4 17,4 5))",
|
||||
3, 19, 4, 18);
|
||||
|
||||
// yet one more polygon with empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::polygon<P>
|
||||
>("POLYGON((),(),(4 5,18 5,18 17,4 17,4 5),(3 4,19 4,19 18,3 18,3 4))",
|
||||
3, 19, 4, 18);
|
||||
|
||||
// multilinestring with empty linestrings
|
||||
test_empty_geometry
|
||||
<
|
||||
bg::model::multi_linestring<bg::model::linestring<P> >
|
||||
>("MULTILINESTRING((),(),())");
|
||||
|
||||
// multilinestring with empty and non-empty linestrings
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_linestring<bg::model::linestring<P> >
|
||||
>("MULTILINESTRING((),(10 20),())", 10, 10, 20, 20);
|
||||
|
||||
// multipolygon with empty polygon
|
||||
test_empty_geometry
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON((()))");
|
||||
|
||||
// multipolygon with many empty polygons
|
||||
test_empty_geometry
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),(()),((),(),(),(),()))");
|
||||
|
||||
// multipolygon with empty polygons and non-empty (valid) polygon
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),((10 30,10 40,20 30,10 30)),\
|
||||
((),(),()),(()))", 10, 20, 30, 40);
|
||||
|
||||
// multipolygon with empty polygons and non-empty (valid) polygon
|
||||
// that has an interior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),(()),\
|
||||
((1 2,1 20,22 20,22 2,1 2),(3 4,19 4,19 18,3 18,3 4)),(()))",
|
||||
1, 22, 2, 20);
|
||||
|
||||
// multipolygon with empty polygons and non-empty (invalid) polygon
|
||||
// that has an interior ring but empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),(()),((),(3 4,19 4,19 18,3 18,3 4)),(()))",
|
||||
3, 19, 4, 18);
|
||||
|
||||
// multipolygon with empty polygons and non-empty (invalid) polygon
|
||||
// that has an interior ring but empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),((),(),(3 4,19 4,19 18,3 18,3 4),()),(()))",
|
||||
3, 19, 4, 18);
|
||||
|
||||
// multipolygon with empty polygons and non-empty (invalid) polygon
|
||||
// that has two non-empty interior rings but empty exterior ring
|
||||
test_envelope
|
||||
<
|
||||
bg::model::multi_polygon<bg::model::polygon<P> >
|
||||
>("MULTIPOLYGON(((),(),()),\
|
||||
((),(),(3 4,19 4,19 18,3 18,3 4),(4 5,18 5,18 17,4 17,4 5),()),\
|
||||
(()))",
|
||||
3, 19, 4, 18);
|
||||
}
|
||||
|
||||
int test_main(int, char* [])
|
||||
{
|
||||
@@ -71,6 +215,16 @@ int test_main(int, char* [])
|
||||
test_3d<test::test_point>();
|
||||
test_3d<boost::tuple<int, int, int> >();
|
||||
|
||||
test_empty<boost::tuple<float, float> >();
|
||||
test_empty<bg::model::d2::point_xy<int> >();
|
||||
test_empty<bg::model::d2::point_xy<float> >();
|
||||
test_empty<bg::model::d2::point_xy<double> >();
|
||||
|
||||
test_invalid<boost::tuple<float, float> >();
|
||||
test_invalid<bg::model::d2::point_xy<int> >();
|
||||
test_invalid<bg::model::d2::point_xy<float> >();
|
||||
test_invalid<bg::model::d2::point_xy<double> >();
|
||||
|
||||
#ifdef HAVE_TTMATH
|
||||
test_2d<bg::model::d2::point_xy<ttmath_big> >();
|
||||
test_3d<boost::tuple<ttmath_big, ttmath_big, ttmath_big> >();
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
#include <limits>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@@ -22,8 +23,10 @@
|
||||
#include <geometry_test_common.hpp>
|
||||
#include <from_wkt.hpp>
|
||||
|
||||
#include <boost/numeric/conversion/bounds.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
@@ -38,125 +41,53 @@
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
|
||||
|
||||
typedef bg::cs::spherical_equatorial<bg::radian> se_rad_type;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> se_deg_type;
|
||||
|
||||
typedef bg::model::point<double, 2, se_rad_type> rad_point_type;
|
||||
typedef bg::model::point<double, 2, se_deg_type> deg_point_type;
|
||||
|
||||
typedef bg::model::multi_point<rad_point_type> rad_multipoint_type;
|
||||
typedef bg::model::multi_point<deg_point_type> deg_multipoint_type;
|
||||
|
||||
typedef bg::model::segment<rad_point_type> rad_segment_type;
|
||||
typedef bg::model::segment<deg_point_type> deg_segment_type;
|
||||
|
||||
typedef bg::model::box<rad_point_type> rad_box_type;
|
||||
typedef bg::model::box<deg_point_type> deg_box_type;
|
||||
|
||||
typedef bg::model::linestring<rad_point_type> rad_linestring_type;
|
||||
typedef bg::model::linestring<deg_point_type> deg_linestring_type;
|
||||
|
||||
typedef bg::model::multi_linestring
|
||||
<
|
||||
rad_linestring_type
|
||||
> rad_multilinestring_type;
|
||||
|
||||
typedef bg::model::multi_linestring
|
||||
<
|
||||
deg_linestring_type
|
||||
> deg_multilinestring_type;
|
||||
|
||||
|
||||
typedef bg::model::ring<rad_point_type> rad_cw_ring_type;
|
||||
typedef bg::model::ring<deg_point_type> deg_cw_ring_type;
|
||||
|
||||
typedef bg::model::ring<rad_point_type, false> rad_ccw_ring_type;
|
||||
typedef bg::model::ring<deg_point_type, false> deg_ccw_ring_type;
|
||||
|
||||
|
||||
template <typename Units>
|
||||
char const* units2string()
|
||||
{
|
||||
if (BOOST_GEOMETRY_CONDITION((boost::is_same<Units, bg::degree>::value)))
|
||||
{
|
||||
return "degrees";
|
||||
}
|
||||
return "radians";
|
||||
}
|
||||
|
||||
template <typename Units>
|
||||
struct other_system_info
|
||||
{
|
||||
typedef bg::degree units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::r2d<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::degree>
|
||||
{
|
||||
typedef bg::radian units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::d2r<T>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class equals_with_tolerance
|
||||
{
|
||||
private:
|
||||
double m_tolerance;
|
||||
|
||||
template <typename T>
|
||||
static inline T const& get_max(T const& a, T const& b, T const& c)
|
||||
{
|
||||
return (std::max)((std::max)(a, b), c);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool check_close(T const& a, T const& b, double tol)
|
||||
{
|
||||
return (a == b)
|
||||
|| (std::abs(a - b) <= tol * get_max(std::abs(a), std::abs(b), 1.0));
|
||||
}
|
||||
|
||||
public:
|
||||
equals_with_tolerance(double tolerance) : m_tolerance(tolerance) {}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator()(T const& value1, T const& value2) const
|
||||
{
|
||||
return check_close(value1, value2, m_tolerance);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
inline bool box_equals(Box1 const& box1, Box2 const& box2, double tol)
|
||||
{
|
||||
equals_with_tolerance equals(tol);
|
||||
|
||||
return equals(bg::get<0, 0>(box1), bg::get<0, 0>(box2))
|
||||
&& equals(bg::get<0, 1>(box1), bg::get<0, 1>(box2))
|
||||
&& equals(bg::get<1, 0>(box1), bg::get<1, 0>(box2))
|
||||
&& equals(bg::get<1, 1>(box1), bg::get<1, 1>(box2));
|
||||
}
|
||||
#include "test_envelope_expand_on_spheroid.hpp"
|
||||
|
||||
|
||||
template <typename MBR>
|
||||
class envelope_on_spheroid_basic_tester
|
||||
{
|
||||
private:
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename bg::tag<Geometry>::type
|
||||
>
|
||||
struct write_geometry
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Geometry const& geometry)
|
||||
{
|
||||
os << bg::wkt(geometry);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment>
|
||||
struct write_geometry<Segment, bg::segment_tag>
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Segment const& segment)
|
||||
{
|
||||
os << "SEGMENT" << bg::dsv(segment);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct write_geometry<Box, bg::box_tag>
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Box const& box)
|
||||
{
|
||||
os << "BOX" << bg::dsv(box);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry, typename Box>
|
||||
static inline void check_message(bool same_boxes,
|
||||
std::string const& case_id,
|
||||
@@ -165,33 +96,12 @@ private:
|
||||
Box const& expected,
|
||||
Box const& detected)
|
||||
{
|
||||
bool const is_box = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::box_tag
|
||||
>::value;
|
||||
|
||||
bool const is_segment = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::segment_tag
|
||||
>::value;
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "case ID: " << case_id << ", "
|
||||
<< "MBR units: " << units_str << "; "
|
||||
<< "geometry: ";
|
||||
|
||||
if (BOOST_GEOMETRY_CONDITION(is_box))
|
||||
{
|
||||
stream << "BOX" << bg::dsv(geometry);
|
||||
}
|
||||
else if (BOOST_GEOMETRY_CONDITION(is_segment))
|
||||
{
|
||||
stream << "SEGMENT" << bg::dsv(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << bg::wkt(geometry);
|
||||
}
|
||||
write_geometry<Geometry>::apply(stream, geometry);
|
||||
|
||||
stream << "; " << "expected: " << bg::dsv(expected)
|
||||
<< ", " << "detected: " << bg::dsv(detected);
|
||||
@@ -202,8 +112,8 @@ private:
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void base_test(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min, double lat_min,
|
||||
double lon_max, double lat_max,
|
||||
double lon_min, double lat_min, double height_min,
|
||||
double lon_max, double lat_max, double height_max,
|
||||
double tolerance)
|
||||
{
|
||||
typedef typename bg::coordinate_system<Box>::type::units box_units_type;
|
||||
@@ -214,32 +124,13 @@ private:
|
||||
bg::envelope(geometry, detected);
|
||||
|
||||
Box expected;
|
||||
bg::assign_values(expected, lon_min, lat_min, lon_max, lat_max);
|
||||
initialize_box<Box>::apply(expected,
|
||||
lon_min, lat_min, height_min,
|
||||
lon_max, lat_max, height_max);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
bool const is_box = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::box_tag
|
||||
>::value;
|
||||
|
||||
bool const is_segment = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::segment_tag
|
||||
>::value;
|
||||
|
||||
std::cout << "geometry: ";
|
||||
if (BOOST_GEOMETRY_CONDITION(is_box))
|
||||
{
|
||||
std::cout << "BOX" << bg::dsv(geometry);
|
||||
}
|
||||
else if(BOOST_GEOMETRY_CONDITION(is_segment))
|
||||
{
|
||||
std::cout << "SEGMENT" << bg::dsv(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << bg::wkt(geometry);
|
||||
}
|
||||
write_geometry<Geometry>::apply(std::cout, geometry);
|
||||
|
||||
std::cout << std::endl
|
||||
<< "MBR units: " << units_str
|
||||
@@ -250,7 +141,7 @@ private:
|
||||
<< std::endl << std::endl;
|
||||
#endif
|
||||
|
||||
check_message(box_equals(detected, expected, tolerance),
|
||||
check_message(box_equals<Box>::apply(detected, expected, tolerance),
|
||||
case_id, units_str,
|
||||
geometry, expected, detected);
|
||||
}
|
||||
@@ -259,13 +150,13 @@ public:
|
||||
template <typename Geometry>
|
||||
static inline void apply(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min, double lat_min,
|
||||
double lon_max, double lat_max,
|
||||
double lon_min, double lat_min, double height_min,
|
||||
double lon_max, double lat_max, double height_max,
|
||||
double tolerance)
|
||||
{
|
||||
typedef other_system_info
|
||||
<
|
||||
typename bg::coordinate_system<MBR>::type::units
|
||||
typename bg::coordinate_system<MBR>::type
|
||||
> other;
|
||||
|
||||
typedef bg::model::box
|
||||
@@ -273,7 +164,7 @@ public:
|
||||
bg::model::point
|
||||
<
|
||||
typename bg::coordinate_type<MBR>::type,
|
||||
2,
|
||||
bg::dimension<MBR>::value,
|
||||
typename other::type
|
||||
>
|
||||
> other_mbr_type;
|
||||
@@ -284,15 +175,30 @@ public:
|
||||
#endif
|
||||
|
||||
base_test<MBR>(case_id, geometry,
|
||||
lon_min, lat_min, lon_max, lat_max,
|
||||
lon_min, lat_min, height_min,
|
||||
lon_max, lat_max, height_max,
|
||||
tolerance);
|
||||
|
||||
base_test<other_mbr_type>(case_id, geometry,
|
||||
other::convert(lon_min),
|
||||
other::convert(lat_min),
|
||||
other::convert(lon_max),
|
||||
other::convert(lat_max),
|
||||
tolerance);
|
||||
if (lon_max < lon_min)
|
||||
{
|
||||
// we are in the case were a special MBR is returned;
|
||||
// makes no sense to change units
|
||||
base_test<other_mbr_type>(case_id, geometry,
|
||||
lon_min, lat_min, height_min,
|
||||
lon_max, lat_max, height_max,
|
||||
tolerance);
|
||||
}
|
||||
else
|
||||
{
|
||||
base_test<other_mbr_type>(case_id, geometry,
|
||||
other::convert(lon_min),
|
||||
other::convert(lat_min),
|
||||
height_min,
|
||||
other::convert(lon_max),
|
||||
other::convert(lat_max),
|
||||
height_max,
|
||||
tolerance);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -331,17 +237,18 @@ struct test_envelope_on_spheroid
|
||||
{
|
||||
static inline void apply(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double lon_min1, double lat_min1, double height_min1,
|
||||
double lon_max1, double lat_max1, double height_max1,
|
||||
double lon_min2, double lat_min2, double height_min2,
|
||||
double lon_max2, double lat_max2, double height_max2,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
envelope_on_spheroid_basic_tester
|
||||
<
|
||||
MBR
|
||||
>::apply(case_id, geometry,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1,
|
||||
tolerance);
|
||||
|
||||
if (BOOST_GEOMETRY_CONDITION(TestReverse))
|
||||
@@ -354,7 +261,8 @@ struct test_envelope_on_spheroid
|
||||
<
|
||||
MBR
|
||||
>::apply(reversed_case_id, reversed_geometry,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2,
|
||||
lon_min2, lat_min2, height_min2,
|
||||
lon_max2, lat_max2, height_max2,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
@@ -364,6 +272,34 @@ struct test_envelope_on_spheroid
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void apply(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, geometry,
|
||||
lon_min1, lat_min1, 0, lon_max1, lat_max1, 0,
|
||||
lon_min2, lat_min2, 0, lon_max2, lat_max2, 0,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
static inline void apply(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min, double lat_min, double height_min,
|
||||
double lon_max, double lat_max, double height_max,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, geometry,
|
||||
lon_min, lat_min, height_min,
|
||||
lon_max, lat_max, height_max,
|
||||
lon_min, lat_min, height_min,
|
||||
lon_max, lat_max, height_max,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
static inline void apply(std::string const& case_id,
|
||||
Geometry const& geometry,
|
||||
double lon_min, double lat_min,
|
||||
@@ -371,8 +307,7 @@ struct test_envelope_on_spheroid
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, geometry,
|
||||
lon_min, lat_min, lon_max, lat_max,
|
||||
lon_min, lat_min, lon_max, lat_max,
|
||||
lon_min, lat_min, 0, lon_max, lat_max, 0,
|
||||
tolerance);
|
||||
}
|
||||
};
|
||||
@@ -399,7 +334,10 @@ struct test_envelope_on_spheroid<Geometry, MBR, bg::ring_tag, TestReverse>
|
||||
|
||||
std::string ccw_case_id = case_id + "-2ccw";
|
||||
|
||||
deg_ccw_ring_type ccw_ring;
|
||||
bg::model::ring
|
||||
<
|
||||
typename bg::point_type<Geometry>::type, false
|
||||
> ccw_ring;
|
||||
bg::convert(geometry, ccw_ring);
|
||||
|
||||
envelope_on_spheroid_basic_tester
|
||||
@@ -429,10 +367,41 @@ struct test_envelope_on_spheroid<Geometry, MBR, bg::ring_tag, TestReverse>
|
||||
};
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_point )
|
||||
template <typename CoordinateSystem, typename Geometry>
|
||||
void test_empty_geometry(std::string const& case_id, std::string const& wkt)
|
||||
{
|
||||
typedef deg_point_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
std::size_t const dim = bg::dimension<Geometry>::value;
|
||||
|
||||
typedef bg::model::point<double, dim, CoordinateSystem> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<Geometry, B> tester;
|
||||
|
||||
typedef typename bg::coordinate_type<Geometry>::type ct;
|
||||
ct high_val = boost::numeric::bounds<ct>::highest();
|
||||
ct low_val = boost::numeric::bounds<ct>::lowest();
|
||||
|
||||
if (BOOST_GEOMETRY_CONDITION(dim == 2))
|
||||
{
|
||||
tester::apply(case_id,
|
||||
from_wkt<Geometry>(wkt),
|
||||
high_val, high_val, low_val, low_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
tester::apply(case_id,
|
||||
from_wkt<Geometry>(wkt),
|
||||
high_val, high_val, high_val, low_val, low_val, low_val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_point()
|
||||
{
|
||||
typedef bg::model::point<double, 2, CoordinateSystem> point_type;
|
||||
typedef point_type G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("p01",
|
||||
from_wkt<G>("POINT(10 10)"),
|
||||
@@ -506,11 +475,43 @@ BOOST_AUTO_TEST_CASE( envelope_point )
|
||||
0, -90, 0, -90);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_point )
|
||||
{
|
||||
test_envelope_point<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_envelope_point<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_point_with_height()
|
||||
{
|
||||
typedef bg::model::point<double, 3, CoordinateSystem> point_type;
|
||||
typedef point_type G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("ph01",
|
||||
from_wkt<G>("POINT(10 10 1256)"),
|
||||
10, 10, 1256, 10, 10, 1256);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_point_with_height )
|
||||
{
|
||||
test_envelope_point_with_height
|
||||
<
|
||||
bg::cs::spherical_equatorial<bg::degree>
|
||||
>();
|
||||
test_envelope_point_with_height<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_segment )
|
||||
{
|
||||
typedef deg_segment_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 2, coordinate_system_type> point_type;
|
||||
typedef bg::model::segment<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("s01",
|
||||
from_wkt<G>("SEGMENT(10 10,40 40)"),
|
||||
@@ -661,10 +662,34 @@ BOOST_AUTO_TEST_CASE( envelope_segment )
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_multipoint )
|
||||
BOOST_AUTO_TEST_CASE( envelope_segment_with_height )
|
||||
{
|
||||
typedef deg_multipoint_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 3, coordinate_system_type> point_type;
|
||||
typedef bg::model::segment<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("sh01",
|
||||
from_wkt<G>("SEGMENT(10 10 567,40 40 1356)"),
|
||||
10, 10, 567, 40, 40, 1356);
|
||||
|
||||
tester::apply("sh02",
|
||||
from_wkt<G>("SEGMENT(10 10 1356,40 40 567)"),
|
||||
10, 10, 567, 40, 40, 1356);
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_multipoint()
|
||||
{
|
||||
typedef bg::model::point<double, 2, CoordinateSystem> point_type;
|
||||
typedef bg::model::multi_point<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
// empty multipoint
|
||||
test_empty_geometry<CoordinateSystem, G>("mp00", "MULTIPOINT()");
|
||||
|
||||
tester::apply("mp01",
|
||||
from_wkt<G>("MULTIPOINT(0 0,10 10)"),
|
||||
@@ -791,11 +816,51 @@ BOOST_AUTO_TEST_CASE( envelope_multipoint )
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_box )
|
||||
BOOST_AUTO_TEST_CASE( envelope_multipoint )
|
||||
{
|
||||
typedef deg_box_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
test_envelope_multipoint<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_envelope_multipoint<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_multipoint_with_height()
|
||||
{
|
||||
typedef bg::model::point<double, 3, CoordinateSystem> point_type;
|
||||
typedef bg::model::multi_point<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
// empty multipoint
|
||||
test_empty_geometry<CoordinateSystem, G>("mph00", "MULTIPOINT()");
|
||||
|
||||
tester::apply("mph01",
|
||||
from_wkt<G>("MULTIPOINT(0 0 567,10 10 1456)"),
|
||||
0, 0, 567, 10, 10, 1456);
|
||||
|
||||
tester::apply("mph02",
|
||||
from_wkt<G>("MULTIPOINT(0 0 567,10 10 1456,20 90 967)"),
|
||||
0, 0, 567, 10, 90, 1456);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_multipoint_with_height )
|
||||
{
|
||||
test_envelope_multipoint_with_height
|
||||
<
|
||||
bg::cs::spherical_equatorial<bg::degree>
|
||||
>();
|
||||
test_envelope_multipoint_with_height<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_box()
|
||||
{
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 2, coordinate_system_type> point_type;
|
||||
typedef bg::model::box<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("b01",
|
||||
from_wkt<G>("BOX(10 10,20 20)"),
|
||||
@@ -976,11 +1041,52 @@ BOOST_AUTO_TEST_CASE( envelope_box )
|
||||
0, -90, 0, -90);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_box )
|
||||
{
|
||||
test_envelope_box<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_envelope_box<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_envelope_box_with_height()
|
||||
{
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 3, coordinate_system_type> point_type;
|
||||
typedef bg::model::box<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("bh01",
|
||||
from_wkt<G>("BOX(10 10 567,20 20 2834)"),
|
||||
10, 10, 567, 20, 20, 2834);
|
||||
|
||||
tester::apply("bh02",
|
||||
from_wkt<G>("BOX(10 10 567,20 20 567)"),
|
||||
10, 10, 567, 20, 20, 567);
|
||||
|
||||
tester::apply("bh03",
|
||||
from_wkt<G>("BOX(0 10 567,170 90 1567)"),
|
||||
0, 10, 567, 170, 90, 1567);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_box_with_height )
|
||||
{
|
||||
test_envelope_box_with_height<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_envelope_box_with_height<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_linestring )
|
||||
{
|
||||
typedef deg_linestring_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 2, coordinate_system_type> point_type;
|
||||
typedef bg::model::linestring<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
// empty linestring
|
||||
test_empty_geometry<coordinate_system_type, G>("l00", "LINESTRING()");
|
||||
|
||||
tester::apply("l01",
|
||||
from_wkt<G>("LINESTRING(10 15)"),
|
||||
@@ -1086,14 +1192,61 @@ BOOST_AUTO_TEST_CASE( envelope_linestring )
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_linestring_with_height )
|
||||
{
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 3, coordinate_system_type> point_type;
|
||||
typedef bg::model::linestring<point_type> G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
// empty linestring
|
||||
test_empty_geometry<coordinate_system_type, G>("lh00", "LINESTRING()");
|
||||
|
||||
tester::apply("lh01",
|
||||
from_wkt<G>("LINESTRING(10 15 30,20 25 434,30 35 186)"),
|
||||
10, 15, 30, 30, 35, 434);
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_multilinestring )
|
||||
{
|
||||
typedef deg_multilinestring_type G;
|
||||
typedef test_envelope_on_spheroid<G, deg_box_type> tester;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 2, coordinate_system_type> point_type;
|
||||
typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
// empty multilinestring
|
||||
test_empty_geometry<coordinate_system_type, G>("ml00", "MULTILINESTRING()");
|
||||
|
||||
// invalid multilinestring
|
||||
test_empty_geometry<coordinate_system_type, G>("ml00a",
|
||||
"MULTILINESTRING(())");
|
||||
|
||||
// invalid multilinestring
|
||||
test_empty_geometry<coordinate_system_type, G>("ml00b",
|
||||
"MULTILINESTRING((),())");
|
||||
|
||||
// invalid multilinestring
|
||||
tester::apply("ml00c",
|
||||
from_wkt<G>("MULTILINESTRING((10 15),(),())"),
|
||||
10, 15, 10, 15);
|
||||
|
||||
// invalid multilinestring
|
||||
tester::apply("ml00d",
|
||||
from_wkt<G>("MULTILINESTRING((),(10 15),())"),
|
||||
10, 15, 10, 15);
|
||||
|
||||
tester::apply("ml01",
|
||||
from_wkt<G>("MULTILINESTRING((10 15))"),
|
||||
10, 15, 10, 15);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
|
||||
tester::apply("ml01a",
|
||||
from_wkt<G>("MULTILINESTRING((),(),(10 15),())"),
|
||||
10, 15, 10, 15);
|
||||
#endif // BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
|
||||
|
||||
tester::apply("ml02",
|
||||
from_wkt<G>("MULTILINESTRING((-170 40,-100 80,10 40),(-10 25,10 35,100 45),(50 30,150 45,-160 30))"),
|
||||
@@ -1121,6 +1274,30 @@ BOOST_AUTO_TEST_CASE( envelope_multilinestring )
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( envelope_multilinestring_with_height )
|
||||
{
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 3, coordinate_system_type> point_type;
|
||||
typedef bg::model::multi_linestring<bg::model::linestring<point_type> > G;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef test_envelope_on_spheroid<G, B> tester;
|
||||
|
||||
tester::apply("mlh01",
|
||||
from_wkt<G>("MULTILINESTRING((10 15 1000))"),
|
||||
10, 15, 1000, 10, 15, 1000);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
|
||||
tester::apply("mlh01a",
|
||||
from_wkt<G>("MULTILINESTRING((),(),(10 15 1000),())"),
|
||||
10, 15, 1000, 10, 15, 1000);
|
||||
#endif // BOOST_GEOMETRY_INCLUDE_FAILING_TESTS
|
||||
|
||||
tester::apply("mlh02",
|
||||
from_wkt<G>("MULTILINESTRING((-170 40 400,-100 80 300),(-10 25 600,10 35 700,120 45 450))"),
|
||||
-10, 25, 300, 260, 80, 700);
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// unit test for rings de-activated for now (current implementation
|
||||
// for area on the spherical equatorial coordinate system is not complete)
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
|
||||
#ifndef BOOST_TEST_MODULE
|
||||
#define BOOST_TEST_MODULE test_expand_on_spheroid
|
||||
#endif
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
@@ -23,112 +24,70 @@
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/tag.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/geometries.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
|
||||
#include <boost/geometry/io/dsv/write.hpp>
|
||||
#include <boost/geometry/io/wkt/wkt.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
#include <boost/geometry/algorithms/expand.hpp>
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
|
||||
typedef bg::cs::spherical_equatorial<bg::radian> se_rad_type;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> se_deg_type;
|
||||
|
||||
typedef bg::model::point<double, 2, se_rad_type> rad_point_type;
|
||||
typedef bg::model::point<double, 2, se_deg_type> deg_point_type;
|
||||
|
||||
typedef bg::model::segment<rad_point_type> rad_segment_type;
|
||||
typedef bg::model::segment<deg_point_type> deg_segment_type;
|
||||
|
||||
typedef bg::model::box<rad_point_type> rad_box_type;
|
||||
typedef bg::model::box<deg_point_type> deg_box_type;
|
||||
|
||||
|
||||
template <typename Units>
|
||||
char const* units2string()
|
||||
{
|
||||
if (BOOST_GEOMETRY_CONDITION((boost::is_same<Units, bg::degree>::value)))
|
||||
{
|
||||
return "degrees";
|
||||
}
|
||||
return "radians";
|
||||
}
|
||||
|
||||
template <typename Units>
|
||||
struct other_system_info
|
||||
{
|
||||
typedef bg::degree units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::r2d<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::degree>
|
||||
{
|
||||
typedef bg::radian units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::d2r<T>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class equals_with_tolerance
|
||||
{
|
||||
private:
|
||||
double m_tolerence;
|
||||
|
||||
template <typename T>
|
||||
static inline T const& get_max(T const& a, T const& b, T const& c)
|
||||
{
|
||||
return (std::max)((std::max)(a, b), c);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool check_close(T const& a, T const& b, double tol)
|
||||
{
|
||||
return (a == b)
|
||||
|| (std::abs(a - b) <= tol * get_max(std::abs(a), std::abs(b), 1.0));
|
||||
}
|
||||
|
||||
public:
|
||||
equals_with_tolerance(double tolerence) : m_tolerence(tolerence) {}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator()(T const& value1, T const& value2) const
|
||||
{
|
||||
return check_close(value1, value2, m_tolerence);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
inline bool box_equals(Box1 const& box1, Box2 const& box2, double tol)
|
||||
{
|
||||
equals_with_tolerance equals(tol);
|
||||
|
||||
return equals(bg::get<0, 0>(box1), bg::get<0, 0>(box2))
|
||||
&& equals(bg::get<0, 1>(box1), bg::get<0, 1>(box2))
|
||||
&& equals(bg::get<1, 0>(box1), bg::get<1, 0>(box2))
|
||||
&& equals(bg::get<1, 1>(box1), bg::get<1, 1>(box2));
|
||||
}
|
||||
#include "test_envelope_expand_on_spheroid.hpp"
|
||||
|
||||
|
||||
class test_expand_on_spheroid
|
||||
{
|
||||
private:
|
||||
template
|
||||
<
|
||||
typename Geometry,
|
||||
typename Tag = typename bg::tag<Geometry>::type
|
||||
>
|
||||
struct write_geometry
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Geometry const& geometry)
|
||||
{
|
||||
os << bg::wkt(geometry);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Segment>
|
||||
struct write_geometry<Segment, bg::segment_tag>
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Segment const& segment)
|
||||
{
|
||||
os << "SEGMENT" << bg::dsv(segment);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct write_geometry<Box, bg::box_tag>
|
||||
{
|
||||
template <typename OutputStream>
|
||||
static inline OutputStream& apply(OutputStream& os,
|
||||
Box const& box)
|
||||
{
|
||||
os << "BOX" << bg::dsv(box);
|
||||
return os;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void check_message(bool same_boxes,
|
||||
std::string const& case_id,
|
||||
@@ -140,34 +99,13 @@ private:
|
||||
Box const& expected2,
|
||||
Box const& detected)
|
||||
{
|
||||
bool const is_box = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::box_tag
|
||||
>::value;
|
||||
|
||||
bool const is_segment = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::segment_tag
|
||||
>::value;
|
||||
|
||||
std::ostringstream stream;
|
||||
stream << "case ID: " << case_id << ", "
|
||||
<< "MBR units: " << units_str << "; "
|
||||
<< "input box: BOX" << bg::dsv(box) << ", "
|
||||
<< "geometry: ";
|
||||
|
||||
if (BOOST_GEOMETRY_CONDITION(is_box))
|
||||
{
|
||||
stream << "BOX" << bg::dsv(geometry);
|
||||
}
|
||||
else if (BOOST_GEOMETRY_CONDITION(is_segment))
|
||||
{
|
||||
stream << "SEGMENT" << bg::dsv(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
stream << bg::wkt(geometry);
|
||||
}
|
||||
write_geometry<Geometry>::apply(stream, geometry);
|
||||
stream << "; " << "expected: " << bg::dsv(expected1);
|
||||
|
||||
if (expected_are_different)
|
||||
@@ -188,9 +126,13 @@ private:
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double height_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double height_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double height_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double height_max2,
|
||||
double tolerance)
|
||||
{
|
||||
typedef typename bg::coordinate_system
|
||||
@@ -209,39 +151,20 @@ private:
|
||||
|| (lon_max1 != lon_max2) || (lat_max1 != lat_max2);
|
||||
|
||||
Box expected1;
|
||||
bg::assign_values(expected1,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1);
|
||||
initialize_box<Box>::apply(expected1,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1);
|
||||
|
||||
Box expected2;
|
||||
bg::assign_values(expected2,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2);
|
||||
initialize_box<Box>::apply(expected2,
|
||||
lon_min2, lat_min2, height_min2,
|
||||
lon_max2, lat_max2, height_max2);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
bool const is_box = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::box_tag
|
||||
>::value;
|
||||
|
||||
bool const is_segment = boost::is_same
|
||||
<
|
||||
typename bg::tag<Geometry>::type, bg::segment_tag
|
||||
>::value;
|
||||
|
||||
std::cout << "input box: BOX" << bg::dsv(box) << std::endl;
|
||||
|
||||
std::cout << "geometry: ";
|
||||
if (BOOST_GEOMETRY_CONDITION(is_box))
|
||||
{
|
||||
std::cout << "BOX" << bg::dsv(geometry);
|
||||
}
|
||||
else if(BOOST_GEOMETRY_CONDITION(is_segment))
|
||||
{
|
||||
std::cout << "SEGMENT" << bg::dsv(geometry);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << bg::wkt(geometry);
|
||||
}
|
||||
write_geometry<Geometry>::apply(std::cout, geometry);
|
||||
|
||||
std::cout << std::endl
|
||||
<< "MBR units: " << units_str
|
||||
@@ -257,11 +180,13 @@ private:
|
||||
<< "detected: " << bg::dsv(detected)
|
||||
<< std::endl << std::endl;
|
||||
#endif
|
||||
bool same_boxes = box_equals(detected, expected1, tolerance);
|
||||
bool same_boxes
|
||||
= box_equals<Box>::apply(detected, expected1, tolerance);
|
||||
|
||||
if (expected_are_different)
|
||||
{
|
||||
same_boxes = same_boxes
|
||||
|| box_equals(detected, expected2, tolerance);
|
||||
|| box_equals<Box>::apply(detected, expected2, tolerance);
|
||||
}
|
||||
|
||||
check_message(same_boxes, case_id, units_str,
|
||||
@@ -274,14 +199,18 @@ private:
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double height_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double height_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double height_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double height_max2,
|
||||
double tolerance)
|
||||
{
|
||||
typedef other_system_info
|
||||
<
|
||||
typename bg::coordinate_system<Box>::type::units
|
||||
typename bg::coordinate_system<Box>::type
|
||||
> other;
|
||||
|
||||
typedef bg::model::box
|
||||
@@ -289,7 +218,7 @@ private:
|
||||
bg::model::point
|
||||
<
|
||||
typename bg::coordinate_type<Box>::type,
|
||||
2,
|
||||
bg::dimension<Box>::value,
|
||||
typename other::type
|
||||
>
|
||||
> other_mbr_type;
|
||||
@@ -300,26 +229,41 @@ private:
|
||||
#endif
|
||||
|
||||
base_test(case_id, box, geometry,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1,
|
||||
lon_min2, lat_min2, height_min2,
|
||||
lon_max2, lat_max2, height_max2,
|
||||
tolerance);
|
||||
|
||||
other_mbr_type other_box;
|
||||
bg::assign_values(other_box,
|
||||
other::convert(bg::get<0, 0>(box)),
|
||||
other::convert(bg::get<0, 1>(box)),
|
||||
other::convert(bg::get<1, 0>(box)),
|
||||
other::convert(bg::get<1, 1>(box)));
|
||||
bg::detail::indexed_point_view<Box const, 0> p_min(box);
|
||||
bg::detail::indexed_point_view<Box const, 1> p_max(box);
|
||||
bg::detail::indexed_point_view
|
||||
<
|
||||
other_mbr_type, 0
|
||||
> other_min(other_box);
|
||||
|
||||
bg::detail::indexed_point_view
|
||||
<
|
||||
other_mbr_type, 1
|
||||
> other_max(other_box);
|
||||
|
||||
bg::transform(p_min, other_min);
|
||||
bg::transform(p_max, other_max);
|
||||
|
||||
base_test(case_id, other_box, geometry,
|
||||
other::convert(lon_min1),
|
||||
other::convert(lat_min1),
|
||||
height_min1,
|
||||
other::convert(lon_max1),
|
||||
other::convert(lat_max1),
|
||||
height_max1,
|
||||
other::convert(lon_min2),
|
||||
other::convert(lat_min2),
|
||||
height_min2,
|
||||
other::convert(lon_max2),
|
||||
other::convert(lat_max2),
|
||||
height_max2,
|
||||
tolerance);
|
||||
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
@@ -337,17 +281,23 @@ private:
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double height_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double height_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double height_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double height_max2,
|
||||
double tolerance)
|
||||
{
|
||||
basic_tester
|
||||
<
|
||||
false
|
||||
>::apply(case_id, box, geometry,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1,
|
||||
lon_min2, lat_min2, height_min1,
|
||||
lon_max2, lat_max2, height_max2,
|
||||
tolerance);
|
||||
|
||||
std::string case_id_r = case_id + "[R]";
|
||||
@@ -356,8 +306,10 @@ private:
|
||||
<
|
||||
false
|
||||
>::apply(case_id_r, geometry, box,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1,
|
||||
lon_min2, lat_min2, height_min2,
|
||||
lon_max2, lat_max2, height_max2,
|
||||
tolerance);
|
||||
}
|
||||
};
|
||||
@@ -368,10 +320,10 @@ public:
|
||||
static inline void apply(std::string const& case_id,
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double lon_min1, double lat_min1, double height_min1,
|
||||
double lon_max1, double lat_max1, double height_max1,
|
||||
double lon_min2, double lat_min2, double height_min2,
|
||||
double lon_max2, double lat_max2, double height_max2,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
|
||||
@@ -383,11 +335,29 @@ public:
|
||||
bg::box_tag
|
||||
>::value
|
||||
>::apply(case_id, box, geometry,
|
||||
lon_min1, lat_min1, lon_max1, lat_max1,
|
||||
lon_min2, lat_min2, lon_max2, lat_max2,
|
||||
lon_min1, lat_min1, height_min1,
|
||||
lon_max1, lat_max1, height_max1,
|
||||
lon_min2, lat_min2, height_min2,
|
||||
lon_max2, lat_max2, height_max2,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(std::string const& case_id,
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min1, double lat_min1,
|
||||
double lon_max1, double lat_max1,
|
||||
double lon_min2, double lat_min2,
|
||||
double lon_max2, double lat_max2,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, box, geometry,
|
||||
lon_min1, lat_min1, 0, lon_max1, lat_max1, 0,
|
||||
lon_min2, lat_min2, 0, lon_max2, lat_max2, 0,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(std::string const& case_id,
|
||||
Box const& box,
|
||||
@@ -397,17 +367,33 @@ public:
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, box, geometry,
|
||||
lon_min, lat_min, lon_max, lat_max,
|
||||
lon_min, lat_min, lon_max, lat_max,
|
||||
lon_min, lat_min, 0, lon_max, lat_max, 0,
|
||||
lon_min, lat_min, 0, lon_max, lat_max, 0,
|
||||
tolerance);
|
||||
}
|
||||
|
||||
template <typename Box, typename Geometry>
|
||||
static inline void apply(std::string const& case_id,
|
||||
Box const& box,
|
||||
Geometry const& geometry,
|
||||
double lon_min, double lat_min, double height_min,
|
||||
double lon_max, double lat_max, double height_max,
|
||||
double tolerance = std::numeric_limits<double>::epsilon())
|
||||
{
|
||||
apply(case_id, box, geometry,
|
||||
lon_min, lat_min, height_min, lon_max, lat_max, height_max,
|
||||
lon_min, lat_min, height_min, lon_max, lat_max, height_max,
|
||||
tolerance);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_point )
|
||||
template <typename CoordinateSystem>
|
||||
void test_expand_point()
|
||||
{
|
||||
typedef deg_box_type B;
|
||||
typedef deg_point_type G;
|
||||
typedef bg::model::point<double, 2, CoordinateSystem> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef point_type G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
tester::apply("p01",
|
||||
@@ -596,11 +582,51 @@ BOOST_AUTO_TEST_CASE( expand_point )
|
||||
10, -90, 100, 90);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_point )
|
||||
{
|
||||
test_expand_point<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_expand_point<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_expand_point_with_height()
|
||||
{
|
||||
typedef bg::model::point<double, 3, CoordinateSystem> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef point_type G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
// deactivate this for now
|
||||
tester::apply("ph01",
|
||||
from_wkt<B>("BOX(0 0 20,5 5 100)"),
|
||||
from_wkt<G>("POINT(10 10 80)"),
|
||||
0, 0, 20, 10, 10, 100);
|
||||
|
||||
tester::apply("ph02",
|
||||
from_wkt<B>("BOX(0 0 20,5 5 100)"),
|
||||
from_wkt<G>("POINT(10 10 120)"),
|
||||
0, 0, 20, 10, 10, 120);
|
||||
|
||||
tester::apply("ph03",
|
||||
from_wkt<B>("BOX(0 0 20,5 5 100)"),
|
||||
from_wkt<G>("POINT(10 10 5)"),
|
||||
0, 0, 5, 10, 10, 100);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_point_with_height )
|
||||
{
|
||||
test_expand_point_with_height<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_expand_point_with_height<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_segment )
|
||||
{
|
||||
typedef deg_box_type B;
|
||||
typedef deg_segment_type G;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 2, coordinate_system_type> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef bg::model::segment<point_type> G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
tester::apply("s01",
|
||||
@@ -675,10 +701,42 @@ BOOST_AUTO_TEST_CASE( expand_segment )
|
||||
}
|
||||
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_box )
|
||||
BOOST_AUTO_TEST_CASE( expand_segment_with_height )
|
||||
{
|
||||
typedef deg_box_type B;
|
||||
typedef deg_box_type G;
|
||||
typedef bg::cs::spherical_equatorial<bg::degree> coordinate_system_type;
|
||||
typedef bg::model::point<double, 3, coordinate_system_type> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef bg::model::segment<point_type> G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
tester::apply("sh01",
|
||||
from_wkt<B>("BOX(20 20 100,50 50 1000)"),
|
||||
from_wkt<G>("SEGMENT(10 10 150,40 40 500)"),
|
||||
10, 10, 100, 50, 50, 1000);
|
||||
|
||||
tester::apply("sh02",
|
||||
from_wkt<B>("BOX(20 20 100,50 50 1000)"),
|
||||
from_wkt<G>("SEGMENT(10 10 60,40 40 1500)"),
|
||||
10, 10, 60, 50, 50, 1500);
|
||||
|
||||
tester::apply("sh03",
|
||||
from_wkt<B>("BOX(20 20 100,50 50 1000)"),
|
||||
from_wkt<G>("SEGMENT(10 10 150,40 40 1500)"),
|
||||
10, 10, 100, 50, 50, 1500);
|
||||
|
||||
tester::apply("sh04",
|
||||
from_wkt<B>("BOX(20 20 100,50 50 1000)"),
|
||||
from_wkt<G>("SEGMENT(10 10 60,40 40 800)"),
|
||||
10, 10, 60, 50, 50, 1000);
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_expand_box()
|
||||
{
|
||||
typedef bg::model::point<double, 2, CoordinateSystem> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef bg::model::box<point_type> G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
tester::apply("b01",
|
||||
@@ -846,3 +904,45 @@ BOOST_AUTO_TEST_CASE( expand_box )
|
||||
from_wkt<G>("BOX(0 -10,185 50)"),
|
||||
-180, -40, 180, 50);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_box )
|
||||
{
|
||||
test_expand_box<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_expand_box<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
void test_expand_box_with_height()
|
||||
{
|
||||
typedef bg::model::point<double, 3, CoordinateSystem> point_type;
|
||||
typedef bg::model::box<point_type> B;
|
||||
typedef bg::model::box<point_type> G;
|
||||
typedef test_expand_on_spheroid tester;
|
||||
|
||||
tester::apply("bh01",
|
||||
from_wkt<B>("BOX(11 11 100,19 19 1000)"),
|
||||
from_wkt<G>("BOX(10 10 200,20 20 800)"),
|
||||
10, 10, 100, 20, 20, 1000);
|
||||
|
||||
tester::apply("bh02",
|
||||
from_wkt<B>("BOX(11 11 200,19 19 1000)"),
|
||||
from_wkt<G>("BOX(10 10 100,20 20 800)"),
|
||||
10, 10, 100, 20, 20, 1000);
|
||||
|
||||
tester::apply("bh03",
|
||||
from_wkt<B>("BOX(11 11 100,19 19 800)"),
|
||||
from_wkt<G>("BOX(10 10 200,20 20 1000)"),
|
||||
10, 10, 100, 20, 20, 1000);
|
||||
|
||||
tester::apply("bh04",
|
||||
from_wkt<B>("BOX(11 11 200,19 19 1000)"),
|
||||
from_wkt<G>("BOX(10 10 100,20 20 800)"),
|
||||
10, 10, 100, 20, 20, 1000);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( expand_box_with_height )
|
||||
{
|
||||
test_expand_box_with_height<bg::cs::spherical_equatorial<bg::degree> >();
|
||||
test_expand_box_with_height<bg::cs::geographic<bg::degree> >();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <boost/geometry/io/wkt/wkt.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/is_valid.hpp>
|
||||
#include <boost/geometry/algorithms/is_simple.hpp>
|
||||
|
||||
@@ -296,6 +297,27 @@ BOOST_AUTO_TEST_CASE( test_is_simple_areal )
|
||||
false);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
std::cout << " is_valid: geometry with NaN coordinates" << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
#endif
|
||||
|
||||
linestring_type ls1, ls2;
|
||||
bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1);
|
||||
bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2);
|
||||
|
||||
// the intersection of the two linestrings is a new linestring
|
||||
// (multilinestring with a single element) that has NaN coordinates
|
||||
multi_linestring_type mls;
|
||||
bg::intersection(ls1, ls2, mls);
|
||||
|
||||
test_simple(mls, true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_simple_variant )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "test_is_valid.hpp"
|
||||
|
||||
#include <boost/geometry/algorithms/correct.hpp>
|
||||
#include <boost/geometry/algorithms/intersection.hpp>
|
||||
#include <boost/geometry/algorithms/reverse.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_valid_point )
|
||||
@@ -1114,6 +1115,38 @@ BOOST_AUTO_TEST_CASE( test_is_valid_multipolygon )
|
||||
test_open_multipolygons<point_type, do_not_allow_duplicates>();
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_geometry_with_NaN_coordinates )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
std::cout << std::endl << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
std::cout << " is_valid: geometry with NaN coordinates" << std::endl;
|
||||
std::cout << "************************************" << std::endl;
|
||||
#endif
|
||||
|
||||
linestring_type ls1, ls2;
|
||||
bg::read_wkt("LINESTRING(1 1,1.115235e+308 1.738137e+308)", ls1);
|
||||
bg::read_wkt("LINESTRING(-1 1,1.115235e+308 1.738137e+308)", ls2);
|
||||
|
||||
// the intersection of the two linestrings is a new linestring
|
||||
// (multilinestring with a single element) that has NaN coordinates
|
||||
multi_linestring_type mls;
|
||||
bg::intersection(ls1, ls2, mls);
|
||||
|
||||
typedef validity_tester_linear<true> tester_allow_spikes;
|
||||
typedef validity_tester_linear<false> tester_disallow_spikes;
|
||||
|
||||
test_valid
|
||||
<
|
||||
tester_allow_spikes, multi_linestring_type
|
||||
>::apply("mls-NaN", mls, true);
|
||||
|
||||
test_valid
|
||||
<
|
||||
tester_disallow_spikes, multi_linestring_type
|
||||
>::apply("mls-NaN", mls, true);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( test_is_valid_variant )
|
||||
{
|
||||
#ifdef BOOST_GEOMETRY_TEST_DEBUG
|
||||
|
||||
192
test/algorithms/test_envelope_expand_on_spheroid.hpp
Normal file
192
test/algorithms/test_envelope_expand_on_spheroid.hpp
Normal file
@@ -0,0 +1,192 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
// Unit Test
|
||||
|
||||
// Copyright (c) 2015, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
|
||||
// Licensed under the Boost Software License version 1.0.
|
||||
// http://www.boost.org/users/license.html
|
||||
|
||||
#ifndef BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
|
||||
#define BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/cs.hpp>
|
||||
|
||||
#include <boost/geometry/util/condition.hpp>
|
||||
#include <boost/geometry/util/math.hpp>
|
||||
|
||||
#include <boost/geometry/views/detail/indexed_point_view.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/assign.hpp>
|
||||
|
||||
|
||||
template <typename Units>
|
||||
char const* units2string()
|
||||
{
|
||||
if (BOOST_GEOMETRY_CONDITION((boost::is_same<Units, bg::degree>::value)))
|
||||
{
|
||||
return "degrees";
|
||||
}
|
||||
return "radians";
|
||||
}
|
||||
|
||||
template <typename CoordinateSystem>
|
||||
struct other_system_info
|
||||
{};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::cs::spherical_equatorial<bg::radian> >
|
||||
{
|
||||
typedef bg::degree units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::r2d<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::cs::spherical_equatorial<bg::degree> >
|
||||
{
|
||||
typedef bg::radian units;
|
||||
typedef bg::cs::spherical_equatorial<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::d2r<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::cs::geographic<bg::radian> >
|
||||
{
|
||||
typedef bg::degree units;
|
||||
typedef bg::cs::geographic<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::r2d<T>();
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct other_system_info<bg::cs::geographic<bg::degree> >
|
||||
{
|
||||
typedef bg::radian units;
|
||||
typedef bg::cs::geographic<units> type;
|
||||
|
||||
template <typename T>
|
||||
static inline T convert(T const& value)
|
||||
{
|
||||
return value * bg::math::d2r<T>();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class equals_with_tolerance
|
||||
{
|
||||
private:
|
||||
double m_tolerence;
|
||||
|
||||
template <typename T>
|
||||
static inline T const& get_max(T const& a, T const& b, T const& c)
|
||||
{
|
||||
return (std::max)((std::max)(a, b), c);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline bool check_close(T const& a, T const& b, double tol)
|
||||
{
|
||||
return (a == b)
|
||||
|| (std::abs(a - b) <= tol * get_max(std::abs(a), std::abs(b), 1.0));
|
||||
}
|
||||
|
||||
public:
|
||||
equals_with_tolerance(double tolerence) : m_tolerence(tolerence) {}
|
||||
|
||||
template <typename T>
|
||||
inline bool operator()(T const& value1, T const& value2) const
|
||||
{
|
||||
return check_close(value1, value2, m_tolerence);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1,
|
||||
typename Box2 = Box1,
|
||||
std::size_t DimensionCount = bg::dimension<Box1>::value
|
||||
>
|
||||
struct box_equals
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, double tol)
|
||||
{
|
||||
equals_with_tolerance equals(tol);
|
||||
|
||||
return equals(bg::get<0, 0>(box1), bg::get<0, 0>(box2))
|
||||
&& equals(bg::get<0, 1>(box1), bg::get<0, 1>(box2))
|
||||
&& equals(bg::get<1, 0>(box1), bg::get<1, 0>(box2))
|
||||
&& equals(bg::get<1, 1>(box1), bg::get<1, 1>(box2));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box1, typename Box2>
|
||||
struct box_equals<Box1, Box2, 3>
|
||||
{
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, double tol)
|
||||
{
|
||||
equals_with_tolerance equals(tol);
|
||||
|
||||
return box_equals<Box1, Box2, 2>::apply(box1, box2, tol)
|
||||
&& equals(bg::get<0, 2>(box1), bg::get<0, 2>(box2))
|
||||
&& equals(bg::get<1, 2>(box1), bg::get<1, 2>(box2));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box, std::size_t Dimension = bg::dimension<Box>::value>
|
||||
struct initialize_box
|
||||
{
|
||||
static inline void apply(Box& box,
|
||||
double lon_min, double lat_min, double,
|
||||
double lon_max, double lat_max, double)
|
||||
{
|
||||
bg::detail::indexed_point_view<Box, bg::min_corner> p_min(box);
|
||||
bg::detail::indexed_point_view<Box, bg::max_corner> p_max(box);
|
||||
|
||||
bg::assign_values(p_min, lon_min, lat_min);
|
||||
bg::assign_values(p_max, lon_max, lat_max);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Box>
|
||||
struct initialize_box<Box, 3>
|
||||
{
|
||||
static inline void apply(Box& box,
|
||||
double lon_min, double lat_min, double height_min,
|
||||
double lon_max, double lat_max, double height_max)
|
||||
{
|
||||
bg::detail::indexed_point_view<Box, bg::min_corner> p_min(box);
|
||||
bg::detail::indexed_point_view<Box, bg::max_corner> p_max(box);
|
||||
|
||||
bg::assign_values(p_min, lon_min, lat_min, height_min);
|
||||
bg::assign_values(p_max, lon_max, lat_max, height_max);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // BOOST_GEOMETRY_TEST_ENVELOPE_EXPAND_ON_SPHEROID_HPP
|
||||
Reference in New Issue
Block a user