[disjoint] Support non-cartesian CSes for Pt/Box and Box/Box.

For Point/Box use part of the implementation of point_in_box covered_by
strategy.
This commit is contained in:
Adam Wulkiewicz
2016-03-09 04:25:02 +01:00
parent 8f14bf15c0
commit 4444357697
2 changed files with 88 additions and 51 deletions

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -28,6 +28,9 @@
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
@@ -39,7 +42,13 @@ namespace detail { namespace disjoint
template
<
typename Box1, typename Box2,
std::size_t Dimension, std::size_t DimensionCount
std::size_t Dimension = 0,
std::size_t DimensionCount = dimension<Box1>::value,
typename CSTag = typename tag_cast
<
typename cs_tag<Box1>::type,
spherical_tag
>::type
>
struct box_box
{
@@ -62,8 +71,8 @@ struct box_box
};
template <typename Box1, typename Box2, std::size_t DimensionCount>
struct box_box<Box1, Box2, DimensionCount, DimensionCount>
template <typename Box1, typename Box2, std::size_t DimensionCount, typename CSTag>
struct box_box<Box1, Box2, DimensionCount, DimensionCount, CSTag>
{
static inline bool apply(Box1 const& , Box2 const& )
{
@@ -72,6 +81,57 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount>
};
template <typename Box1, typename Box2, std::size_t DimensionCount>
struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag>
{
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
typedef typename geometry::select_most_precise
<
typename coordinate_type<Box1>::type,
typename coordinate_type<Box2>::type
>::type calc_t;
typedef typename coordinate_system<Box1>::type::units units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
calc_t const b1_min = get<min_corner, 0>(box1);
calc_t const b1_max = get<max_corner, 0>(box1);
calc_t const b2_min = get<min_corner, 0>(box2);
calc_t const b2_max = get<max_corner, 0>(box2);
// min <= max <=> diff >= 0
calc_t const diff1 = b1_max - b1_min;
calc_t const diff2 = b2_max - b2_min;
// check the intersection if neither box cover the whole globe
if (math::smaller(diff1, constants::period())
&& math::smaller(diff2, constants::period()) ) // < period
{
// calculate positive longitude translation with b1_min as origin
calc_t const c0 = 0;
calc_t diff_min = b2_min - b1_min;
math::normalize_longitude<units_t, calc_t>(diff_min);
if (diff_min < c0) // [-180, 180] -> [0, 360]
diff_min += constants::period();
calc_t const b2_min_transl = b1_min + diff_min; // always right of b1_min
if (b2_min_transl > b1_max // b2_min right of b1_max
&& b2_min_transl - constants::period() + diff2 < b1_min) // b2_max left of b1_min
{
return true;
}
}
return box_box
<
Box1, Box2,
1, DimensionCount
>::apply(box1, box2);
}
};
/*!
\brief Internal utility function to detect if boxes are disjoint
\note Is used from other algorithms, declared separately
@@ -80,11 +140,7 @@ struct box_box<Box1, Box2, DimensionCount, DimensionCount>
template <typename Box1, typename Box2>
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
{
return box_box
<
Box1, Box2,
0, dimension<Box1>::type::value
>::apply(box1, box2);
return box_box<Box1, Box2>::apply(box1, box2);
}

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// This file was modified by Oracle on 2013-2015.
// Modifications copyright (c) 2013-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -28,6 +28,7 @@
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
namespace boost { namespace geometry
{
@@ -37,49 +38,19 @@ namespace detail { namespace disjoint
{
template
<
typename Point, typename Box,
std::size_t Dimension, std::size_t DimensionCount
>
struct point_box
{
static inline bool apply(Point const& point, Box const& box)
{
if (get<Dimension>(point) < get<min_corner, Dimension>(box)
|| get<Dimension>(point) > get<max_corner, Dimension>(box))
{
return true;
}
return point_box
<
Point, Box,
Dimension + 1, DimensionCount
>::apply(point, box);
}
};
template <typename Point, typename Box, std::size_t DimensionCount>
struct point_box<Point, Box, DimensionCount, DimensionCount>
{
static inline bool apply(Point const& , Box const& )
{
return false;
}
};
/*!
\brief Internal utility function to detect if point/box are disjoint
*/
template <typename Point, typename Box>
inline bool disjoint_point_box(Point const& point, Box const& box)
{
return detail::disjoint::point_box
<
Point, Box,
0, dimension<Point>::type::value
>::apply(point, box);
// ! covered_by(point, box)
return ! strategy::within::relate_point_box_loop
<
strategy::within::covered_by_range,
Point, Box,
0, dimension<Point>::type::value
>::apply(point, box);
}
@@ -94,8 +65,18 @@ namespace dispatch
template <typename Point, typename Box, std::size_t DimensionCount>
struct disjoint<Point, Box, DimensionCount, point_tag, box_tag, false>
: detail::disjoint::point_box<Point, Box, 0, DimensionCount>
{};
{
static inline bool apply(Point const& point, Box const& box)
{
// ! covered_by(point, box)
return ! strategy::within::relate_point_box_loop
<
strategy::within::covered_by_range,
Point, Box,
0, DimensionCount
>::apply(point, box);
}
};
} // namespace dispatch