updated boost on windows
This commit is contained in:
@@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2019.
|
||||
// Modifications copyright (c) 2013-2019, 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/detail/point_on_border.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
|
||||
|
||||
#include <boost/geometry/iterators/segment_iterator.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -38,30 +41,15 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
template <typename Geometry, typename Tag = typename tag<Geometry>::type>
|
||||
struct check_each_ring_for_within_call_covered_by
|
||||
template <typename Geometry1, typename Geometry2, typename Strategy>
|
||||
inline bool point_on_border_covered_by(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
/*!
|
||||
\tparam Strategy point_in_geometry strategy
|
||||
*/
|
||||
template <typename Point, typename Strategy>
|
||||
static inline bool apply(Point const& p, Geometry const& g, Strategy const& strategy)
|
||||
{
|
||||
return geometry::covered_by(p, g, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Geometry>
|
||||
struct check_each_ring_for_within_call_covered_by<Geometry, box_tag>
|
||||
{
|
||||
template <typename Point, typename Strategy>
|
||||
static inline bool apply(Point const& p, Geometry const& g, Strategy const& )
|
||||
{
|
||||
return geometry::covered_by(p, g);
|
||||
}
|
||||
};
|
||||
|
||||
typename geometry::point_type<Geometry1>::type pt;
|
||||
return geometry::point_on_border(pt, geometry1)
|
||||
&& geometry::covered_by(pt, geometry2, strategy);
|
||||
}
|
||||
|
||||
/*!
|
||||
\tparam Strategy point_in_geometry strategy
|
||||
@@ -83,13 +71,8 @@ struct check_each_ring_for_within
|
||||
template <typename Range>
|
||||
inline void apply(Range const& range)
|
||||
{
|
||||
typename point_type<Range>::type pt;
|
||||
not_disjoint = not_disjoint
|
||||
|| ( geometry::point_on_border(pt, range)
|
||||
&& check_each_ring_for_within_call_covered_by
|
||||
<
|
||||
Geometry
|
||||
>::apply(pt, m_geometry, m_strategy) );
|
||||
|| point_on_border_covered_by(range, m_geometry, m_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -113,7 +96,7 @@ inline bool rings_containing(FirstGeometry const& geometry1,
|
||||
|
||||
|
||||
template <typename Geometry1, typename Geometry2>
|
||||
struct general_areal
|
||||
struct areal_areal
|
||||
{
|
||||
/*!
|
||||
\tparam Strategy relate (segments intersection) strategy
|
||||
@@ -147,6 +130,56 @@ struct general_areal
|
||||
};
|
||||
|
||||
|
||||
template <typename Areal, typename Box>
|
||||
struct areal_box
|
||||
{
|
||||
/*!
|
||||
\tparam Strategy relate (segments intersection) strategy
|
||||
*/
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Areal const& areal,
|
||||
Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
if ( ! for_each_segment(geometry::segments_begin(areal),
|
||||
geometry::segments_end(areal),
|
||||
box,
|
||||
strategy.get_disjoint_segment_box_strategy()) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there is no intersection of any segment and box,
|
||||
// the box might be located inside areal geometry
|
||||
|
||||
if ( point_on_border_covered_by(box, areal,
|
||||
strategy.template get_point_in_geometry_strategy<Box, Areal>()) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
template <typename SegIter, typename Strategy>
|
||||
static inline bool for_each_segment(SegIter first,
|
||||
SegIter last,
|
||||
Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
for ( ; first != last ; ++first)
|
||||
{
|
||||
if (! disjoint_segment_box::apply(*first, box, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -160,13 +193,13 @@ namespace dispatch
|
||||
|
||||
template <typename Areal1, typename Areal2>
|
||||
struct disjoint<Areal1, Areal2, 2, areal_tag, areal_tag, false>
|
||||
: detail::disjoint::general_areal<Areal1, Areal2>
|
||||
: detail::disjoint::areal_areal<Areal1, Areal2>
|
||||
{};
|
||||
|
||||
|
||||
template <typename Areal, typename Box>
|
||||
struct disjoint<Areal, Box, 2, areal_tag, box_tag, false>
|
||||
: detail::disjoint::general_areal<Areal, Box>
|
||||
: detail::disjoint::areal_box<Areal, Box>
|
||||
{};
|
||||
|
||||
|
||||
|
||||
@@ -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-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2018.
|
||||
// Modifications copyright (c) 2013-2018, 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
|
||||
@@ -23,130 +23,30 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
|
||||
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
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
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
{
|
||||
return apply(box1, box2);
|
||||
}
|
||||
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2)
|
||||
{
|
||||
if (get<max_corner, Dimension>(box1) < get<min_corner, Dimension>(box2))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (get<min_corner, Dimension>(box1) > get<max_corner, Dimension>(box2))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return box_box
|
||||
<
|
||||
Box1, Box2,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct box_box<Box1, Box2, 0, DimensionCount, spherical_tag>
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
{
|
||||
return apply(box1, box2);
|
||||
}
|
||||
|
||||
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 (diff1 < constants::period() && diff2 < constants::period())
|
||||
{
|
||||
// calculate positive longitude translation with b1_min as origin
|
||||
calc_t const diff_min = math::longitude_distance_unsigned<units_t>(b1_min, b2_min);
|
||||
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
|
||||
to avoid circular references
|
||||
*/
|
||||
template <typename Box1, typename Box2>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2)
|
||||
template <typename Box1, typename Box2, typename Strategy>
|
||||
inline bool disjoint_box_box(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
{
|
||||
return box_box<Box1, Box2>::apply(box1, box2);
|
||||
return Strategy::apply(box1, box2);
|
||||
}
|
||||
|
||||
|
||||
@@ -161,8 +61,13 @@ namespace dispatch
|
||||
|
||||
template <typename Box1, typename Box2, std::size_t DimensionCount>
|
||||
struct disjoint<Box1, Box2, DimensionCount, box_tag, box_tag, false>
|
||||
: detail::disjoint::box_box<Box1, Box2, 0, DimensionCount>
|
||||
{};
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Box1 const& box1, Box2 const& box2, Strategy const&)
|
||||
{
|
||||
return Strategy::apply(box1, box2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2014.
|
||||
// Modifications copyright (c) 2013-2014, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, 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
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2018.
|
||||
// Modifications copyright (c) 2013-2018, 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
|
||||
@@ -41,8 +41,9 @@
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
|
||||
|
||||
|
||||
@@ -93,18 +93,6 @@ struct assign_disjoint_policy
|
||||
static bool const include_no_turn = true;
|
||||
static bool const include_degenerate = true;
|
||||
static bool const include_opposite = true;
|
||||
|
||||
// We don't assign extra info:
|
||||
template
|
||||
<
|
||||
typename Info,
|
||||
typename Point1,
|
||||
typename Point2,
|
||||
typename IntersectionInfo
|
||||
>
|
||||
static inline void apply(Info& , Point1 const& , Point2 const&,
|
||||
IntersectionInfo const&)
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
|
||||
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
|
||||
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
@@ -30,13 +31,16 @@
|
||||
|
||||
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
|
||||
#include <boost/geometry/algorithms/detail/partition.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
|
||||
#include <boost/geometry/algorithms/detail/relate/less.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
#include <boost/geometry/policies/compare.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -53,10 +57,10 @@ class multipoint_multipoint
|
||||
private:
|
||||
template <typename Iterator>
|
||||
class unary_disjoint_predicate
|
||||
: detail::relate::less
|
||||
: geometry::less<>
|
||||
{
|
||||
private:
|
||||
typedef detail::relate::less base_type;
|
||||
typedef geometry::less<> base_type;
|
||||
|
||||
public:
|
||||
unary_disjoint_predicate(Iterator first, Iterator last)
|
||||
@@ -87,7 +91,7 @@ public:
|
||||
std::vector<point1_type> points1(boost::begin(multipoint1),
|
||||
boost::end(multipoint1));
|
||||
|
||||
std::sort(points1.begin(), points1.end(), detail::relate::less());
|
||||
std::sort(points1.begin(), points1.end(), geometry::less<>());
|
||||
|
||||
typedef unary_disjoint_predicate
|
||||
<
|
||||
@@ -117,49 +121,49 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: After adding non-cartesian Segment envelope to the library
|
||||
// this policy should be modified to take envelope strategy.
|
||||
template <typename EnvelopeStrategy>
|
||||
struct expand_box_segment
|
||||
{
|
||||
explicit expand_box_segment(EnvelopeStrategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Segment>
|
||||
static inline void apply(Box& total, Segment const& segment)
|
||||
inline void apply(Box& total, Segment const& segment) const
|
||||
{
|
||||
geometry::expand(total, geometry::return_envelope<Box>(segment));
|
||||
geometry::expand(total,
|
||||
geometry::return_envelope<Box>(segment, m_strategy));
|
||||
}
|
||||
|
||||
EnvelopeStrategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
{
|
||||
// The default strategy is enough in this case
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
<
|
||||
Point, Box
|
||||
>::type strategy_type;
|
||||
return ! dispatch::disjoint<Point, Box>::apply(point, box, strategy_type());
|
||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: After implementing disjoint Segment/Box for non-cartesian geometries
|
||||
// this strategy should be passed here.
|
||||
// TODO: This Segment/Box strategy should somehow be derived from Point/Segment strategy
|
||||
// which by default is winding containing CS-specific side strategy
|
||||
// TODO: disjoint Segment/Box will be called in this case which may take
|
||||
// quite long in non-cartesian CS. So we should consider passing range of bounding boxes
|
||||
// of segments after calculating them once.
|
||||
template <typename DisjointStrategy>
|
||||
struct overlaps_box_segment
|
||||
{
|
||||
explicit overlaps_box_segment(DisjointStrategy const& strategy)
|
||||
: m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Box, typename Segment>
|
||||
static inline bool apply(Box const& box, Segment const& segment)
|
||||
inline bool apply(Box const& box, Segment const& segment) const
|
||||
{
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
<
|
||||
Segment, Box
|
||||
>::type strategy_type;
|
||||
return ! dispatch::disjoint<Segment, Box>::apply(segment, box, strategy_type());
|
||||
return ! dispatch::disjoint<Segment, Box>::apply(segment, box, m_strategy);
|
||||
}
|
||||
|
||||
DisjointStrategy const& m_strategy;
|
||||
};
|
||||
|
||||
template <typename PtSegStrategy>
|
||||
@@ -172,13 +176,15 @@ private:
|
||||
{}
|
||||
|
||||
template <typename Item1, typename Item2>
|
||||
inline void apply(Item1 const& item1, Item2 const& item2)
|
||||
inline bool apply(Item1 const& item1, Item2 const& item2)
|
||||
{
|
||||
if (! m_intersection_found
|
||||
&& ! dispatch::disjoint<Item1, Item2>::apply(item1, item2, m_strategy))
|
||||
{
|
||||
m_intersection_found = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool intersection_found() const { return m_intersection_found; }
|
||||
@@ -219,12 +225,23 @@ public:
|
||||
{
|
||||
item_visitor_type<Strategy> visitor(strategy);
|
||||
|
||||
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
|
||||
typedef typename Strategy::disjoint_strategy_type disjoint_strategy_type;
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type disjoint_pb_strategy_type;
|
||||
|
||||
// TODO: disjoint Segment/Box may be called in partition multiple times
|
||||
// possibly for non-cartesian segments which could be slow. We should consider
|
||||
// passing a range of bounding boxes of segments after calculating them once.
|
||||
// Alternatively instead of a range of segments a range of Segment/Envelope pairs
|
||||
// should be passed, where envelope would be lazily calculated when needed the first time
|
||||
geometry::partition
|
||||
<
|
||||
geometry::model::box<typename point_type<MultiPoint>::type>
|
||||
>::apply(multipoint, segment_range(linear), visitor,
|
||||
expand_box_point(), overlaps_box_point(),
|
||||
expand_box_segment(), overlaps_box_segment());
|
||||
expand_box_point(),
|
||||
overlaps_box_point<disjoint_pb_strategy_type>(),
|
||||
expand_box_segment<envelope_strategy_type>(strategy.get_envelope_strategy()),
|
||||
overlaps_box_segment<disjoint_strategy_type>(strategy.get_disjoint_strategy()));
|
||||
|
||||
return ! visitor.intersection_found();
|
||||
}
|
||||
@@ -237,6 +254,195 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename SingleGeometry>
|
||||
class multi_point_single_geometry
|
||||
{
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point,
|
||||
SingleGeometry const& single_geometry,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<SingleGeometry>::type point2_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
|
||||
box2_type box2;
|
||||
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
|
||||
geometry::detail::expand_by_epsilon(box2);
|
||||
|
||||
typedef typename boost::range_const_iterator<MultiPoint>::type iterator;
|
||||
for ( iterator it = boost::begin(multi_point) ; it != boost::end(multi_point) ; ++it )
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type())
|
||||
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(SingleGeometry const& single_geometry, MultiPoint const& multi_point, Strategy const& strategy)
|
||||
{
|
||||
return apply(multi_point, single_geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename MultiGeometry>
|
||||
class multi_point_multi_geometry
|
||||
{
|
||||
private:
|
||||
struct expand_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline void apply(Box& total, Point const& point)
|
||||
{
|
||||
geometry::expand(total, point);
|
||||
}
|
||||
};
|
||||
|
||||
struct expand_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
inline void apply(Box& total, BoxPair const& box_pair) const
|
||||
{
|
||||
geometry::expand(total, box_pair.first);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DisjointPointBoxStrategy>
|
||||
struct overlaps_box_point
|
||||
{
|
||||
template <typename Box, typename Point>
|
||||
static inline bool apply(Box const& box, Point const& point)
|
||||
{
|
||||
// The default strategy is enough for Point/Box
|
||||
return ! detail::disjoint::disjoint_point_box(point, box,
|
||||
DisjointPointBoxStrategy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename DisjointBoxBoxStrategy>
|
||||
struct overlaps_box_box_pair
|
||||
{
|
||||
template <typename Box, typename BoxPair>
|
||||
inline bool apply(Box const& box, BoxPair const& box_pair) const
|
||||
{
|
||||
// The default strategy is enough for Box/Box
|
||||
return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
|
||||
DisjointBoxBoxStrategy());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename PtSegStrategy>
|
||||
class item_visitor_type
|
||||
{
|
||||
public:
|
||||
item_visitor_type(MultiGeometry const& multi_geometry,
|
||||
PtSegStrategy const& strategy)
|
||||
: m_intersection_found(false)
|
||||
, m_multi_geometry(multi_geometry)
|
||||
, m_strategy(strategy)
|
||||
{}
|
||||
|
||||
template <typename Point, typename BoxPair>
|
||||
inline bool apply(Point const& point, BoxPair const& box_pair)
|
||||
{
|
||||
typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
|
||||
|
||||
typedef typename boost::range_value<MultiGeometry>::type single_type;
|
||||
|
||||
// The default strategy is enough for Point/Box
|
||||
if (! m_intersection_found
|
||||
&& ! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pb_strategy_type())
|
||||
&& ! dispatch::disjoint<Point, single_type>::apply(point, range::at(m_multi_geometry, box_pair.second), m_strategy))
|
||||
{
|
||||
m_intersection_found = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool intersection_found() const { return m_intersection_found; }
|
||||
|
||||
private:
|
||||
bool m_intersection_found;
|
||||
MultiGeometry const& m_multi_geometry;
|
||||
PtSegStrategy const& m_strategy;
|
||||
};
|
||||
// structs for partition -- end
|
||||
|
||||
public:
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiPoint const& multi_point, MultiGeometry const& multi_geometry, Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<MultiPoint>::type point1_type;
|
||||
typedef typename point_type<MultiGeometry>::type point2_type;
|
||||
typedef model::box<point1_type> box1_type;
|
||||
typedef model::box<point2_type> box2_type;
|
||||
typedef std::pair<box2_type, std::size_t> box_pair_type;
|
||||
|
||||
typename Strategy::envelope_strategy_type const
|
||||
envelope_strategy = strategy.get_envelope_strategy();
|
||||
|
||||
std::size_t count2 = boost::size(multi_geometry);
|
||||
std::vector<box_pair_type> boxes(count2);
|
||||
for (std::size_t i = 0 ; i < count2 ; ++i)
|
||||
{
|
||||
geometry::envelope(range::at(multi_geometry, i), boxes[i].first, envelope_strategy);
|
||||
geometry::detail::expand_by_epsilon(boxes[i].first);
|
||||
boxes[i].second = i;
|
||||
}
|
||||
|
||||
item_visitor_type<Strategy> visitor(multi_geometry, strategy);
|
||||
|
||||
typedef overlaps_box_point
|
||||
<
|
||||
typename Strategy::disjoint_point_box_strategy_type
|
||||
> overlaps_box_point_type;
|
||||
typedef overlaps_box_box_pair
|
||||
<
|
||||
typename Strategy::disjoint_box_box_strategy_type
|
||||
> overlaps_box_box_pair_type;
|
||||
|
||||
geometry::partition
|
||||
<
|
||||
box1_type
|
||||
>::apply(multi_point, boxes, visitor,
|
||||
expand_box_point(),
|
||||
overlaps_box_point_type(),
|
||||
expand_box_box_pair(),
|
||||
overlaps_box_box_pair_type());
|
||||
|
||||
return ! visitor.intersection_found();
|
||||
}
|
||||
|
||||
template <typename Strategy>
|
||||
static inline bool apply(MultiGeometry const& multi_geometry, MultiPoint const& multi_point, Strategy const& strategy)
|
||||
{
|
||||
return apply(multi_point, multi_geometry, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Areal, typename Tag = typename tag<Areal>::type>
|
||||
struct multipoint_areal
|
||||
: multi_point_single_geometry<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
template <typename MultiPoint, typename Areal>
|
||||
struct multipoint_areal<MultiPoint, Areal, multi_polygon_tag>
|
||||
: multi_point_multi_geometry<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
}} // namespace detail::disjoint
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -321,6 +527,22 @@ struct disjoint
|
||||
{};
|
||||
|
||||
|
||||
template <typename Areal, typename MultiPoint, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
Areal, MultiPoint, DimensionCount, areal_tag, multi_point_tag, false
|
||||
> : detail::disjoint::multipoint_areal<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
template <typename MultiPoint, typename Areal, std::size_t DimensionCount>
|
||||
struct disjoint
|
||||
<
|
||||
MultiPoint, Areal, DimensionCount, multi_point_tag, areal_tag, false
|
||||
> : detail::disjoint::multipoint_areal<MultiPoint, Areal>
|
||||
{};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
@@ -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-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2018.
|
||||
// Modifications copyright (c) 2013-2018, 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
|
||||
@@ -41,16 +41,11 @@ namespace detail { namespace disjoint
|
||||
/*!
|
||||
\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)
|
||||
template <typename Point, typename Box, typename Strategy>
|
||||
inline bool disjoint_point_box(Point const& point, Box const& box, Strategy const& )
|
||||
{
|
||||
typedef typename strategy::disjoint::services::default_strategy
|
||||
<
|
||||
Point, Box
|
||||
>::type strategy_type;
|
||||
|
||||
// ! covered_by(point, box)
|
||||
return ! strategy_type::apply(point, box);
|
||||
return ! Strategy::apply(point, box);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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, 2014, 2015, 2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013, 2014, 2015, 2017, 2018.
|
||||
// Modifications copyright (c) 2013-2018, 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
|
||||
@@ -23,29 +23,15 @@
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <boost/geometry/core/access.hpp>
|
||||
#include <boost/geometry/core/radian_access.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.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/util/math.hpp>
|
||||
#include <boost/geometry/util/select_most_precise.hpp>
|
||||
|
||||
#include <boost/geometry/strategies/strategy_transform.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/helper_geometry.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/transform.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
|
||||
// For backward compatibility
|
||||
#include <boost/geometry/strategies/disjoint.hpp>
|
||||
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
|
||||
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -56,169 +42,15 @@ namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
|
||||
template <std::size_t Dimension, std::size_t DimensionCount>
|
||||
struct point_point_generic
|
||||
{
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& p1, Point2 const& p2, Strategy const& )
|
||||
{
|
||||
return apply(p1, p2);
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
static inline bool apply(Point1 const& p1, Point2 const& p2)
|
||||
{
|
||||
if (! geometry::math::equals(get<Dimension>(p1), get<Dimension>(p2)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return
|
||||
point_point_generic<Dimension + 1, DimensionCount>::apply(p1, p2);
|
||||
}
|
||||
};
|
||||
|
||||
template <std::size_t DimensionCount>
|
||||
struct point_point_generic<DimensionCount, DimensionCount>
|
||||
{
|
||||
template <typename Point1, typename Point2>
|
||||
static inline bool apply(Point1 const&, Point2 const& )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class point_point_on_spheroid
|
||||
{
|
||||
private:
|
||||
template <typename Point1, typename Point2, bool SameUnits>
|
||||
struct are_same_points
|
||||
{
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
typedef typename helper_geometry<Point1>::type helper_point_type1;
|
||||
typedef typename helper_geometry<Point2>::type helper_point_type2;
|
||||
|
||||
helper_point_type1 point1_normalized
|
||||
= return_normalized<helper_point_type1>(point1);
|
||||
helper_point_type2 point2_normalized
|
||||
= return_normalized<helper_point_type2>(point2);
|
||||
|
||||
return point_point_generic
|
||||
<
|
||||
0, dimension<Point1>::value
|
||||
>::apply(point1_normalized, point2_normalized);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
struct are_same_points<Point1, Point2, false> // points have different units
|
||||
{
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
typedef typename geometry::select_most_precise
|
||||
<
|
||||
typename fp_coordinate_type<Point1>::type,
|
||||
typename fp_coordinate_type<Point2>::type
|
||||
>::type calculation_type;
|
||||
|
||||
typename helper_geometry
|
||||
<
|
||||
Point1, calculation_type, radian
|
||||
>::type helper_point1, helper_point2;
|
||||
|
||||
Point1 point1_normalized = return_normalized<Point1>(point1);
|
||||
Point2 point2_normalized = return_normalized<Point2>(point2);
|
||||
|
||||
geometry::transform(point1_normalized, helper_point1);
|
||||
geometry::transform(point2_normalized, helper_point2);
|
||||
|
||||
return point_point_generic
|
||||
<
|
||||
0, dimension<Point1>::value
|
||||
>::apply(helper_point1, helper_point2);
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
|
||||
{
|
||||
return apply(point1, point2);
|
||||
}
|
||||
|
||||
template <typename Point1, typename Point2>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2)
|
||||
{
|
||||
return are_same_points
|
||||
<
|
||||
Point1,
|
||||
Point2,
|
||||
boost::is_same
|
||||
<
|
||||
typename coordinate_system<Point1>::type::units,
|
||||
typename coordinate_system<Point2>::type::units
|
||||
>::value
|
||||
>::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2,
|
||||
std::size_t Dimension, std::size_t DimensionCount,
|
||||
typename CSTag1 = typename cs_tag<Point1>::type,
|
||||
typename CSTag2 = CSTag1
|
||||
>
|
||||
struct point_point
|
||||
: point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
<
|
||||
Point1, Point2, Dimension, DimensionCount, spherical_equatorial_tag
|
||||
> : point_point_on_spheroid
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_point
|
||||
<
|
||||
Point1, Point2, Dimension, DimensionCount, geographic_tag
|
||||
> : point_point_on_spheroid
|
||||
{};
|
||||
|
||||
template
|
||||
<
|
||||
typename Point1, typename Point2,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct point_point<Point1, Point2, Dimension, DimensionCount, cartesian_tag>
|
||||
: point_point_generic<Dimension, DimensionCount>
|
||||
{};
|
||||
|
||||
|
||||
/*!
|
||||
\brief Internal utility function to detect of points are disjoint
|
||||
\note To avoid circular references
|
||||
*/
|
||||
template <typename Point1, typename Point2>
|
||||
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
|
||||
template <typename Point1, typename Point2, typename Strategy>
|
||||
inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
return point_point
|
||||
<
|
||||
Point1, Point2,
|
||||
0, dimension<Point1>::type::value
|
||||
>::apply(point1, point2);
|
||||
return ! Strategy::apply(point1, point2);
|
||||
}
|
||||
|
||||
|
||||
@@ -226,8 +58,6 @@ inline bool disjoint_point_point(Point1 const& point1, Point2 const& point2)
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
@@ -235,8 +65,14 @@ namespace dispatch
|
||||
|
||||
template <typename Point1, typename Point2, std::size_t DimensionCount>
|
||||
struct disjoint<Point1, Point2, DimensionCount, point_tag, point_tag, false>
|
||||
: detail::disjoint::point_point<Point1, Point2, 0, DimensionCount>
|
||||
{};
|
||||
{
|
||||
template <typename Strategy>
|
||||
static inline bool apply(Point1 const& point1, Point2 const& point2,
|
||||
Strategy const& )
|
||||
{
|
||||
return ! Strategy::apply(point1, point2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
|
||||
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
|
||||
|
||||
// This file was modified by Oracle on 2013-2017.
|
||||
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
|
||||
// This file was modified by Oracle on 2013-2019.
|
||||
// Modifications copyright (c) 2013-2019, Oracle and/or its affiliates.
|
||||
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
||||
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
||||
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
||||
|
||||
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
|
||||
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
|
||||
@@ -24,9 +25,22 @@
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/geometry/core/tags.hpp>
|
||||
#include <boost/geometry/core/radian_access.hpp>
|
||||
|
||||
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
|
||||
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
|
||||
#include <boost/geometry/algorithms/detail/normalize.hpp>
|
||||
#include <boost/geometry/algorithms/dispatch/disjoint.hpp>
|
||||
#include <boost/geometry/algorithms/envelope.hpp>
|
||||
|
||||
#include <boost/geometry/formulas/vertex_longitude.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/box.hpp>
|
||||
|
||||
// Temporary, for envelope_segment_impl
|
||||
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
@@ -36,10 +50,202 @@ namespace boost { namespace geometry
|
||||
namespace detail { namespace disjoint
|
||||
{
|
||||
|
||||
template <typename CS_Tag>
|
||||
struct disjoint_segment_box_sphere_or_spheroid
|
||||
{
|
||||
struct disjoint_info
|
||||
{
|
||||
enum type
|
||||
{
|
||||
intersect,
|
||||
disjoint_no_vertex,
|
||||
disjoint_vertex
|
||||
};
|
||||
disjoint_info(type t) : m_(t){}
|
||||
operator type () const {return m_;}
|
||||
type m_;
|
||||
private :
|
||||
//prevent automatic conversion for any other built-in types
|
||||
template <typename T>
|
||||
operator T () const;
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
typename AzimuthStrategy,
|
||||
typename NormalizeStrategy,
|
||||
typename DisjointPointBoxStrategy,
|
||||
typename DisjointBoxBoxStrategy
|
||||
>
|
||||
static inline bool apply(Segment const& segment,
|
||||
Box const& box,
|
||||
AzimuthStrategy const& azimuth_strategy,
|
||||
NormalizeStrategy const& normalize_strategy,
|
||||
DisjointPointBoxStrategy const& disjoint_point_box_strategy,
|
||||
DisjointBoxBoxStrategy const& disjoint_box_box_strategy)
|
||||
{
|
||||
typedef typename point_type<Segment>::type segment_point;
|
||||
segment_point vertex;
|
||||
return apply(segment, box, vertex,
|
||||
azimuth_strategy,
|
||||
normalize_strategy,
|
||||
disjoint_point_box_strategy,
|
||||
disjoint_box_box_strategy) != disjoint_info::intersect;
|
||||
}
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
typename P,
|
||||
typename AzimuthStrategy,
|
||||
typename NormalizeStrategy,
|
||||
typename DisjointPointBoxStrategy,
|
||||
typename DisjointBoxBoxStrategy
|
||||
>
|
||||
static inline disjoint_info apply(Segment const& segment,
|
||||
Box const& box,
|
||||
P& vertex,
|
||||
AzimuthStrategy const& azimuth_strategy,
|
||||
NormalizeStrategy const& ,
|
||||
DisjointPointBoxStrategy const& disjoint_point_box_strategy,
|
||||
DisjointBoxBoxStrategy const& disjoint_box_box_strategy)
|
||||
{
|
||||
assert_dimension_equal<Segment, Box>();
|
||||
|
||||
typedef typename point_type<Segment>::type segment_point_type;
|
||||
|
||||
segment_point_type p0, p1;
|
||||
geometry::detail::assign_point_from_index<0>(segment, p0);
|
||||
geometry::detail::assign_point_from_index<1>(segment, p1);
|
||||
|
||||
//vertex not computed here
|
||||
disjoint_info disjoint_return_value = disjoint_info::disjoint_no_vertex;
|
||||
|
||||
// Simplest cases first
|
||||
|
||||
// Case 1: if box contains one of segment's endpoints then they are not disjoint
|
||||
if ( ! disjoint_point_box(p0, box, disjoint_point_box_strategy)
|
||||
|| ! disjoint_point_box(p1, box, disjoint_point_box_strategy) )
|
||||
{
|
||||
return disjoint_info::intersect;
|
||||
}
|
||||
|
||||
// Case 2: disjoint if bounding boxes are disjoint
|
||||
|
||||
typedef typename coordinate_type<segment_point_type>::type CT;
|
||||
|
||||
segment_point_type p0_normalized;
|
||||
NormalizeStrategy::apply(p0, p0_normalized);
|
||||
segment_point_type p1_normalized;
|
||||
NormalizeStrategy::apply(p1, p1_normalized);
|
||||
|
||||
CT lon1 = geometry::get_as_radian<0>(p0_normalized);
|
||||
CT lat1 = geometry::get_as_radian<1>(p0_normalized);
|
||||
CT lon2 = geometry::get_as_radian<0>(p1_normalized);
|
||||
CT lat2 = geometry::get_as_radian<1>(p1_normalized);
|
||||
|
||||
if (lon1 > lon2)
|
||||
{
|
||||
std::swap(lon1, lon2);
|
||||
std::swap(lat1, lat2);
|
||||
}
|
||||
|
||||
geometry::model::box<segment_point_type> box_seg;
|
||||
|
||||
strategy::envelope::detail::envelope_segment_impl
|
||||
<
|
||||
CS_Tag
|
||||
>::template apply<geometry::radian>(lon1, lat1,
|
||||
lon2, lat2,
|
||||
box_seg,
|
||||
azimuth_strategy);
|
||||
|
||||
if (disjoint_box_box(box, box_seg, disjoint_box_box_strategy))
|
||||
{
|
||||
return disjoint_return_value;
|
||||
}
|
||||
|
||||
// Case 3: test intersection by comparing angles
|
||||
|
||||
CT alp1, a_b0, a_b1, a_b2, a_b3;
|
||||
|
||||
CT b_lon_min = geometry::get_as_radian<geometry::min_corner, 0>(box);
|
||||
CT b_lat_min = geometry::get_as_radian<geometry::min_corner, 1>(box);
|
||||
CT b_lon_max = geometry::get_as_radian<geometry::max_corner, 0>(box);
|
||||
CT b_lat_max = geometry::get_as_radian<geometry::max_corner, 1>(box);
|
||||
|
||||
azimuth_strategy.apply(lon1, lat1, lon2, lat2, alp1);
|
||||
azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_min, a_b0);
|
||||
azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_min, a_b1);
|
||||
azimuth_strategy.apply(lon1, lat1, b_lon_min, b_lat_max, a_b2);
|
||||
azimuth_strategy.apply(lon1, lat1, b_lon_max, b_lat_max, a_b3);
|
||||
|
||||
bool b0 = formula::azimuth_side_value(alp1, a_b0) > 0;
|
||||
bool b1 = formula::azimuth_side_value(alp1, a_b1) > 0;
|
||||
bool b2 = formula::azimuth_side_value(alp1, a_b2) > 0;
|
||||
bool b3 = formula::azimuth_side_value(alp1, a_b3) > 0;
|
||||
|
||||
if (!(b0 && b1 && b2 && b3) && (b0 || b1 || b2 || b3))
|
||||
{
|
||||
return disjoint_info::intersect;
|
||||
}
|
||||
|
||||
// Case 4: The only intersection case not covered above is when all four
|
||||
// points of the box are above (below) the segment in northern (southern)
|
||||
// hemisphere. Then we have to compute the vertex of the segment
|
||||
|
||||
CT vertex_lat;
|
||||
CT lat_sum = lat1 + lat2;
|
||||
|
||||
if ((lat1 < b_lat_min && lat_sum > CT(0))
|
||||
|| (lat1 > b_lat_max && lat_sum < CT(0)))
|
||||
{
|
||||
CT b_lat_below; //latitude of box closest to equator
|
||||
|
||||
if (lat_sum > CT(0))
|
||||
{
|
||||
vertex_lat = geometry::get_as_radian<geometry::max_corner, 1>(box_seg);
|
||||
b_lat_below = b_lat_min;
|
||||
} else {
|
||||
vertex_lat = geometry::get_as_radian<geometry::min_corner, 1>(box_seg);
|
||||
b_lat_below = b_lat_max;
|
||||
}
|
||||
|
||||
//optimization TODO: computing the spherical longitude should suffice for
|
||||
// the majority of cases
|
||||
CT vertex_lon = geometry::formula::vertex_longitude<CT, CS_Tag>
|
||||
::apply(lon1, lat1,
|
||||
lon2, lat2,
|
||||
vertex_lat,
|
||||
alp1,
|
||||
azimuth_strategy);
|
||||
|
||||
geometry::set_from_radian<0>(vertex, vertex_lon);
|
||||
geometry::set_from_radian<1>(vertex, vertex_lat);
|
||||
disjoint_return_value = disjoint_info::disjoint_vertex; //vertex_computed
|
||||
|
||||
// Check if the vertex point is within the band defined by the
|
||||
// minimum and maximum longitude of the box; if yes, then return
|
||||
// false if the point is above the min latitude of the box; return
|
||||
// true in all other cases
|
||||
if (vertex_lon >= b_lon_min && vertex_lon <= b_lon_max
|
||||
&& std::abs(vertex_lat) > std::abs(b_lat_below))
|
||||
{
|
||||
return disjoint_info::intersect;
|
||||
}
|
||||
}
|
||||
|
||||
return disjoint_return_value;
|
||||
}
|
||||
};
|
||||
|
||||
struct disjoint_segment_box
|
||||
{
|
||||
template <typename Segment, typename Box, typename Strategy>
|
||||
static inline bool apply(Segment const& segment, Box const& box, Strategy const& strategy)
|
||||
static inline bool apply(Segment const& segment,
|
||||
Box const& box,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return strategy.apply(segment, box);
|
||||
}
|
||||
@@ -56,7 +262,7 @@ namespace dispatch
|
||||
|
||||
template <typename Segment, typename Box, std::size_t DimensionCount>
|
||||
struct disjoint<Segment, Box, DimensionCount, segment_tag, box_tag, false>
|
||||
: detail::disjoint::disjoint_segment_box
|
||||
: detail::disjoint::disjoint_segment_box
|
||||
{};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user