updated boost on windows

This commit is contained in:
Bassem Girgis
2019-08-13 21:48:48 -05:00
parent 7d77d485fd
commit b40a3bee82
5162 changed files with 473027 additions and 116452 deletions

View File

@@ -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>
{};

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-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

View File

@@ -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

View File

@@ -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>

View File

@@ -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&)
{}
};

View File

@@ -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

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-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);
}

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, 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

View File

@@ -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
{};