Merge branch 'develop' into feature/buffer_point_geographic

This commit is contained in:
Barend Gehrels
2019-01-09 20:24:31 +01:00
127 changed files with 5298 additions and 3259 deletions

View File

@@ -50,8 +50,8 @@ int main()
/*`
Output:
[pre
(0, 0) (0, 4) (4, 4) (4, 0) (0, 0)
Area: 16
(0, 0) (1, 1)
Length: 1.41421
]
*/
//]

View File

@@ -216,15 +216,20 @@ struct area<MultiGeometry, multi_polygon_tag> : detail::multi_sum
namespace resolve_strategy
{
template <typename Strategy>
struct area
{
template <typename Geometry, typename Strategy>
template <typename Geometry>
static inline typename area_result<Geometry, Strategy>::type
apply(Geometry const& geometry, Strategy const& strategy)
{
return dispatch::area<Geometry>::apply(geometry, strategy);
}
};
template <>
struct area<default_strategy>
{
template <typename Geometry>
static inline typename area_result<Geometry>::type
apply(Geometry const& geometry, default_strategy)
@@ -252,7 +257,7 @@ struct area
static inline typename area_result<Geometry, Strategy>::type
apply(Geometry const& geometry, Strategy const& strategy)
{
return resolve_strategy::area::apply(geometry, strategy);
return resolve_strategy::area<Strategy>::apply(geometry, strategy);
}
};

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2016-2017.
// Modifications copyright (c) 2016-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2016-2018.
// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -633,6 +633,15 @@ struct buffered_piece_collection
{
// Check if a turn is inside any of the originals
typedef turn_in_original_ovelaps_box
<
typename IntersectionStrategy::disjoint_point_box_strategy_type
> turn_in_original_ovelaps_box_type;
typedef original_ovelaps_box
<
typename IntersectionStrategy::disjoint_box_box_strategy_type
> original_ovelaps_box_type;
turn_in_original_visitor<turn_vector_type> visitor(m_turns);
geometry::partition
<
@@ -640,8 +649,8 @@ struct buffered_piece_collection
include_turn_policy,
detail::partition::include_all_policy
>::apply(m_turns, robust_originals, visitor,
turn_get_box(), turn_in_original_ovelaps_box(),
original_get_box(), original_ovelaps_box());
turn_get_box(), turn_in_original_ovelaps_box_type(),
original_get_box(), original_ovelaps_box_type());
bool const deflate = distance_strategy.negative();
@@ -905,12 +914,21 @@ struct buffered_piece_collection
> visitor(m_pieces, offsetted_rings, m_turns,
m_intersection_strategy, m_robust_policy);
typedef detail::section::get_section_box
<
typename IntersectionStrategy::expand_box_strategy_type
> get_section_box_type;
typedef detail::section::overlaps_section_box
<
typename IntersectionStrategy::disjoint_box_box_strategy_type
> overlaps_section_box_type;
geometry::partition
<
robust_box_type
>::apply(monotonic_sections, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
get_section_box_type(),
overlaps_section_box_type());
}
insert_rescaled_piece_turns();
@@ -929,12 +947,21 @@ struct buffered_piece_collection
turn_vector_type, piece_vector_type
> visitor(m_turns, m_pieces);
typedef turn_ovelaps_box
<
typename IntersectionStrategy::disjoint_point_box_strategy_type
> turn_ovelaps_box_type;
typedef piece_ovelaps_box
<
typename IntersectionStrategy::disjoint_box_box_strategy_type
> piece_ovelaps_box_type;
geometry::partition
<
robust_box_type
>::apply(m_turns, m_pieces, visitor,
turn_get_box(), turn_ovelaps_box(),
piece_get_box(), piece_ovelaps_box());
turn_get_box(), turn_ovelaps_box_type(),
piece_get_box(), piece_ovelaps_box_type());
}
}
@@ -1400,6 +1427,8 @@ struct buffered_piece_collection
inline bool point_coveredby_original(point_type const& point)
{
typedef typename IntersectionStrategy::disjoint_point_box_strategy_type d_pb_strategy_type;
robust_point_type any_point;
geometry::recalculate(any_point, point, m_robust_policy);
@@ -1416,7 +1445,8 @@ struct buffered_piece_collection
{
robust_original const& original = *it;
if (detail::disjoint::disjoint_point_box(any_point,
original.m_box))
original.m_box,
d_pb_strategy_type()))
{
continue;
}

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -315,7 +315,8 @@ public:
|| is_adjacent(piece1, piece2)
|| is_on_same_convex_ring(piece1, piece2)
|| detail::disjoint::disjoint_box_box(section1.bounding_box,
section2.bounding_box) )
section2.bounding_box,
m_intersection_strategy.get_disjoint_box_box_strategy()) )
{
return true;
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2016.
// Modifications copyright (c) 2016 Oracle and/or its affiliates.
// This file was modified by Oracle on 2016, 2018.
// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -38,12 +38,14 @@ struct original_get_box
}
};
template <typename DisjointBoxBoxStrategy>
struct original_ovelaps_box
{
template <typename Box, typename Original>
static inline bool apply(Box const& box, Original const& original)
{
return ! detail::disjoint::disjoint_box_box(box, original.m_box);
return ! detail::disjoint::disjoint_box_box(box, original.m_box,
DisjointBoxBoxStrategy());
}
};
@@ -56,6 +58,7 @@ struct include_turn_policy
}
};
template <typename DisjointPointBoxStrategy>
struct turn_in_original_ovelaps_box
{
template <typename Box, typename Turn>
@@ -68,7 +71,7 @@ struct turn_in_original_ovelaps_box
}
return ! geometry::detail::disjoint::disjoint_point_box(
turn.robust_point, box);
turn.robust_point, box, DisjointPointBoxStrategy());
}
};

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2012-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2016.
// Modifications copyright (c) 2016 Oracle and/or its affiliates.
// This file was modified by Oracle on 2016, 2018.
// Modifications copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -55,6 +55,7 @@ struct piece_get_box
}
};
template <typename DisjointBoxBoxStrategy>
struct piece_ovelaps_box
{
template <typename Box, typename Piece>
@@ -70,7 +71,8 @@ struct piece_ovelaps_box
return false;
}
return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope);
return ! geometry::detail::disjoint::disjoint_box_box(box, piece.robust_envelope,
DisjointBoxBoxStrategy());
}
};
@@ -83,12 +85,14 @@ struct turn_get_box
}
};
template <typename DisjointPointBoxStrategy>
struct turn_ovelaps_box
{
template <typename Box, typename Turn>
static inline bool apply(Box const& box, Turn const& turn)
{
return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box);
return ! geometry::detail::disjoint::disjoint_point_box(turn.robust_point, box,
DisjointPointBoxStrategy());
}
};

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -63,13 +63,7 @@ struct covered_by
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::within::check
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
Strategy
>();
concepts::within::check<Geometry1, Geometry2, Strategy>();
concepts::check<Geometry1 const>();
concepts::check<Geometry2 const>();
assert_dimension_equal<Geometry1, Geometry2>();

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,139 +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
calc_t b2_max_transl = b2_min_transl - constants::period() + diff2;
// if the translation is too close then use the original point
// note that math::abs(b2_max_transl - b2_max) takes values very
// close to k*2*constants::period() for k=0,1,2,...
if (math::abs(b2_max_transl - b2_max) < constants::period() / 2)
{
b2_max_transl = b2_max;
}
if (b2_min_transl > b1_max // b2_min right of b1_max
&& b2_max_transl < 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);
}
@@ -170,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

@@ -1,8 +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
@@ -138,13 +138,15 @@ private:
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
return ! detail::disjoint::disjoint_point_box(point, box);
return ! detail::disjoint::disjoint_point_box(point, box,
DisjointPointBoxStrategy());
}
};
@@ -225,6 +227,7 @@ public:
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
@@ -236,7 +239,7 @@ public:
geometry::model::box<typename point_type<MultiPoint>::type>
>::apply(multipoint, segment_range(linear), visitor,
expand_box_point(),
overlaps_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()));
@@ -256,8 +259,12 @@ class multi_point_single_geometry
{
public:
template <typename Strategy>
static inline bool apply(MultiPoint const& multi_point, SingleGeometry const& single_geometry, Strategy const& 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;
@@ -270,7 +277,7 @@ public:
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)
if (! detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type())
&& ! dispatch::disjoint<point1_type, SingleGeometry>::apply(*it, single_geometry, strategy))
{
return false;
@@ -310,23 +317,27 @@ private:
}
};
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);
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);
return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
DisjointBoxBoxStrategy());
}
};
@@ -344,11 +355,13 @@ private:
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)
&& ! 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;
@@ -390,14 +403,23 @@ public:
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(),
overlaps_box_point_type(),
expand_box_box_pair(),
overlaps_box_box_pair());
overlaps_box_box_pair_type());
return ! visitor.intersection_found();
}

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,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 Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -39,6 +39,9 @@
#include <boost/geometry/geometries/box.hpp>
// Temporary, for envelope_segment_impl
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
namespace boost { namespace geometry
{
@@ -50,21 +53,6 @@ namespace detail { namespace disjoint
template <typename CS_Tag>
struct disjoint_segment_box_sphere_or_spheroid
{
private:
template <typename CT>
static inline void swap(CT& lon1,
CT& lat1,
CT& lon2,
CT& lat2)
{
std::swap(lon1, lon2);
std::swap(lat1, lat2);
}
public:
struct disjoint_info
{
enum type
@@ -82,21 +70,46 @@ public:
operator T () const;
};
template <typename Segment, typename Box, typename Strategy>
template
<
typename Segment, typename Box,
typename AzimuthStrategy,
typename NormalizeStrategy,
typename DisjointPointBoxStrategy,
typename DisjointBoxBoxStrategy
>
static inline bool apply(Segment const& segment,
Box const& box,
Strategy const& azimuth_strategy)
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, azimuth_strategy, vertex) != disjoint_info::intersect);
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 Strategy, typename P>
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,
Strategy const& azimuth_strategy,
P& vertex)
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>();
@@ -113,7 +126,8 @@ public:
// 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(p1, box))
if ( ! disjoint_point_box(p0, box, disjoint_point_box_strategy)
|| ! disjoint_point_box(p1, box, disjoint_point_box_strategy) )
{
return disjoint_info::intersect;
}
@@ -122,10 +136,10 @@ public:
typedef typename coordinate_type<segment_point_type>::type CT;
segment_point_type p0_normalized =
geometry::detail::return_normalized<segment_point_type>(p0);
segment_point_type p1_normalized =
geometry::detail::return_normalized<segment_point_type>(p1);
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);
@@ -134,7 +148,8 @@ public:
if (lon1 > lon2)
{
swap(lon1, lat1, lon2, lat2);
std::swap(lon1, lon2);
std::swap(lat1, lat2);
}
//Compute alp1 outside envelope and pass it to envelope_segment_impl
@@ -145,14 +160,17 @@ public:
geometry::model::box<segment_point_type> box_seg;
geometry::detail::envelope::envelope_segment_impl<segment_cs_type>
::template apply<geometry::radian>(lon1, lat1,
lon2, lat2,
box_seg,
azimuth_strategy,
alp1);
// TODO: Shouldn't CSTag be taken from the caller, not from the segment?
strategy::envelope::detail::envelope_segment_impl
<
segment_cs_type
>::template apply<geometry::radian>(lon1, lat1,
lon2, lat2,
box_seg,
azimuth_strategy,
alp1);
if (disjoint_box_box(box, box_seg))
if (disjoint_box_box(box, box_seg, disjoint_box_box_strategy))
{
return disjoint_return_value;
}

View File

@@ -95,9 +95,10 @@ struct distance
namespace resolve_strategy
{
template <typename Strategy>
struct distance
{
template <typename Geometry1, typename Geometry2, typename Strategy>
template <typename Geometry1, typename Geometry2>
static inline typename distance_result<Geometry1, Geometry2, Strategy>::type
apply(Geometry1 const& geometry1,
Geometry2 const& geometry2,
@@ -108,7 +109,11 @@ struct distance
Geometry1, Geometry2, Strategy
>::apply(geometry1, geometry2, strategy);
}
};
template <>
struct distance<default_strategy>
{
template <typename Geometry1, typename Geometry2>
static inline
typename distance_result<Geometry1, Geometry2, default_strategy>::type
@@ -144,8 +149,10 @@ struct distance
Geometry2 const& geometry2,
Strategy const& strategy)
{
return
resolve_strategy::distance::apply(geometry1, geometry2, strategy);
return resolve_strategy::distance
<
Strategy
>::apply(geometry1, geometry2, strategy);
}
};

View File

@@ -3,6 +3,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -28,7 +29,6 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
template <typename EnvelopePolicy>
struct envelope_polygon
{
template <typename Polygon, typename Box, typename Strategy>
@@ -42,13 +42,13 @@ struct envelope_polygon
// if the exterior ring is empty, consider the interior rings
envelope_multi_range
<
EnvelopePolicy
envelope_range
>::apply(interior_rings(polygon), mbr, strategy);
}
else
{
// otherwise, consider only the exterior ring
EnvelopePolicy::apply(ext_ring, mbr, strategy);
envelope_range::apply(ext_ring, mbr, strategy);
}
}
};
@@ -62,77 +62,21 @@ namespace dispatch
{
template <typename Ring, typename CS_Tag>
struct envelope<Ring, ring_tag, CS_Tag>
template <typename Ring>
struct envelope<Ring, ring_tag>
: detail::envelope::envelope_range
{};
template <typename Ring>
struct envelope<Ring, ring_tag, spherical_equatorial_tag>
: detail::envelope::envelope_linestring_or_ring_on_spheroid
{};
template <typename Ring>
struct envelope<Ring, ring_tag, geographic_tag>
: detail::envelope::envelope_linestring_or_ring_on_spheroid
{};
template <typename Polygon, typename CS_Tag>
struct envelope<Polygon, polygon_tag, CS_Tag>
: detail::envelope::envelope_polygon
<
detail::envelope::envelope_range
>
{};
template <typename Polygon>
struct envelope<Polygon, polygon_tag, spherical_equatorial_tag>
struct envelope<Polygon, polygon_tag>
: detail::envelope::envelope_polygon
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
{};
template <typename Polygon>
struct envelope<Polygon, polygon_tag, geographic_tag>
: detail::envelope::envelope_polygon
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
{};
template <typename MultiPolygon, typename CS_Tag>
struct envelope<MultiPolygon, multi_polygon_tag, CS_Tag>
: detail::envelope::envelope_multi_range
<
detail::envelope::envelope_polygon
<
detail::envelope::envelope_range
>
>
{};
template <typename MultiPolygon>
struct envelope<MultiPolygon, multi_polygon_tag, spherical_equatorial_tag>
struct envelope<MultiPolygon, multi_polygon_tag>
: detail::envelope::envelope_multi_range
<
detail::envelope::envelope_polygon
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
>
{};
template <typename MultiPolygon>
struct envelope<MultiPolygon, multi_polygon_tag, geographic_tag>
: detail::envelope::envelope_multi_range
<
detail::envelope::envelope_polygon
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
>
{};

View File

@@ -18,134 +18,17 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_BOX_HPP
#include <cstddef>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
#include <boost/geometry/strategies/spherical/envelope_box.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace envelope
{
template
<
std::size_t Index,
std::size_t Dimension,
std::size_t DimensionCount
>
struct envelope_indexed_box
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
detail::conversion::point_to_point
<
detail::indexed_point_view<BoxIn const, Index>,
detail::indexed_point_view<BoxOut, Index>,
Dimension,
DimensionCount
>::apply(box_in_corner, mbr_corner);
}
};
template
<
std::size_t Index,
std::size_t DimensionCount
>
struct envelope_indexed_box_on_spheroid
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
// transform() does not work with boxes of dimension higher
// than 2; to account for such boxes we transform the min/max
// points of the boxes using the indexed_point_view
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
// first transform the units
transform_units(box_in_corner, mbr_corner);
// now transform the remaining coordinates
detail::conversion::point_to_point
<
detail::indexed_point_view<BoxIn const, Index>,
detail::indexed_point_view<BoxOut, Index>,
2,
DimensionCount
>::apply(box_in_corner, mbr_corner);
}
};
struct envelope_box
{
template<typename BoxIn, typename BoxOut, typename Strategy>
static inline void apply(BoxIn const& box_in,
BoxOut& mbr,
Strategy const&)
{
envelope_indexed_box
<
min_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
envelope_indexed_box
<
max_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
}
};
struct envelope_box_on_spheroid
{
template <typename BoxIn, typename BoxOut, typename Strategy>
static inline void apply(BoxIn const& box_in,
BoxOut& mbr,
Strategy const&)
{
BoxIn box_in_normalized = box_in;
if (!is_inverse_spheroidal_coordinates(box_in))
{
box_in_normalized = detail::return_normalized<BoxIn>(box_in);
}
envelope_indexed_box_on_spheroid
<
min_corner, dimension<BoxIn>::value
>::apply(box_in_normalized, mbr);
envelope_indexed_box_on_spheroid
<
max_corner, dimension<BoxIn>::value
>::apply(box_in_normalized, mbr);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
@@ -153,27 +36,14 @@ namespace dispatch
template <typename Box>
struct envelope<Box, box_tag, cartesian_tag>
: detail::envelope::envelope_box
{};
template <typename Box>
struct envelope<Box, box_tag, spherical_polar_tag>
: detail::envelope::envelope_box_on_spheroid
{};
template <typename Box>
struct envelope<Box, box_tag, spherical_equatorial_tag>
: detail::envelope::envelope_box_on_spheroid
{};
template <typename Box>
struct envelope<Box, box_tag, geographic_tag>
: detail::envelope::envelope_box_on_spheroid
{};
struct envelope<Box, box_tag>
{
template<typename BoxIn, typename BoxOut, typename Strategy>
static inline void apply(BoxIn const& box_in, BoxOut& mbr, Strategy const& )
{
Strategy::apply(box_in, mbr);
}
};
} // namespace dispatch

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -21,19 +21,24 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_INTERFACE_HPP
#include <boost/variant/apply_visitor.hpp>
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
namespace boost { namespace geometry
{
@@ -57,13 +62,15 @@ struct envelope
Box& box,
default_strategy)
{
typedef typename point_type<Geometry>::type point_type;
typedef typename coordinate_type<point_type>::type coordinate_type;
typedef typename strategy::envelope::services::default_strategy
<
typename cs_tag<point_type>::type,
coordinate_type
typename tag<Geometry>::type,
typename cs_tag<Geometry>::type,
typename select_most_precise
<
typename coordinate_type<Geometry>::type,
typename coordinate_type<Box>::type
>::type
>::type strategy_type;
dispatch::envelope<Geometry>::apply(geometry, box, strategy_type());

View File

@@ -4,11 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,92 +18,40 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_LINEAR_HPP
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/iterators/segment_iterator.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/envelope.hpp>
#include <boost/geometry/strategies/spherical/envelope.hpp>
#include <boost/geometry/strategies/geographic/envelope.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace envelope
{
struct envelope_linestring_or_ring_on_spheroid
{
template <typename LinestringRing, typename Box, typename Strategy>
static inline void apply(LinestringRing const& linestring_or_ring,
Box& mbr,
Strategy const& strategy)
{
envelope_range::apply(geometry::segments_begin(linestring_or_ring),
geometry::segments_end(linestring_or_ring),
mbr,
strategy);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename Linestring, typename CS_Tag>
struct envelope<Linestring, linestring_tag, CS_Tag>
template <typename Linestring>
struct envelope<Linestring, linestring_tag>
: detail::envelope::envelope_range
{};
template <typename Linestring>
struct envelope<Linestring, linestring_tag, spherical_equatorial_tag>
: detail::envelope::envelope_linestring_or_ring_on_spheroid
{};
template <typename Linestring>
struct envelope<Linestring, linestring_tag, geographic_tag>
: detail::envelope::envelope_linestring_or_ring_on_spheroid
{};
template <typename MultiLinestring, typename CS_Tag>
struct envelope
<
MultiLinestring, multi_linestring_tag, CS_Tag
> : detail::envelope::envelope_multi_range
template <typename MultiLinestring>
struct envelope<MultiLinestring, multi_linestring_tag>
: detail::envelope::envelope_multi_range
<
detail::envelope::envelope_range
>
{};
template <typename MultiLinestring>
struct envelope
<
MultiLinestring, multi_linestring_tag, spherical_equatorial_tag
> : detail::envelope::envelope_multi_range_on_spheroid
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
{};
template <typename MultiLinestring>
struct envelope
<
MultiLinestring, multi_linestring_tag, geographic_tag
> : detail::envelope::envelope_multi_range_on_spheroid
<
detail::envelope::envelope_linestring_or_ring_on_spheroid
>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -13,361 +13,32 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_MULTIPOINT_HPP
#include <cstddef>
#include <algorithm>
#include <utility>
#include <vector>
#include <boost/algorithm/minmax_element.hpp>
#include <boost/range.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/box.hpp>
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/algorithms/detail/expand/point.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/envelope_multipoint.hpp>
#include <boost/geometry/strategies/spherical/envelope_multipoint.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace envelope
{
class envelope_multipoint_on_spheroid
{
private:
template <std::size_t Dim>
struct coordinate_less
{
template <typename Point>
inline bool operator()(Point const& point1, Point const& point2) const
{
return math::smaller(geometry::get<Dim>(point1),
geometry::get<Dim>(point2));
}
};
template <typename Constants, typename MultiPoint, typename OutputIterator>
static inline void analyze_point_coordinates(MultiPoint const& multipoint,
bool& has_south_pole,
bool& has_north_pole,
OutputIterator oit)
{
typedef typename boost::range_value<MultiPoint>::type point_type;
typedef typename boost::range_iterator
<
MultiPoint const
>::type iterator_type;
// analyze point coordinates:
// (1) normalize point coordinates
// (2) check if any point is the north or the south pole
// (3) put all non-pole points in a container
//
// notice that at this point in the algorithm, we have at
// least two points on the spheroid
has_south_pole = false;
has_north_pole = false;
for (iterator_type it = boost::begin(multipoint);
it != boost::end(multipoint);
++it)
{
point_type point = detail::return_normalized<point_type>(*it);
if (math::equals(geometry::get<1>(point),
Constants::min_latitude()))
{
has_south_pole = true;
}
else if (math::equals(geometry::get<1>(point),
Constants::max_latitude()))
{
has_north_pole = true;
}
else
{
*oit++ = point;
}
}
}
template <typename SortedRange, typename Value>
static inline Value maximum_gap(SortedRange const& sorted_range,
Value& max_gap_left,
Value& max_gap_right)
{
typedef typename boost::range_iterator
<
SortedRange const
>::type iterator_type;
iterator_type it1 = boost::begin(sorted_range), it2 = it1;
++it2;
max_gap_left = geometry::get<0>(*it1);
max_gap_right = geometry::get<0>(*it2);
Value max_gap = max_gap_right - max_gap_left;
for (++it1, ++it2; it2 != boost::end(sorted_range); ++it1, ++it2)
{
Value gap = geometry::get<0>(*it2) - geometry::get<0>(*it1);
if (math::larger(gap, max_gap))
{
max_gap_left = geometry::get<0>(*it1);
max_gap_right = geometry::get<0>(*it2);
max_gap = gap;
}
}
return max_gap;
}
template
<
typename Constants,
typename PointRange,
typename LongitudeLess,
typename CoordinateType
>
static inline void get_min_max_longitudes(PointRange& range,
LongitudeLess const& lon_less,
CoordinateType& lon_min,
CoordinateType& lon_max)
{
typedef typename boost::range_iterator
<
PointRange const
>::type iterator_type;
// compute min and max longitude values
std::pair<iterator_type, iterator_type> min_max_longitudes
= boost::minmax_element(boost::begin(range),
boost::end(range),
lon_less);
lon_min = geometry::get<0>(*min_max_longitudes.first);
lon_max = geometry::get<0>(*min_max_longitudes.second);
// if the longitude span is "large" compute the true maximum gap
if (math::larger(lon_max - lon_min, Constants::half_period()))
{
std::sort(boost::begin(range), boost::end(range), lon_less);
CoordinateType max_gap_left = 0, max_gap_right = 0;
CoordinateType max_gap
= maximum_gap(range, max_gap_left, max_gap_right);
CoordinateType complement_gap
= Constants::period() + lon_min - lon_max;
if (math::larger(max_gap, complement_gap))
{
lon_min = max_gap_right;
lon_max = max_gap_left + Constants::period();
}
}
}
template
<
typename Constants,
typename Iterator,
typename LatitudeLess,
typename CoordinateType
>
static inline void get_min_max_latitudes(Iterator const first,
Iterator const last,
LatitudeLess const& lat_less,
bool has_south_pole,
bool has_north_pole,
CoordinateType& lat_min,
CoordinateType& lat_max)
{
if (has_south_pole && has_north_pole)
{
lat_min = Constants::min_latitude();
lat_max = Constants::max_latitude();
}
else if (has_south_pole)
{
lat_min = Constants::min_latitude();
lat_max
= geometry::get<1>(*std::max_element(first, last, lat_less));
}
else if (has_north_pole)
{
lat_min
= geometry::get<1>(*std::min_element(first, last, lat_less));
lat_max = Constants::max_latitude();
}
else
{
std::pair<Iterator, Iterator> min_max_latitudes
= boost::minmax_element(first, last, lat_less);
lat_min = geometry::get<1>(*min_max_latitudes.first);
lat_max = geometry::get<1>(*min_max_latitudes.second);
}
}
public:
template <typename MultiPoint, typename Box, typename Strategy>
static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& strategy)
{
typedef typename point_type<MultiPoint>::type point_type;
typedef typename coordinate_type<MultiPoint>::type coordinate_type;
typedef typename boost::range_iterator
<
MultiPoint const
>::type iterator_type;
typedef math::detail::constants_on_spheroid
<
coordinate_type,
typename coordinate_system<MultiPoint>::type::units
> constants;
if (boost::empty(multipoint))
{
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
return;
}
initialize<Box, 0, 2>::apply(mbr);
if (boost::size(multipoint) == 1)
{
return dispatch::envelope
<
typename boost::range_value<MultiPoint>::type
>::apply(range::front(multipoint), mbr, strategy);
}
// analyze the points and put the non-pole ones in the
// points vector
std::vector<point_type> points;
bool has_north_pole = false, has_south_pole = false;
analyze_point_coordinates<constants>(multipoint,
has_south_pole, has_north_pole,
std::back_inserter(points));
coordinate_type lon_min, lat_min, lon_max, lat_max;
if (points.size() == 1)
{
// we have one non-pole point and at least one pole point
lon_min = geometry::get<0>(range::front(points));
lon_max = geometry::get<0>(range::front(points));
lat_min = has_south_pole
? constants::min_latitude()
: constants::max_latitude();
lat_max = has_north_pole
? constants::max_latitude()
: constants::min_latitude();
}
else if (points.empty())
{
// all points are pole points
BOOST_GEOMETRY_ASSERT(has_south_pole || has_north_pole);
lon_min = coordinate_type(0);
lon_max = coordinate_type(0);
lat_min = has_south_pole
? constants::min_latitude()
: constants::max_latitude();
lat_max = (has_north_pole)
? constants::max_latitude()
: constants::min_latitude();
}
else
{
get_min_max_longitudes<constants>(points,
coordinate_less<0>(),
lon_min,
lon_max);
get_min_max_latitudes<constants>(points.begin(),
points.end(),
coordinate_less<1>(),
has_south_pole,
has_north_pole,
lat_min,
lat_max);
}
typedef typename helper_geometry
<
Box,
coordinate_type,
typename coordinate_system<MultiPoint>::type::units
>::type helper_box_type;
helper_box_type helper_mbr;
geometry::set<min_corner, 0>(helper_mbr, lon_min);
geometry::set<min_corner, 1>(helper_mbr, lat_min);
geometry::set<max_corner, 0>(helper_mbr, lon_max);
geometry::set<max_corner, 1>(helper_mbr, lat_max);
// now transform to output MBR (per index)
envelope_indexed_box_on_spheroid<min_corner, 2>::apply(helper_mbr, mbr);
envelope_indexed_box_on_spheroid<max_corner, 2>::apply(helper_mbr, mbr);
// compute envelope for higher coordinates
iterator_type it = boost::begin(multipoint);
envelope_one_point<2, dimension<Box>::value>::apply(*it, mbr, strategy);
for (++it; it != boost::end(multipoint); ++it)
{
detail::expand::point_loop
<
2, dimension<Box>::value
>::apply(mbr, *it, strategy);
}
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template <typename MultiPoint, typename CSTag>
struct envelope<MultiPoint, multi_point_tag, CSTag>
: detail::envelope::envelope_range
{};
template <typename MultiPoint>
struct envelope<MultiPoint, multi_point_tag, spherical_equatorial_tag>
: detail::envelope::envelope_multipoint_on_spheroid
{};
template <typename MultiPoint>
struct envelope<MultiPoint, multi_point_tag, geographic_tag>
: detail::envelope::envelope_multipoint_on_spheroid
{};
struct envelope<MultiPoint, multi_point_tag>
{
template <typename Box, typename Strategy>
static inline void apply(MultiPoint const& multipoint, Box& mbr, Strategy const& )
{
Strategy::apply(multipoint, mbr);
}
};
} // namespace dispatch

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -18,23 +18,14 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_POINT_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
#include <boost/geometry/strategies/spherical/envelope_point.hpp>
namespace boost { namespace geometry
{
@@ -44,53 +35,12 @@ namespace detail { namespace envelope
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_one_point
struct envelope_point
{
template <std::size_t Index, typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
detail::indexed_point_view<Box, Index> box_corner(mbr);
detail::conversion::point_to_point
<
Point,
detail::indexed_point_view<Box, Index>,
Dimension,
DimensionCount
>::apply(point, box_corner);
}
template <typename Point, typename Box, typename Strategy>
static inline void apply(Point const& point, Box& mbr, Strategy const&)
static inline void apply(Point const& point, Box& mbr, Strategy const& )
{
apply<min_corner>(point, mbr);
apply<max_corner>(point, mbr);
}
};
struct envelope_point_on_spheroid
{
template<typename Point, typename Box, typename Strategy>
static inline void apply(Point const& point, Box& mbr, Strategy const& strategy)
{
Point normalized_point = detail::return_normalized<Point>(point);
typename point_type<Box>::type box_point;
// transform units of input point to units of a box point
transform_units(normalized_point, box_point);
geometry::set<min_corner, 0>(mbr, geometry::get<0>(box_point));
geometry::set<min_corner, 1>(mbr, geometry::get<1>(box_point));
geometry::set<max_corner, 0>(mbr, geometry::get<0>(box_point));
geometry::set<max_corner, 1>(mbr, geometry::get<1>(box_point));
envelope_one_point
<
2, dimension<Point>::value
>::apply(normalized_point, mbr, strategy);
Strategy::apply(point, mbr);
}
};
@@ -104,26 +54,8 @@ namespace dispatch
template <typename Point>
struct envelope<Point, point_tag, cartesian_tag>
: detail::envelope::envelope_one_point<0, dimension<Point>::value>
{};
template <typename Point>
struct envelope<Point, point_tag, spherical_polar_tag>
: detail::envelope::envelope_point_on_spheroid
{};
template <typename Point>
struct envelope<Point, point_tag, spherical_equatorial_tag>
: detail::envelope::envelope_point_on_spheroid
{};
template <typename Point>
struct envelope<Point, point_tag, geographic_tag>
: detail::envelope::envelope_point_on_spheroid
struct envelope<Point, point_tag>
: detail::envelope::envelope_point
{};

View File

@@ -4,11 +4,12 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -23,23 +24,17 @@
#include <iterator>
#include <vector>
#include <boost/range.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/geometry/algorithms/is_empty.hpp>
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/algorithms/detail/envelope/range_of_boxes.hpp>
#include <boost/geometry/algorithms/detail/expand/box.hpp>
#include <boost/geometry/algorithms/detail/expand/point.hpp>
#include <boost/geometry/algorithms/detail/expand/segment.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
namespace boost { namespace geometry
{
@@ -53,7 +48,7 @@ namespace detail { namespace envelope
struct envelope_range
{
template <typename Iterator, typename Box, typename Strategy>
static inline void apply(Iterator first,
static inline void apply(Iterator it,
Iterator last,
Box& mbr,
Strategy const& strategy)
@@ -63,16 +58,21 @@ struct envelope_range
// initialize MBR
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
Iterator it = first;
if (it != last)
{
// initialize box with first element in range
dispatch::envelope<value_type>::apply(*it, mbr, strategy);
dispatch::envelope
<
value_type
>::apply(*it, mbr, strategy.get_element_envelope_strategy());
// consider now the remaining elements in the range (if any)
for (++it; it != last; ++it)
{
dispatch::expand<Box, value_type>::apply(mbr, *it, strategy);
dispatch::expand
<
Box, value_type
>::apply(mbr, *it, strategy.get_element_expand_strategy());
}
}
}
@@ -80,7 +80,7 @@ struct envelope_range
template <typename Range, typename Box, typename Strategy>
static inline void apply(Range const& range, Box& mbr, Strategy const& strategy)
{
return apply(boost::begin(range), boost::end(range), mbr, strategy);
return apply(Strategy::begin(range), Strategy::end(range), mbr, strategy);
}
};
@@ -94,86 +94,26 @@ struct envelope_multi_range
Box& mbr,
Strategy const& strategy)
{
typedef typename boost::range_iterator
<
MultiRange const
>::type iterator_type;
bool initialized = false;
for (iterator_type it = boost::begin(multirange);
it != boost::end(multirange);
++it)
{
if (! geometry::is_empty(*it))
{
if (initialized)
{
Box helper_mbr;
EnvelopePolicy::apply(*it, helper_mbr, strategy);
dispatch::expand<Box, Box>::apply(mbr, helper_mbr, strategy);
}
else
{
// compute the initial envelope
EnvelopePolicy::apply(*it, mbr, strategy);
initialized = true;
}
}
}
if (! initialized)
{
// if not already initialized, initialize MBR
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
}
apply(boost::begin(multirange), boost::end(multirange), mbr, strategy);
}
};
// implementation for multi-range on a spheroid (longitude is periodic)
template <typename EnvelopePolicy>
struct envelope_multi_range_on_spheroid
{
template <typename MultiRange, typename Box, typename Strategy>
static inline void apply(MultiRange const& multirange,
template <typename Iter, typename Box, typename Strategy>
static inline void apply(Iter it,
Iter last,
Box& mbr,
Strategy const& strategy)
{
typedef typename boost::range_iterator
<
MultiRange const
>::type iterator_type;
// due to the periodicity of longitudes we need to compute the boxes
// of all the single geometries and keep them in a container
std::vector<Box> boxes;
for (iterator_type it = boost::begin(multirange);
it != boost::end(multirange);
++it)
typename Strategy::template multi_state<Box> state;
for (; it != last; ++it)
{
if (! geometry::is_empty(*it))
{
Box helper_box;
EnvelopePolicy::apply(*it, helper_box, strategy);
boxes.push_back(helper_box);
Box helper_mbr;
EnvelopePolicy::apply(*it, helper_mbr, strategy);
state.apply(helper_mbr);
}
}
// now we need to compute the envelope of the range of boxes
// (cannot be done in an incremental fashion as in the
// Cartesian coordinate system)
// if all single geometries are empty no boxes have been found
// and the MBR is simply initialized
if (! boxes.empty())
{
envelope_range_of_boxes::apply(boxes, mbr, strategy);
}
else
{
initialize<Box, 0, dimension<Box>::value>::apply(mbr);
}
state.result(mbr);
}
};

View File

@@ -151,10 +151,8 @@ struct envelope_range_of_longitudes
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_range_of_boxes_by_expansion
{
template <typename RangeOfBoxes, typename Box, typename Strategy>
static inline void apply(RangeOfBoxes const& range_of_boxes,
Box& mbr,
Strategy const& strategy)
template <typename RangeOfBoxes, typename Box>
static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
{
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
@@ -198,14 +196,14 @@ struct envelope_range_of_boxes_by_expansion
min_corner,
Dimension,
DimensionCount
>::apply(mbr, *it, strategy);
>::apply(mbr, *it);
detail::expand::indexed_loop
<
max_corner,
Dimension,
DimensionCount
>::apply(mbr, *it, strategy);
>::apply(mbr, *it);
}
}
@@ -225,16 +223,14 @@ struct envelope_range_of_boxes
}
};
template <typename RangeOfBoxes, typename Box, typename Strategy>
static inline void apply(RangeOfBoxes const& range_of_boxes,
Box& mbr,
Strategy const& strategy)
template <typename RangeOfBoxes, typename Box>
static inline void apply(RangeOfBoxes const& range_of_boxes, Box& mbr)
{
// boxes in the range are assumed to be normalized already
typedef typename boost::range_value<RangeOfBoxes>::type box_type;
typedef typename coordinate_type<box_type>::type coordinate_type;
typedef typename coordinate_system<box_type>::type::units units_type;
typedef typename detail::cs_angular_units<box_type>::type units_type;
typedef typename boost::range_iterator
<
RangeOfBoxes const
@@ -326,7 +322,7 @@ struct envelope_range_of_boxes
envelope_range_of_boxes_by_expansion
<
2, dimension<Box>::value
>::apply(range_of_boxes, mbr, strategy);
>::apply(range_of_boxes, mbr);
}
};

View File

@@ -19,33 +19,17 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_ENVELOPE_SEGMENT_HPP
#include <cstddef>
#include <utility>
#include <boost/core/ignore_unused.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/geometries/helper_geometry.hpp>
#include <boost/geometry/formulas/meridian_segment.hpp>
#include <boost/geometry/formulas/vertex_latitude.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/envelope/point.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/detail/expand/point.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
@@ -53,385 +37,6 @@ namespace boost { namespace geometry
namespace detail { namespace envelope
{
template <typename CalculationType, typename CS_Tag>
struct envelope_segment_call_vertex_latitude
{
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& )
{
return geometry::formula::vertex_latitude<CalculationType, CS_Tag>
::apply(lat1, alp1);
}
};
template <typename CalculationType>
struct envelope_segment_call_vertex_latitude<CalculationType, geographic_tag>
{
template <typename T1, typename T2, typename Strategy>
static inline CalculationType apply(T1 const& lat1,
T2 const& alp1,
Strategy const& strategy)
{
return geometry::formula::vertex_latitude<CalculationType, geographic_tag>
::apply(lat1, alp1, strategy.model());
}
};
template <typename Units, typename CS_Tag>
struct envelope_segment_convert_polar
{
template <typename T>
static inline void pre(T & , T & ) {}
template <typename T>
static inline void post(T & , T & ) {}
};
template <typename Units>
struct envelope_segment_convert_polar<Units, spherical_polar_tag>
{
template <typename T>
static inline void pre(T & lat1, T & lat2)
{
lat1 = math::latitude_convert_ep<Units>(lat1);
lat2 = math::latitude_convert_ep<Units>(lat2);
}
template <typename T>
static inline void post(T & lat1, T & lat2)
{
lat1 = math::latitude_convert_ep<Units>(lat1);
lat2 = math::latitude_convert_ep<Units>(lat2);
std::swap(lat1, lat2);
}
};
template <typename CS_Tag>
class envelope_segment_impl
{
private:
// degrees or radians
template <typename CalculationType>
static inline void swap(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
{
std::swap(lon1, lon2);
std::swap(lat1, lat2);
}
// radians
template <typename CalculationType>
static inline bool contains_pi_half(CalculationType const& a1,
CalculationType const& a2)
{
// azimuths a1 and a2 are assumed to be in radians
BOOST_GEOMETRY_ASSERT(! math::equals(a1, a2));
static CalculationType const pi_half = math::half_pi<CalculationType>();
return (a1 < a2)
? (a1 < pi_half && pi_half < a2)
: (a1 > pi_half && pi_half > a2);
}
// radians or degrees
template <typename Units, typename CoordinateType>
static inline bool crosses_antimeridian(CoordinateType const& lon1,
CoordinateType const& lon2)
{
typedef math::detail::constants_on_spheroid
<
CoordinateType, Units
> constants;
return math::abs(lon1 - lon2) > constants::half_period(); // > pi
}
// degrees or radians
template <typename Units, typename CalculationType, typename Strategy>
static inline void compute_box_corners(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2,
CalculationType a1,
CalculationType a2,
Strategy const& strategy)
{
// coordinates are assumed to be in radians
BOOST_GEOMETRY_ASSERT(lon1 <= lon2);
boost::ignore_unused(lon1, lon2);
CalculationType lat1_rad = math::as_radian<Units>(lat1);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
if (math::equals(a1, a2))
{
// the segment must lie on the equator or is very short or is meridian
return;
}
if (lat1 > lat2)
{
std::swap(lat1, lat2);
std::swap(lat1_rad, lat2_rad);
std::swap(a1, a2);
}
if (contains_pi_half(a1, a2))
{
CalculationType p_max = envelope_segment_call_vertex_latitude
<CalculationType, CS_Tag>::apply(lat1_rad, a1, strategy);
CalculationType const mid_lat = lat1 + lat2;
if (mid_lat < 0)
{
// update using min latitude
CalculationType const lat_min_rad = -p_max;
CalculationType const lat_min
= math::from_radian<Units>(lat_min_rad);
if (lat1 > lat_min)
{
lat1 = lat_min;
}
}
else
{
// update using max latitude
CalculationType const lat_max_rad = p_max;
CalculationType const lat_max
= math::from_radian<Units>(lat_max_rad);
if (lat2 < lat_max)
{
lat2 = lat_max;
}
}
}
}
template <typename Units, typename CalculationType>
static inline void special_cases(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2)
{
typedef math::detail::constants_on_spheroid
<
CalculationType, Units
> constants;
bool is_pole1 = math::equals(math::abs(lat1), constants::max_latitude());
bool is_pole2 = math::equals(math::abs(lat2), constants::max_latitude());
if (is_pole1 && is_pole2)
{
// both points are poles; nothing more to do:
// longitudes are already normalized to 0
// but just in case
lon1 = 0;
lon2 = 0;
}
else if (is_pole1 && !is_pole2)
{
// first point is a pole, second point is not:
// make the longitude of the first point the same as that
// of the second point
lon1 = lon2;
}
else if (!is_pole1 && is_pole2)
{
// second point is a pole, first point is not:
// make the longitude of the second point the same as that
// of the first point
lon2 = lon1;
}
if (lon1 == lon2)
{
// segment lies on a meridian
if (lat1 > lat2)
{
std::swap(lat1, lat2);
}
return;
}
BOOST_GEOMETRY_ASSERT(!is_pole1 && !is_pole2);
if (lon1 > lon2)
{
swap(lon1, lat1, lon2, lat2);
}
if (crosses_antimeridian<Units>(lon1, lon2))
{
lon1 += constants::period();
swap(lon1, lat1, lon2, lat2);
}
}
template
<
typename Units,
typename CalculationType,
typename Box
>
static inline void create_box(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr)
{
typedef typename coordinate_type<Box>::type box_coordinate_type;
typedef typename helper_geometry
<
Box, box_coordinate_type, Units
>::type helper_box_type;
helper_box_type helper_mbr;
geometry::set
<
min_corner, 0
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon1));
geometry::set
<
min_corner, 1
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat1));
geometry::set
<
max_corner, 0
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lon2));
geometry::set
<
max_corner, 1
>(helper_mbr, boost::numeric_cast<box_coordinate_type>(lat2));
transform_units(helper_mbr, mbr);
}
template <typename Units, typename CalculationType, typename Strategy>
static inline void apply(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2,
Strategy const& strategy)
{
special_cases<Units>(lon1, lat1, lon2, lat2);
CalculationType lon1_rad = math::as_radian<Units>(lon1);
CalculationType lat1_rad = math::as_radian<Units>(lat1);
CalculationType lon2_rad = math::as_radian<Units>(lon2);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
CalculationType alp1, alp2;
strategy.apply(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp1, alp2);
compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
}
template <typename Units, typename CalculationType, typename Strategy>
static inline void apply(CalculationType& lon1,
CalculationType& lat1,
CalculationType& lon2,
CalculationType& lat2,
Strategy const& strategy,
CalculationType alp1)
{
special_cases<Units>(lon1, lat1, lon2, lat2);
CalculationType lon1_rad = math::as_radian<Units>(lon1);
CalculationType lat1_rad = math::as_radian<Units>(lat1);
CalculationType lon2_rad = math::as_radian<Units>(lon2);
CalculationType lat2_rad = math::as_radian<Units>(lat2);
CalculationType alp2;
strategy.apply_reverse(lon1_rad, lat1_rad, lon2_rad, lat2_rad, alp2);
compute_box_corners<Units>(lon1, lat1, lon2, lat2, alp1, alp2, strategy);
}
public:
template
<
typename Units,
typename CalculationType,
typename Box,
typename Strategy
>
static inline void apply(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr,
Strategy const& strategy)
{
typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
convert_polar::pre(lat1, lat2);
apply<Units>(lon1, lat1, lon2, lat2, strategy);
convert_polar::post(lat1, lat2);
create_box<Units>(lon1, lat1, lon2, lat2, mbr);
}
template
<
typename Units,
typename CalculationType,
typename Box,
typename Strategy
>
static inline void apply(CalculationType lon1,
CalculationType lat1,
CalculationType lon2,
CalculationType lat2,
Box& mbr,
Strategy const& strategy,
CalculationType alp1)
{
typedef envelope_segment_convert_polar<Units, typename cs_tag<Box>::type> convert_polar;
convert_polar::pre(lat1, lat2);
apply<Units>(lon1, lat1, lon2, lat2, strategy, alp1);
convert_polar::post(lat1, lat2);
create_box<Units>(lon1, lat1, lon2, lat2, mbr);
}
};
template <std::size_t Dimension, std::size_t DimensionCount>
struct envelope_one_segment
{
template<typename Point, typename Box, typename Strategy>
static inline void apply(Point const& p1,
Point const& p2,
Box& mbr,
Strategy const& strategy)
{
envelope_one_point<Dimension, DimensionCount>::apply(p1, mbr, strategy);
detail::expand::point_loop
<
Dimension,
DimensionCount
>::apply(mbr, p2, strategy);
}
};
template <std::size_t DimensionCount>
struct envelope_segment
{
@@ -441,12 +46,7 @@ struct envelope_segment
Box& mbr,
Strategy const& strategy)
{
// first compute the envelope range for the first two coordinates
strategy.apply(p1, p2, mbr);
// now compute the envelope range for coordinates of
// dimension 2 and higher
envelope_one_segment<2, DimensionCount>::apply(p1, p2, mbr, strategy);
}
template <typename Segment, typename Box, typename Strategy>

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015, 2016, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2014-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
@@ -64,13 +64,9 @@ template
struct point_point
{
template <typename Point1, typename Point2, typename Strategy>
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& strategy)
static inline bool apply(Point1 const& point1, Point2 const& point2, Strategy const& )
{
return ! detail::disjoint::point_point
<
Point1, Point2,
Dimension, DimensionCount
>::apply(point1, point2, strategy);
return Strategy::apply(point1, point2);
}
};
@@ -108,20 +104,28 @@ struct box_box<DimensionCount, DimensionCount>
struct segment_segment
{
template <typename Segment1, typename Segment2, typename Strategy>
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2, Strategy const& )
static inline bool apply(Segment1 const& segment1, Segment2 const& segment2,
Strategy const& strategy)
{
typename Strategy::point_in_point_strategy_type const&
pt_pt_strategy = strategy.get_point_in_point_strategy();
return equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
indexed_point_view<Segment2 const, 0>(segment2) )
indexed_point_view<Segment2 const, 0>(segment2),
pt_pt_strategy)
? equals::equals_point_point(
indexed_point_view<Segment1 const, 1>(segment1),
indexed_point_view<Segment2 const, 1>(segment2) )
indexed_point_view<Segment2 const, 1>(segment2),
pt_pt_strategy)
: ( equals::equals_point_point(
indexed_point_view<Segment1 const, 0>(segment1),
indexed_point_view<Segment2 const, 1>(segment2) )
indexed_point_view<Segment2 const, 1>(segment2),
pt_pt_strategy)
&& equals::equals_point_point(
indexed_point_view<Segment1 const, 1>(segment1),
indexed_point_view<Segment2 const, 0>(segment2) )
indexed_point_view<Segment2 const, 0>(segment2),
pt_pt_strategy)
);
}
};

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-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
@@ -21,13 +21,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace equals
{
@@ -36,17 +33,16 @@ namespace detail { namespace equals
\brief Internal utility function to detect of points are disjoint
\note To avoid circular references
*/
template <typename Point1, typename Point2>
inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
template <typename Point1, typename Point2, typename Strategy>
inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
Strategy const& )
{
return ! detail::disjoint::disjoint_point_point(point1, point2);
return Strategy::apply(point1, point2);
}
}} // namespace detail::equals
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_EQUALS_POINT_POINT_HPP

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -19,52 +19,19 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_BOX_HPP
#include <cstddef>
#include <algorithm>
#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>
#include <boost/geometry/core/tags.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/expand_box.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace expand
{
struct box_on_spheroid
{
template <typename BoxOut, typename BoxIn, typename Strategy>
static inline void apply(BoxOut& box_out,
BoxIn const& box_in,
Strategy const& strategy)
{
// normalize both boxes and convert box-in to be of type of box-out
BoxOut mbrs[2];
detail::envelope::envelope_box_on_spheroid::apply(box_in, mbrs[0], strategy);
detail::envelope::envelope_box_on_spheroid::apply(box_out, mbrs[1], strategy);
// compute the envelope of the two boxes
detail::envelope::envelope_range_of_boxes::apply(mbrs, box_out, strategy);
}
};
}} // namespace detail::expand
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
@@ -73,59 +40,23 @@ namespace dispatch
// Box + box -> new box containing two input boxes
template
<
typename BoxOut, typename BoxIn,
typename CSTagOut, typename CSTag
typename BoxOut, typename BoxIn
>
struct expand
<
BoxOut, BoxIn,
box_tag, box_tag,
CSTagOut, CSTag
box_tag, box_tag
>
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
(types<CSTagOut, CSTag>()));
template <typename Strategy>
static inline void apply(BoxOut& box_out,
BoxIn const& box_in,
Strategy const& )
{
Strategy::apply(box_out, box_in);
}
};
template <typename BoxOut, typename BoxIn>
struct expand
<
BoxOut, BoxIn,
box_tag, box_tag,
cartesian_tag, cartesian_tag
> : detail::expand::expand_indexed
<
0, dimension<BoxIn>::value
>
{};
template <typename BoxOut, typename BoxIn>
struct expand
<
BoxOut, BoxIn,
box_tag, box_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::expand::box_on_spheroid
{};
template <typename BoxOut, typename BoxIn>
struct expand
<
BoxOut, BoxIn,
box_tag, box_tag,
spherical_polar_tag, spherical_polar_tag
> : detail::expand::box_on_spheroid
{};
template <typename BoxOut, typename BoxIn>
struct expand
<
BoxOut, BoxIn,
box_tag, box_tag,
geographic_tag, geographic_tag
> : detail::expand::box_on_spheroid
{};
} // namespace dispatch

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -48,8 +48,8 @@ template
>
struct indexed_loop
{
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box& box, Geometry const& source, Strategy const& strategy)
template <typename Box, typename Geometry>
static inline void apply(Box& box, Geometry const& source)
{
typedef typename select_coordinate_type
<
@@ -75,7 +75,7 @@ struct indexed_loop
indexed_loop
<
Index, Dimension + 1, DimensionCount
>::apply(box, source, strategy);
>::apply(box, source);
}
};
@@ -86,8 +86,8 @@ struct indexed_loop
Index, DimensionCount, DimensionCount
>
{
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box&, Geometry const&, Strategy const&) {}
template <typename Box, typename Geometry>
static inline void apply(Box&, Geometry const&) {}
};
@@ -96,20 +96,18 @@ struct indexed_loop
template <std::size_t Dimension, std::size_t DimensionCount>
struct expand_indexed
{
template <typename Box, typename Geometry, typename Strategy>
static inline void apply(Box& box,
Geometry const& geometry,
Strategy const& strategy)
template <typename Box, typename Geometry>
static inline void apply(Box& box, Geometry const& geometry)
{
indexed_loop
<
0, Dimension, DimensionCount
>::apply(box, geometry, strategy);
>::apply(box, geometry);
indexed_loop
<
1, Dimension, DimensionCount
>::apply(box, geometry, strategy);
>::apply(box, geometry);
}
};

View File

@@ -5,11 +5,12 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016.
// Modifications copyright (c) 2015-2016, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -25,16 +26,17 @@
#include <boost/variant/static_visitor.hpp>
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/algorithms/dispatch/expand.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/strategies/expand.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
namespace boost { namespace geometry
{
@@ -58,14 +60,11 @@ struct expand
Geometry const& geometry,
default_strategy)
{
typedef typename point_type<Geometry>::type point_type;
typedef typename coordinate_type<point_type>::type coordinate_type;
typedef typename strategy::envelope::services::default_strategy
<
typename cs_tag<point_type>::type,
coordinate_type
>::type strategy_type;
typedef typename strategy::expand::services::default_strategy
<
typename tag<Geometry>::type,
typename cs_tag<Geometry>::type
>::type strategy_type;
dispatch::expand<Box, Geometry>::apply(box, geometry, strategy_type());
}

View File

@@ -22,263 +22,25 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_EXPAND_POINT_HPP
#include <cstddef>
#include <algorithm>
#include <functional>
#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>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/is_inverse_spheroidal_coordinates.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/dispatch/expand.hpp>
#include <boost/geometry/core/tags.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/expand_point.hpp>
#include <boost/geometry/strategies/spherical/expand_point.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace expand
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct point_loop
{
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box& box, Point const& source, Strategy const& strategy)
{
typedef typename select_coordinate_type
<
Point, Box
>::type coordinate_type;
std::less<coordinate_type> less;
std::greater<coordinate_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<Dimension + 1, DimensionCount>::apply(box, source, strategy);
}
};
template <std::size_t DimensionCount>
struct point_loop<DimensionCount, DimensionCount>
{
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box&, Point const&, Strategy const&) {}
};
// implementation for the spherical and geographic coordinate systems
template <std::size_t DimensionCount, bool IsEquatorial = true>
struct point_loop_on_spheroid
{
template <typename Box, typename Point, typename Strategy>
static inline void apply(Box& box,
Point const& point,
Strategy const& strategy)
{
typedef typename point_type<Box>::type box_point_type;
typedef typename coordinate_type<Box>::type box_coordinate_type;
typedef typename coordinate_system<Box>::type::units units_type;
typedef math::detail::constants_on_spheroid
<
box_coordinate_type,
units_type
> constants;
// normalize input point and input box
Point p_normalized = detail::return_normalized<Point>(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);
if (is_inverse_spheroidal_coordinates(box))
{
geometry::set_from_radian<min_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
geometry::set_from_radian<min_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
geometry::set_from_radian<max_corner, 0>(box, geometry::get_as_radian<0>(p_normalized));
geometry::set_from_radian<max_corner, 1>(box, geometry::get_as_radian<1>(p_normalized));
} else {
detail::normalize(box, box);
box_coordinate_type p_lon = geometry::get<0>(box_point);
box_coordinate_type p_lat = geometry::get<1>(box_point);
typename coordinate_type<Box>::type
b_lon_min = geometry::get<min_corner, 0>(box),
b_lat_min = geometry::get<min_corner, 1>(box),
b_lon_max = geometry::get<max_corner, 0>(box),
b_lat_max = geometry::get<max_corner, 1>(box);
if (math::is_latitude_pole<units_type, IsEquatorial>(p_lat))
{
// the point of expansion is the either the north or the
// 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
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;
}
if (math::equals(b_lat_min, b_lat_max)
&& math::is_latitude_pole<units_type, IsEquatorial>(b_lat_min))
{
// the box degenerates to either the north or the south pole;
// 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
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;
}
// update latitudes
b_lat_min = (std::min)(b_lat_min, p_lat);
b_lat_max = (std::max)(b_lat_max, p_lat);
// update longitudes
if (math::smaller(p_lon, b_lon_min))
{
box_coordinate_type p_lon_shifted = p_lon + constants::period();
if (math::larger(p_lon_shifted, b_lon_max))
{
// here we could check using: ! math::larger(.., ..)
if (math::smaller(b_lon_min - p_lon, p_lon_shifted - b_lon_max))
{
b_lon_min = p_lon;
}
else
{
b_lon_max = p_lon_shifted;
}
}
}
else if (math::larger(p_lon, b_lon_max))
{
// in this case, and since p_lon is normalized in the range
// (-180, 180], we must have that b_lon_max <= 180
if (b_lon_min < 0
&& math::larger(p_lon - b_lon_max,
constants::period() - p_lon + b_lon_min))
{
b_lon_min = p_lon;
b_lon_max += constants::period();
}
else
{
b_lon_max = p_lon;
}
}
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
<
2, DimensionCount
>::apply(box, point, strategy);
}
};
}} // namespace detail::expand
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
// Box + point -> new box containing also point
template
<
typename BoxOut, typename Point,
typename CSTagOut, typename CSTag
>
struct expand
<
BoxOut, Point,
box_tag, point_tag,
CSTagOut, CSTag
>
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
(types<CSTagOut, CSTag>()));
};
template <typename BoxOut, typename Point>
struct expand
<
BoxOut, Point,
box_tag, point_tag,
cartesian_tag, cartesian_tag
> : detail::expand::point_loop
<
0, dimension<Point>::value
>
{};
template <typename BoxOut, typename Point>
struct expand
<
BoxOut, Point,
box_tag, point_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::expand::point_loop_on_spheroid
<
dimension<Point>::value
>
{};
template <typename BoxOut, typename Point>
struct expand
<
BoxOut, Point,
box_tag, point_tag,
spherical_polar_tag, spherical_polar_tag
> : detail::expand::point_loop_on_spheroid
<
dimension<Point>::value,
false
>
{};
template
<
typename BoxOut, typename Point
@@ -286,13 +48,18 @@ template
struct expand
<
BoxOut, Point,
box_tag, point_tag,
geographic_tag, geographic_tag
> : detail::expand::point_loop_on_spheroid
<
dimension<Point>::value
>
{};
box_tag, point_tag
>
{
template <typename Strategy>
static inline void apply(BoxOut& box,
Point const& point,
Strategy const& )
{
Strategy::apply(box, point);
}
};
} // namespace dispatch

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -19,79 +19,26 @@
#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/indexed.hpp>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/dispatch/expand.hpp>
#include <boost/geometry/core/tags.hpp>
// For backward compatibility
#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
#include <boost/geometry/strategies/geographic/expand_segment.hpp>
#include <boost/geometry/strategies/spherical/expand_segment.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace expand
{
struct segment
{
template <typename Box, typename Segment, typename Strategy>
static inline void apply(Box& box,
Segment const& segment,
Strategy const& strategy)
{
Box mbrs[2];
// compute the envelope of the segment
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_segment
<
dimension<Segment>::value
>::apply(p[0], p[1], mbrs[0], strategy);
// normalize the box
detail::envelope::envelope_box_on_spheroid::apply(box, mbrs[1], strategy);
// compute the envelope of the two boxes
detail::envelope::envelope_range_of_boxes::apply(mbrs, box, strategy);
}
};
}} // namespace detail::expand
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename Box, typename Segment,
typename CSTagOut, typename CSTag
>
struct expand
<
Box, Segment,
box_tag, segment_tag,
CSTagOut, CSTag
>
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THESE_COORDINATE_SYSTEMS,
(types<CSTagOut, CSTag>()));
};
template
<
typename Box, typename Segment
@@ -99,40 +46,19 @@ template
struct expand
<
Box, Segment,
box_tag, segment_tag,
cartesian_tag, cartesian_tag
> : detail::expand::expand_indexed
<
0, dimension<Segment>::value
>
{};
box_tag, segment_tag
>
{
template <typename Strategy>
static inline void apply(Box& box,
Segment const& segment,
Strategy const& strategy)
{
boost::ignore_unused(strategy);
strategy.apply(box, segment);
}
};
template <typename Box, typename Segment>
struct expand
<
Box, Segment,
box_tag, segment_tag,
spherical_polar_tag, spherical_polar_tag
> : detail::expand::segment
{};
template <typename Box, typename Segment>
struct expand
<
Box, Segment,
box_tag, segment_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::expand::segment
{};
template <typename Box, typename Segment>
struct expand
<
Box, Segment,
box_tag, segment_tag,
geographic_tag, geographic_tag
> : detail::expand::segment
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH

View File

@@ -116,19 +116,12 @@ private:
}
// prepare strategies
typedef typename std::iterator_traits<PolygonIterator>::value_type polygon_type;
typedef typename Strategy::template point_in_geometry_strategy
<
polygon_type, polygon_type
>::type within_strategy_type;
within_strategy_type const within_strategy
= strategy.template get_point_in_geometry_strategy<polygon_type, polygon_type>();
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if polygons are disjoint from each other
typename base::template item_visitor_type<within_strategy_type> item_visitor(within_strategy);
typename base::template item_visitor_type<Strategy> item_visitor(strategy);
geometry::partition
<

View File

@@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// 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
@@ -217,26 +217,19 @@ protected:
, m_strategy(strategy)
{}
template <typename Item>
inline bool is_within(Item const& first, Item const& second)
{
typename point_type<Polygon>::type point;
typedef detail::point_on_border::point_on_range<true> pob;
// TODO: this should check for a point on the interior, instead
// of on border. Or it should check using the overlap function.
return pob::apply(point, points_begin(first), points_end(first))
&& geometry::within(point, second, m_strategy);
}
template <typename Iterator, typename Box>
inline bool apply(partition_item<Iterator, Box> const& item1,
partition_item<Iterator, Box> const& item2)
{
if (! items_overlap
&& (is_within(*item1.get(), *item2.get())
|| is_within(*item2.get(), *item1.get())))
typedef boost::mpl::vector
<
geometry::de9im::static_mask<'T'>,
geometry::de9im::static_mask<'*', 'T'>,
geometry::de9im::static_mask<'*', '*', '*', 'T'>
> relate_mask_t;
if ( ! items_overlap
&& geometry::relate(*item1.get(), *item2.get(), relate_mask_t(), m_strategy) )
{
items_overlap = true;
return false; // interrupt
@@ -326,19 +319,13 @@ protected:
}
// prepare strategies
typedef typename Strategy::template point_in_geometry_strategy
<
inter_ring_type, inter_ring_type
>::type in_interior_strategy_type;
in_interior_strategy_type const in_interior_strategy
= strategy.template get_point_in_geometry_strategy<inter_ring_type, inter_ring_type>();
typedef typename Strategy::envelope_strategy_type envelope_strategy_type;
envelope_strategy_type const envelope_strategy
= strategy.get_envelope_strategy();
// call partition to check if interior rings are disjoint from
// each other
item_visitor_type<in_interior_strategy_type> item_visitor(in_interior_strategy);
item_visitor_type<Strategy> item_visitor(strategy);
geometry::partition
<

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2015-2017, Oracle and/or its affiliates.
// Copyright (c) 2015-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
@@ -11,298 +11,31 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_NORMALIZE_HPP
#include <cstddef>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/geometry/core/access.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/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/normalize_spheroidal_box_coordinates.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
// For backward compatibility
#include <boost/geometry/strategies/normalize.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace normalization
{
struct do_nothing
{
template <typename GeometryIn, typename GeometryOut>
static inline void apply(GeometryIn const&, GeometryOut&)
{
}
};
template <std::size_t Dimension, std::size_t DimensionCount>
struct assign_loop
{
template <typename CoordinateType, typename PointIn, typename PointOut>
static inline void apply(CoordinateType const& longitude,
CoordinateType const& latitude,
PointIn const& point_in,
PointOut& point_out)
{
geometry::set<Dimension>(point_out, boost::numeric_cast
<
typename coordinate_type<PointOut>::type
>(geometry::get<Dimension>(point_in)));
assign_loop
<
Dimension + 1, DimensionCount
>::apply(longitude, latitude, point_in, point_out);
}
};
template <std::size_t DimensionCount>
struct assign_loop<DimensionCount, DimensionCount>
{
template <typename CoordinateType, typename PointIn, typename PointOut>
static inline void apply(CoordinateType const&,
CoordinateType const&,
PointIn const&,
PointOut&)
{
}
};
template <std::size_t DimensionCount>
struct assign_loop<0, DimensionCount>
{
template <typename CoordinateType, typename PointIn, typename PointOut>
static inline void apply(CoordinateType const& longitude,
CoordinateType const& latitude,
PointIn const& point_in,
PointOut& point_out)
{
geometry::set<0>(point_out, boost::numeric_cast
<
typename coordinate_type<PointOut>::type
>(longitude));
assign_loop
<
1, DimensionCount
>::apply(longitude, latitude, point_in, point_out);
}
};
template <std::size_t DimensionCount>
struct assign_loop<1, DimensionCount>
{
template <typename CoordinateType, typename PointIn, typename PointOut>
static inline void apply(CoordinateType const& longitude,
CoordinateType const& latitude,
PointIn const& point_in,
PointOut& point_out)
{
geometry::set<1>(point_out, boost::numeric_cast
<
typename coordinate_type<PointOut>::type
>(latitude));
assign_loop
<
2, DimensionCount
>::apply(longitude, latitude, point_in, point_out);
}
};
template <typename PointIn, typename PointOut, bool IsEquatorial = true>
struct normalize_point
{
static inline void apply(PointIn const& point_in, PointOut& point_out)
{
typedef typename coordinate_type<PointIn>::type in_coordinate_type;
in_coordinate_type longitude = geometry::get<0>(point_in);
in_coordinate_type latitude = geometry::get<1>(point_in);
math::normalize_spheroidal_coordinates
<
typename coordinate_system<PointIn>::type::units,
IsEquatorial,
in_coordinate_type
>(longitude, latitude);
assign_loop
<
0, dimension<PointIn>::value
>::apply(longitude, latitude, point_in, point_out);
}
};
template <typename BoxIn, typename BoxOut, bool IsEquatorial = true>
class normalize_box
{
template <typename UnitsIn, typename UnitsOut, typename CoordinateInType>
static inline void apply_to_coordinates(CoordinateInType& lon_min,
CoordinateInType& lat_min,
CoordinateInType& lon_max,
CoordinateInType& lat_max,
BoxIn const& box_in,
BoxOut& box_out)
{
detail::indexed_point_view<BoxOut, min_corner> p_min_out(box_out);
assign_loop
<
0, dimension<BoxIn>::value
>::apply(lon_min,
lat_min,
detail::indexed_point_view
<
BoxIn const, min_corner
>(box_in),
p_min_out);
detail::indexed_point_view<BoxOut, max_corner> p_max_out(box_out);
assign_loop
<
0, dimension<BoxIn>::value
>::apply(lon_max,
lat_max,
detail::indexed_point_view
<
BoxIn const, max_corner
>(box_in),
p_max_out);
}
public:
static inline void apply(BoxIn const& box_in, BoxOut& box_out)
{
typedef typename coordinate_type<BoxIn>::type in_coordinate_type;
in_coordinate_type lon_min = geometry::get<min_corner, 0>(box_in);
in_coordinate_type lat_min = geometry::get<min_corner, 1>(box_in);
in_coordinate_type lon_max = geometry::get<max_corner, 0>(box_in);
in_coordinate_type lat_max = geometry::get<max_corner, 1>(box_in);
math::normalize_spheroidal_box_coordinates
<
typename coordinate_system<BoxIn>::type::units,
IsEquatorial,
in_coordinate_type
>(lon_min, lat_min, lon_max, lat_max);
apply_to_coordinates
<
typename coordinate_system<BoxIn>::type::units,
typename coordinate_system<BoxOut>::type::units
>(lon_min, lat_min, lon_max, lat_max, box_in, box_out);
}
};
}} // namespace detail::normalization
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename GeometryIn,
typename GeometryOut,
typename TagIn = typename tag<GeometryIn>::type,
typename TagOut = typename tag<GeometryOut>::type,
typename CSTagIn = typename cs_tag<GeometryIn>::type,
typename CSTagOut = typename cs_tag<GeometryOut>::type
>
struct normalize : detail::normalization::do_nothing
{};
template <typename PointIn, typename PointOut>
struct normalize
<
PointIn, PointOut, point_tag, point_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::normalization::normalize_point<PointIn, PointOut>
{};
template <typename PointIn, typename PointOut>
struct normalize
<
PointIn, PointOut, point_tag, point_tag,
spherical_polar_tag, spherical_polar_tag
> : detail::normalization::normalize_point<PointIn, PointOut, false>
{};
template <typename PointIn, typename PointOut>
struct normalize
<
PointIn, PointOut, point_tag, point_tag, geographic_tag, geographic_tag
> : detail::normalization::normalize_point<PointIn, PointOut>
{};
template <typename BoxIn, typename BoxOut>
struct normalize
<
BoxIn, BoxOut, box_tag, box_tag,
spherical_equatorial_tag, spherical_equatorial_tag
> : detail::normalization::normalize_box<BoxIn, BoxOut>
{};
template <typename BoxIn, typename BoxOut>
struct normalize
<
BoxIn, BoxOut, box_tag, box_tag,
spherical_polar_tag, spherical_polar_tag
> : detail::normalization::normalize_box<BoxIn, BoxOut, false>
{};
template <typename BoxIn, typename BoxOut>
struct normalize
<
BoxIn, BoxOut, box_tag, box_tag, geographic_tag, geographic_tag
> : detail::normalization::normalize_box<BoxIn, BoxOut>
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename GeometryIn, typename GeometryOut>
inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out)
template <typename GeometryIn, typename GeometryOut, typename Strategy>
inline void normalize(GeometryIn const& geometry_in, GeometryOut& geometry_out, Strategy const& )
{
dispatch::normalize
<
GeometryIn, GeometryOut
>::apply(geometry_in, geometry_out);
Strategy::apply(geometry_in, geometry_out);
}
template <typename GeometryOut, typename GeometryIn>
inline GeometryOut return_normalized(GeometryIn const& geometry_in)
template <typename GeometryOut, typename GeometryIn, typename Strategy>
inline GeometryOut return_normalized(GeometryIn const& geometry_in, Strategy const& strategy)
{
GeometryOut geometry_out;
detail::normalize(geometry_in, geometry_out);
detail::normalize(geometry_in, geometry_out, strategy);
return geometry_out;
}

View File

@@ -2,6 +2,11 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -10,11 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPLICATES_HPP
#include <boost/range.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@@ -26,11 +30,24 @@ namespace detail { namespace overlay
{
template <typename Range, typename Point>
inline void append_no_duplicates(Range& range, Point const& point, bool force = false)
inline void append_with_duplicates(Range& range, Point const& point)
{
if (boost::size(range) == 0
|| force
|| ! geometry::detail::equals::equals_point_point(*(boost::end(range)-1), point))
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
std::cout << " add: ("
<< geometry::get<0>(point) << ", " << geometry::get<1>(point) << ")"
<< std::endl;
#endif
geometry::append(range, point);
}
template <typename Range, typename Point, typename EqPPStrategy>
inline void append_no_duplicates(Range& range, Point const& point,
EqPPStrategy const& strategy)
{
if ( boost::empty(range)
|| ! geometry::detail::equals::equals_point_point(geometry::range::back(range),
point,
strategy) )
{
#ifdef BOOST_GEOMETRY_DEBUG_INTERSECTION
std::cout << " add: ("

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017, 2018.
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -15,6 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_APPEND_NO_DUPS_OR_SPIKES_HPP
#include <boost/range.hpp>
#include <boost/static_assert.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/detail/point_is_spike_or_equal.hpp>
@@ -33,12 +34,13 @@ namespace detail { namespace overlay
{
// TODO: move this / rename this
template <typename Point1, typename Point2, typename RobustPolicy>
template <typename Point1, typename Point2, typename EqualsStrategy, typename RobustPolicy>
inline bool points_equal_or_close(Point1 const& point1,
Point2 const& point2,
EqualsStrategy const& strategy,
RobustPolicy const& robust_policy)
{
if (detail::equals::equals_point_point(point1, point2))
if (detail::equals::equals_point_point(point1, point2, strategy))
{
return true;
}
@@ -59,7 +61,14 @@ inline bool points_equal_or_close(Point1 const& point1,
geometry::recalculate(point1_rob, point1, robust_policy);
geometry::recalculate(point2_rob, point2, robust_policy);
return detail::equals::equals_point_point(point1_rob, point2_rob);
// Only if this is the case the same strategy can be used.
BOOST_STATIC_ASSERT((boost::is_same
<
typename geometry::cs_tag<Point1>::type,
typename geometry::cs_tag<robust_point_type>::type
>::value));
return detail::equals::equals_point_point(point1_rob, point2_rob, strategy);
}
@@ -76,8 +85,10 @@ inline void append_no_dups_or_spikes(Range& range, Point const& point,
// The code below this condition checks all spikes/dups
// for geometries >= 3 points.
// So we have to check the first potential duplicate differently
if (boost::size(range) == 1
&& points_equal_or_close(*(boost::begin(range)), point, robust_policy))
if ( boost::size(range) == 1
&& points_equal_or_close(*(boost::begin(range)), point,
strategy.get_equals_point_point_strategy(),
robust_policy) )
{
return;
}
@@ -113,8 +124,10 @@ inline void append_no_collinear(Range& range, Point const& point,
// The code below this condition checks all spikes/dups
// for geometries >= 3 points.
// So we have to check the first potential duplicate differently
if (boost::size(range) == 1
&& points_equal_or_close(*(boost::begin(range)), point, robust_policy))
if ( boost::size(range) == 1
&& points_equal_or_close(*(boost::begin(range)), point,
strategy.get_equals_point_point_strategy(),
robust_policy) )
{
return;
}

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@@ -134,12 +134,14 @@ struct ring_info_helper_get_box
}
};
template <typename DisjointBoxBoxStrategy>
struct ring_info_helper_ovelaps_box
{
template <typename Box, typename InputItem>
static inline bool apply(Box const& box, InputItem const& item)
{
return ! geometry::detail::disjoint::disjoint_box_box(box, item.envelope);
return ! geometry::detail::disjoint::disjoint_box_box(
box, item.envelope, DisjointBoxBoxStrategy());
}
};
@@ -327,11 +329,16 @@ inline void assign_parents(Geometry1 const& geometry1,
Strategy
> visitor(geometry1, geometry2, collection, ring_map, strategy, check_for_orientation);
typedef ring_info_helper_ovelaps_box
<
typename Strategy::disjoint_box_box_strategy_type
> overlaps_box_type;
geometry::partition
<
box_type
>::apply(vector, visitor, ring_info_helper_get_box(),
ring_info_helper_ovelaps_box());
overlaps_box_type());
}
if (check_for_orientation)

View File

@@ -2,10 +2,11 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2018.
// Modifications copyright (c) 2015-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,6 +25,8 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/geometries/segment.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
namespace boost { namespace geometry
{
@@ -83,6 +86,15 @@ private:
public:
// TODO: Temporary, this strategy should be moved, it is cartesian-only
typedef strategy::within::cartesian_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
inline bool clip_segment(Box const& b, segment_type& s, bool& sp1_clipped, bool& sp2_clipped) const
{
typedef typename select_coordinate_type<Box, Point>::type coordinate_type;
@@ -224,9 +236,10 @@ OutputIterator clip_range_with_box(Box const& b, Range const& range,
// b. Add p1 only if it is the first point, then add p2
if (boost::empty(line_out))
{
detail::overlay::append_no_duplicates(line_out, p1, true);
detail::overlay::append_with_duplicates(line_out, p1);
}
detail::overlay::append_no_duplicates(line_out, p2);
detail::overlay::append_no_duplicates(line_out, p2,
strategy.get_equals_point_point_strategy());
// c. If c2 is clipped, finish the line
if (c2)

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017, 2018.
// Modifications 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
@@ -137,11 +137,11 @@ private:
template <typename RangeOut, typename Point, typename SideStrategy, typename RobustPolicy>
static inline void append_to_output(RangeOut& current_output,
Point const& point,
SideStrategy const&,
SideStrategy const& strategy,
RobustPolicy const&,
boost::false_type const&)
{
detail::overlay::append_no_duplicates(current_output, point);
detail::overlay::append_no_duplicates(current_output, point, strategy.get_equals_point_point_strategy());
}
public:

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017, 2018.
// Modifications 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
@@ -159,7 +159,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
typename SideStrategy,
typename Strategy,
typename RobustPolicy
>
static inline void enter(LineStringOut& current_piece,
@@ -167,13 +167,13 @@ struct action_selector<overlay_intersection, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type , Point const& point,
Operation const& operation,
SideStrategy const& ,
Strategy const& strategy,
RobustPolicy const& ,
OutputIterator& )
{
// On enter, append the intersection point and remember starting point
// TODO: we don't check on spikes for linestrings (?). Consider this.
detail::overlay::append_no_duplicates(current_piece, point);
detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
segment_id = operation.seg_id;
}
@@ -184,7 +184,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
typename SideStrategy,
typename Strategy,
typename RobustPolicy
>
static inline void leave(LineStringOut& current_piece,
@@ -192,7 +192,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& ,
SideStrategy const& strategy,
Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{
@@ -202,7 +202,7 @@ struct action_selector<overlay_intersection, RemoveSpikes>
<
false, RemoveSpikes
>::apply(linestring, segment_id, index, strategy, robust_policy, current_piece);
detail::overlay::append_no_duplicates(current_piece, point);
detail::overlay::append_no_duplicates(current_piece, point, strategy.get_equals_point_point_strategy());
if (::boost::size(current_piece) > 1)
{
*out++ = current_piece;
@@ -260,7 +260,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
typename SideStrategy,
typename Strategy,
typename RobustPolicy
>
static inline void enter(LineStringOut& current_piece,
@@ -268,7 +268,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& operation,
SideStrategy const& strategy,
Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{
@@ -283,7 +283,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
typename LineString,
typename Point,
typename Operation,
typename SideStrategy,
typename Strategy,
typename RobustPolicy
>
static inline void leave(LineStringOut& current_piece,
@@ -291,7 +291,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
segment_identifier& segment_id,
signed_size_type index, Point const& point,
Operation const& operation,
SideStrategy const& strategy,
Strategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator& out)
{

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -109,11 +109,12 @@ namespace detail { namespace overlay {
class linear_intersections
{
public:
template <typename Point1, typename Point2, typename IntersectionResult>
template <typename Point1, typename Point2, typename IntersectionResult, typename EqPPStrategy>
linear_intersections(Point1 const& pi,
Point2 const& qi,
IntersectionResult const& result,
bool is_p_last, bool is_q_last)
bool is_p_last, bool is_q_last,
EqPPStrategy const& strategy)
{
int arrival_a = result.template get<1>().arrival[0];
int arrival_b = result.template get<1>().arrival[1];
@@ -133,10 +134,10 @@ public:
ips[0].is_pi
= equals::equals_point_point(
pi, result.template get<0>().intersections[0]);
pi, result.template get<0>().intersections[0], strategy);
ips[0].is_qi
= equals::equals_point_point(
qi, result.template get<0>().intersections[0]);
qi, result.template get<0>().intersections[0], strategy);
ips[1].is_pj = arrival_a != -1;
ips[1].is_qj = arrival_b != -1;
}
@@ -233,14 +234,16 @@ struct get_turn_info_for_endpoint
typename UniqueSubRange2,
typename TurnInfo,
typename IntersectionInfo,
typename OutputIterator
typename OutputIterator,
typename EqPPStrategy
>
static inline bool apply(UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
method_type /*method*/,
OutputIterator out)
OutputIterator out,
EqPPStrategy const& strategy)
{
std::size_t ip_count = inters.i_info().count;
// no intersection points
@@ -262,7 +265,8 @@ struct get_turn_info_for_endpoint
range_q.at(0),
inters.result(),
range_p.is_last_segment(),
range_q.is_last_segment());
range_q.is_last_segment(),
strategy);
bool append0_last
= analyse_segment_and_assign_ip(range_p, range_q,

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 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
@@ -52,7 +52,7 @@ struct get_turn_info_linear_areal
UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionStrategy const& intersection_strategy,
IntersectionStrategy const& strategy,
RobustPolicy const& robust_policy,
OutputIterator out)
{
@@ -64,8 +64,7 @@ struct get_turn_info_linear_areal
RobustPolicy
> inters_info;
inters_info inters(range_p, range_q,
intersection_strategy, robust_policy);
inters_info inters(range_p, range_q, strategy, robust_policy);
char const method = inters.d_info().how;
@@ -79,7 +78,8 @@ struct get_turn_info_linear_areal
case 'f' : // collinear, "from"
case 's' : // starts from the middle
get_turn_info_for_endpoint<true, true>(range_p, range_q,
tp_model, inters, method_none, out);
tp_model, inters, method_none, out,
strategy.get_point_in_point_strategy());
break;
case 'd' : // disjoint: never do anything
@@ -88,7 +88,8 @@ struct get_turn_info_linear_areal
case 'm' :
{
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
tp_model, inters, method_touch_interior, out) )
tp_model, inters, method_touch_interior, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -125,7 +126,8 @@ struct get_turn_info_linear_areal
// this function assumes that 'u' must be set for a spike
calculate_spike_operation(tp.operations[0].operation,
inters);
inters,
strategy.get_point_in_point_strategy());
*out++ = tp;
}
@@ -144,7 +146,8 @@ struct get_turn_info_linear_areal
{
// Both touch (both arrive there)
if ( get_turn_info_for_endpoint<false, true>(range_p, range_q,
tp_model, inters, method_touch, out) )
tp_model, inters, method_touch, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -216,7 +219,8 @@ struct get_turn_info_linear_areal
bool ignore_spike
= calculate_spike_operation(tp.operations[0].operation,
inters);
inters,
strategy.get_point_in_point_strategy());
if ( ! BOOST_GEOMETRY_CONDITION(handle_spikes)
|| ignore_spike
@@ -231,7 +235,8 @@ struct get_turn_info_linear_areal
case 'e':
{
if ( get_turn_info_for_endpoint<true, true>(range_p, range_q,
tp_model, inters, method_equal, out) )
tp_model, inters, method_equal, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -274,7 +279,8 @@ struct get_turn_info_linear_areal
// Collinear
if ( get_turn_info_for_endpoint<true, true>(
range_p, range_q,
tp_model, inters, method_collinear, out) )
tp_model, inters, method_collinear, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -352,12 +358,14 @@ struct get_turn_info_linear_areal
only_convert::apply(tp, inters.i_info());
if ( range_p.is_first_segment()
&& equals::equals_point_point(range_p.at(0), tp.point) )
&& equals::equals_point_point(range_p.at(0), tp.point,
strategy.get_point_in_point_strategy()) )
{
tp.operations[0].position = position_front;
}
else if ( range_p.is_last_segment()
&& equals::equals_point_point(range_p.at(1), tp.point) )
&& equals::equals_point_point(range_p.at(1), tp.point,
strategy.get_point_in_point_strategy()) )
{
tp.operations[0].position = position_back;
}
@@ -383,9 +391,11 @@ struct get_turn_info_linear_areal
}
template <typename Operation,
typename IntersectionInfo>
typename IntersectionInfo,
typename EqPPStrategy>
static inline bool calculate_spike_operation(Operation & op,
IntersectionInfo const& inters)
IntersectionInfo const& inters,
EqPPStrategy const& strategy)
{
bool is_p_spike = ( op == operation_union || op == operation_intersection )
&& inters.is_spike_p();
@@ -405,7 +415,7 @@ struct get_turn_info_linear_areal
// spike on the edge point
// if it's already known that the spike is going out this musn't be checked
if ( ! going_out
&& equals::equals_point_point(inters.rpj(), inters.rqj()) )
&& detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
{
int const pk_q2 = inters.sides().pk_wrt_q2();
going_in = pk_q1 < 0 && pk_q2 < 0; // Pk on the right of both
@@ -417,7 +427,7 @@ struct get_turn_info_linear_areal
// spike on the edge point
// if it's already known that the spike is going in this musn't be checked
if ( ! going_in
&& equals::equals_point_point(inters.rpj(), inters.rqj()) )
&& detail::equals::equals_point_point(inters.rpj(), inters.rqj(), strategy) )
{
int const pk_q2 = inters.sides().pk_wrt_q2();
going_in = pk_q1 < 0 || pk_q2 < 0; // Pk on the right of one of them
@@ -664,18 +674,20 @@ struct get_turn_info_linear_areal
template <bool EnableFirst,
bool EnableLast,
typename TurnInfo,
typename IntersectionInfo,
typename UniqueSubRange1,
typename UniqueSubRange2,
typename OutputIterator>
typename TurnInfo,
typename IntersectionInfo,
typename OutputIterator,
typename EqPPStrategy>
static inline bool get_turn_info_for_endpoint(
UniqueSubRange1 const& range_p,
UniqueSubRange2 const& range_q,
TurnInfo const& tp_model,
IntersectionInfo const& inters,
method_type /*method*/,
OutputIterator out)
OutputIterator out,
EqPPStrategy const& strategy)
{
namespace ov = overlay;
typedef ov::get_turn_info_for_endpoint<EnableFirst, EnableLast> get_info_e;
@@ -700,7 +712,8 @@ struct get_turn_info_linear_areal
range_q.at(0),
inters.result(),
range_p.is_last_segment(),
range_q.is_last_segment());
range_q.is_last_segment(),
strategy);
linear_intersections::ip_info const& ip0 = intersections.template get<0>();
linear_intersections::ip_info const& ip1 = intersections.template get<1>();
@@ -725,14 +738,6 @@ struct get_turn_info_linear_areal
}
else
{
// The code below should avoid using a side_calculator.
// Mainly because it is constructed with the wrong points.
// It should never be constructed other than pi,pj,pk / qi,qj,qk
// That side calculator might not be necessary here.
// Relevant sides can be passed to the method operations_and_equal
// (and that method can assign the operations, no need to return
// a pair, that is not done anywhere in all turns/operations)
// pi is the intersection point at qj or in the middle of q1
// so consider segments
// 1. pi at qj: qi-qj-pj and qi-qj-qk
@@ -858,6 +863,14 @@ struct get_turn_info_linear_areal
// don't ignore anything for now
return false;
}
template <typename Point1, typename Point2, typename IntersectionStrategy>
static inline bool equals_point_point(Point1 const& point1, Point2 const& point2,
IntersectionStrategy const& strategy)
{
return detail::equals::equals_point_point(point1, point2,
strategy.get_point_in_point_strategy());
}
};
}} // namespace detail::overlay

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 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
@@ -74,7 +74,8 @@ struct get_turn_info_linear_linear
case 's' : // starts from the middle
get_turn_info_for_endpoint<true, true>
::apply(range_p, range_q,
tp_model, inters, method_none, out);
tp_model, inters, method_none, out,
strategy.get_point_in_point_strategy());
break;
case 'd' : // disjoint: never do anything
@@ -84,7 +85,8 @@ struct get_turn_info_linear_linear
{
if ( get_turn_info_for_endpoint<false, true>
::apply(range_p, range_q,
tp_model, inters, method_touch_interior, out) )
tp_model, inters, method_touch_interior, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -141,7 +143,8 @@ struct get_turn_info_linear_linear
// Both touch (both arrive there)
if ( get_turn_info_for_endpoint<false, true>
::apply(range_p, range_q,
tp_model, inters, method_touch, out) )
tp_model, inters, method_touch, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -270,7 +273,8 @@ struct get_turn_info_linear_linear
{
if ( get_turn_info_for_endpoint<true, true>
::apply(range_p, range_q,
tp_model, inters, method_equal, out) )
tp_model, inters, method_equal, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -323,7 +327,8 @@ struct get_turn_info_linear_linear
// Collinear
if ( get_turn_info_for_endpoint<true, true>
::apply(range_p, range_q,
tp_model, inters, method_collinear, out) )
tp_model, inters, method_collinear, out,
strategy.get_point_in_point_strategy()) )
{
// do nothing
}
@@ -405,26 +410,29 @@ struct get_turn_info_linear_linear
// degenerate points
if ( BOOST_GEOMETRY_CONDITION(AssignPolicy::include_degenerate) )
{
typedef typename IntersectionStrategy::point_in_point_strategy_type
equals_strategy_type;
only_convert::apply(tp, inters.i_info());
// if any, only one of those should be true
if ( range_p.is_first_segment()
&& equals::equals_point_point(range_p.at(0), tp.point) )
&& equals::equals_point_point(range_p.at(0), tp.point, equals_strategy_type()) )
{
tp.operations[0].position = position_front;
}
else if ( range_p.is_last_segment()
&& equals::equals_point_point(range_p.at(1), tp.point) )
&& equals::equals_point_point(range_p.at(1), tp.point, equals_strategy_type()) )
{
tp.operations[0].position = position_back;
}
else if ( range_q.is_first_segment()
&& equals::equals_point_point(range_q.at(0), tp.point) )
&& equals::equals_point_point(range_q.at(0), tp.point, equals_strategy_type()) )
{
tp.operations[1].position = position_front;
}
else if ( range_q.is_last_segment()
&& equals::equals_point_point(range_q.at(1), tp.point) )
&& equals::equals_point_point(range_q.at(1), tp.point, equals_strategy_type()) )
{
tp.operations[1].position = position_back;
}

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2016, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2016, 2017, 2018.
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -108,6 +108,7 @@ template
typename Section,
typename Point,
typename CircularIterator,
typename IntersectionStrategy,
typename RobustPolicy
>
struct unique_sub_range_from_section
@@ -169,6 +170,7 @@ private :
inline void advance_to_non_duplicate_next(Point const& current, CircularIterator& circular_iterator) const
{
typedef typename IntersectionStrategy::point_in_point_strategy_type disjoint_strategy_type;
typedef typename robust_point_type<Point, RobustPolicy>::type robust_point_type;
robust_point_type current_robust_point;
robust_point_type next_robust_point;
@@ -187,7 +189,8 @@ private :
std::size_t check = 0;
while(! detail::disjoint::disjoint_point_point
(
current_robust_point, next_robust_point
current_robust_point, next_robust_point,
disjoint_strategy_type()
)
&& check++ < m_section.range_count)
{
@@ -349,8 +352,14 @@ public :
it1 != end1 && ! detail::section::exceeding<0>(dir1, *prev1, sec1.bounding_box, sec2.bounding_box, robust_policy);
++prev1, ++it1, ++index1, ++next1, ++ndi1)
{
unique_sub_range_from_section<areal1, Section1, point1_type, circular1_iterator, RobustPolicy> unique_sub_range1(sec1, index1,
circular1_iterator(begin_range_1, end_range_1, next1, true), *prev1, *it1, robust_policy);
unique_sub_range_from_section
<
areal1, Section1, point1_type, circular1_iterator,
IntersectionStrategy, RobustPolicy
> unique_sub_range1(sec1, index1,
circular1_iterator(begin_range_1, end_range_1, next1, true),
*prev1, *it1,
robust_policy);
signed_size_type index2 = sec2.begin_index;
signed_size_type ndi2 = sec2.non_duplicate_index;
@@ -396,8 +405,14 @@ public :
if (! skip)
{
unique_sub_range_from_section<areal2, Section2, point2_type, circular2_iterator, RobustPolicy> unique_sub_range2(sec2, index2,
circular2_iterator(begin_range_2, end_range_2, next2), *prev2, *it2, robust_policy);
unique_sub_range_from_section
<
areal2, Section2, point2_type, circular2_iterator,
IntersectionStrategy, RobustPolicy
> unique_sub_range2(sec2, index2,
circular2_iterator(begin_range_2, end_range_2, next2),
*prev2, *it2,
robust_policy);
typedef typename boost::range_value<Turns>::type turn_info;
@@ -502,7 +517,9 @@ struct section_visitor
template <typename Section>
inline bool apply(Section const& sec1, Section const& sec2)
{
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box))
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
sec2.bounding_box,
m_intersection_strategy.get_disjoint_box_box_strategy()))
{
// false if interrupted
return get_turns_in_sections
@@ -561,11 +578,13 @@ public:
typename IntersectionStrategy::envelope_strategy_type const
envelope_strategy = intersection_strategy.get_envelope_strategy();
typename IntersectionStrategy::expand_strategy_type const
expand_strategy = intersection_strategy.get_expand_strategy();
geometry::sectionalize<Reverse1, dimensions>(geometry1, robust_policy,
sec1, envelope_strategy, 0);
sec1, envelope_strategy, expand_strategy, 0);
geometry::sectionalize<Reverse2, dimensions>(geometry2, robust_policy,
sec2, envelope_strategy, 1);
sec2, envelope_strategy, expand_strategy, 1);
// ... and then partition them, intersecting overlapping sections in visitor method
section_visitor
@@ -579,12 +598,21 @@ public:
intersection_strategy, robust_policy,
turns, interrupt_policy);
typedef detail::section::get_section_box
<
typename IntersectionStrategy::expand_box_strategy_type
> get_section_box_type;
typedef detail::section::overlaps_section_box
<
typename IntersectionStrategy::disjoint_box_box_strategy_type
> overlaps_section_box_type;
geometry::partition
<
box_type
>::apply(sec1, sec2, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
get_section_box_type(),
overlaps_section_box_type());
}
};

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// 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
@@ -148,13 +148,13 @@ struct point_point_point
Point2 const& point2,
RobustPolicy const& ,
OutputIterator oit,
Strategy const&)
Strategy const& strategy)
{
action_selector_pl_pl
<
PointOut, OverlayType
>::apply(point1,
detail::equals::equals_point_point(point1, point2),
detail::equals::equals_point_point(point1, point2, strategy),
oit);
return oit;
@@ -182,7 +182,7 @@ struct multipoint_point_point
Point const& point,
RobustPolicy const& ,
OutputIterator oit,
Strategy const&)
Strategy const& strategy)
{
BOOST_GEOMETRY_ASSERT( OverlayType == overlay_difference );
@@ -194,7 +194,7 @@ struct multipoint_point_point
<
PointOut, OverlayType
>::apply(*it,
detail::equals::equals_point_point(*it, point),
detail::equals::equals_point_point(*it, point, strategy),
oit);
}
@@ -218,7 +218,7 @@ struct point_multipoint_point
MultiPoint const& multipoint,
RobustPolicy const& ,
OutputIterator oit,
Strategy const&)
Strategy const& strategy)
{
typedef action_selector_pl_pl<PointOut, OverlayType> action;
@@ -226,7 +226,7 @@ struct point_multipoint_point
it = boost::begin(multipoint);
it != boost::end(multipoint); ++it)
{
if ( detail::equals::equals_point_point(*it, point) )
if ( detail::equals::equals_point_point(*it, point, strategy) )
{
action::apply(point, true, oit);
return oit;

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -99,7 +99,9 @@ struct self_section_visitor
template <typename Section>
inline bool apply(Section const& sec1, Section const& sec2)
{
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box, sec2.bounding_box)
if (! detail::disjoint::disjoint_box_box(sec1.bounding_box,
sec2.bounding_box,
m_intersection_strategy.get_disjoint_box_box_strategy())
&& ! sec1.duplicate
&& ! sec2.duplicate)
{
@@ -154,7 +156,8 @@ struct get_turns
sections_type sec;
geometry::sectionalize<Reverse, dimensions>(geometry, robust_policy, sec,
intersection_strategy.get_envelope_strategy());
intersection_strategy.get_envelope_strategy(),
intersection_strategy.get_expand_strategy());
self_section_visitor
<
@@ -162,13 +165,22 @@ struct get_turns
Turns, TurnPolicy, IntersectionStrategy, RobustPolicy, InterruptPolicy
> visitor(geometry, intersection_strategy, robust_policy, turns, interrupt_policy, source_index, skip_adjacent);
typedef detail::section::get_section_box
<
typename IntersectionStrategy::expand_box_strategy_type
> get_section_box_type;
typedef detail::section::overlaps_section_box
<
typename IntersectionStrategy::disjoint_box_box_strategy_type
> overlaps_section_box_type;
// false if interrupted
geometry::partition
<
box_type
>::apply(sec, visitor,
detail::section::get_section_box(),
detail::section::overlaps_section_box());
get_section_box_type(),
overlaps_section_box_type());
return ! interrupt_policy.has_intersections;
}

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -56,117 +56,47 @@ struct get_point
}
};
template<typename Point, std::size_t Dimension, std::size_t DimensionCount>
struct midpoint_helper
{
template <typename InputPoint>
static inline bool apply(Point& p, InputPoint const& p1, InputPoint const& p2)
{
typename coordinate_type<Point>::type const two = 2;
set<Dimension>(p,
(get<Dimension>(p1) + get<Dimension>(p2)) / two);
return midpoint_helper<Point, Dimension + 1, DimensionCount>::apply(p, p1, p2);
}
};
template <typename Point, std::size_t DimensionCount>
struct midpoint_helper<Point, DimensionCount, DimensionCount>
{
template <typename InputPoint>
static inline bool apply(Point& , InputPoint const& , InputPoint const& )
{
return true;
}
};
template <bool Midpoint>
struct point_on_range
{
// Version with iterator
template<typename Point, typename Iterator>
static inline bool apply(Point& point, Iterator begin, Iterator end)
{
Iterator it = begin;
if (it == end)
if (begin == end)
{
return false;
}
if (! Midpoint)
{
geometry::detail::conversion::convert_point_to_point(*it, point);
return true;
}
Iterator prev = it++;
// Go to next non-duplicate point
while (it != end
&& detail::equals::equals_point_point(*it, *prev))
{
prev = it++;
}
if (it != end)
{
return midpoint_helper
<
Point,
0, dimension<Point>::value
>::apply(point, *prev, *it);
}
return false;
geometry::detail::conversion::convert_point_to_point(*begin, point);
return true;
}
// Version with range
template<typename Point, typename Range>
static inline bool apply(Point& point, Range const& range)
{
typedef typename geometry::cs_tag<Point>::type cs_tag;
BOOST_STATIC_ASSERT((! Midpoint || boost::is_same<cs_tag, cartesian_tag>::value));
return apply(point, boost::begin(range), boost::end(range));
}
};
template <bool Midpoint>
struct point_on_polygon
{
template<typename Point, typename Polygon>
static inline bool apply(Point& point, Polygon const& polygon)
{
return point_on_range
<
Midpoint
>::apply(point, exterior_ring(polygon));
return point_on_range::apply(point, exterior_ring(polygon));
}
};
template <bool Midpoint>
struct point_on_box
{
template<typename Point, typename Box>
static inline bool apply(Point& point, Box const& box)
{
if (BOOST_GEOMETRY_CONDITION(Midpoint))
{
Point p1, p2;
detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, p1);
detail::assign::assign_box_2d_corner<max_corner, min_corner>(box, p2);
midpoint_helper
<
Point,
0, dimension<Point>::value
>::apply(point, p1, p2);
}
else
{
detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
}
detail::assign::assign_box_2d_corner<min_corner, min_corner>(box, point);
return true;
}
};
@@ -206,60 +136,50 @@ namespace dispatch
{
template
<
typename GeometryTag,
bool Midpoint
>
template <typename GeometryTag>
struct point_on_border
{};
template <bool Midpoint>
struct point_on_border<point_tag, Midpoint>
template <>
struct point_on_border<point_tag>
: detail::point_on_border::get_point
{};
template <>
struct point_on_border<linestring_tag>
: detail::point_on_border::point_on_range
{};
template <bool Midpoint>
struct point_on_border<linestring_tag, Midpoint>
: detail::point_on_border::point_on_range<Midpoint>
template <>
struct point_on_border<ring_tag>
: detail::point_on_border::point_on_range
{};
template <>
struct point_on_border<polygon_tag>
: detail::point_on_border::point_on_polygon
{};
template <>
struct point_on_border<box_tag>
: detail::point_on_border::point_on_box
{};
template <bool Midpoint>
struct point_on_border<ring_tag, Midpoint>
: detail::point_on_border::point_on_range<Midpoint>
{};
template <bool Midpoint>
struct point_on_border<polygon_tag, Midpoint>
: detail::point_on_border::point_on_polygon<Midpoint>
{};
template <bool Midpoint>
struct point_on_border<box_tag, Midpoint>
: detail::point_on_border::point_on_box<Midpoint>
{};
template <bool Midpoint>
struct point_on_border<multi_polygon_tag, Midpoint>
template <>
struct point_on_border<multi_polygon_tag>
: detail::point_on_border::point_on_multi
<
detail::point_on_border::point_on_polygon<Midpoint>
detail::point_on_border::point_on_polygon
>
{};
template <bool Midpoint>
struct point_on_border<multi_linestring_tag, Midpoint>
template <>
struct point_on_border<multi_linestring_tag>
: detail::point_on_border::point_on_multi
<
detail::point_on_border::point_on_range<Midpoint>
detail::point_on_border::point_on_range
>
{};
@@ -286,33 +206,11 @@ inline bool point_on_border(Point& point, Geometry const& geometry)
return dispatch::point_on_border
<
typename tag<Geometry>::type,
false
typename tag<Geometry>::type
>::apply(point, geometry);
}
/*!
\tparam Midpoint boolean flag, true if the point should not be a vertex, but some point
in between of two vertices
\note for Midpoint, it is not taken from two consecutive duplicate vertices,
(unless there are no other).
*/
/*
template <bool Midpoint, typename Point, typename Geometry>
inline bool point_on_border(Point& point, Geometry const& geometry)
{
concepts::check<Point>();
concepts::check<Geometry const>();
return dispatch::point_on_border
<
typename tag<Geometry>::type,
Midpoint
>::apply(point, geometry);
}
*/
}} // namespace boost::geometry

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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
@@ -277,7 +277,8 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 0> analyser;
analyse_each_turn(result, analyser, turns.begin(), turns.end());
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
point_in_areal_strategy12.get_equals_point_point_strategy());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -317,7 +318,8 @@ struct areal_areal
{
// analyse sorted turns
turns_analyser<turn_type, 1> analyser;
analyse_each_turn(result, analyser, turns.begin(), turns.end());
analyse_each_turn(result, analyser, turns.begin(), turns.end(),
point_in_areal_strategy21.get_equals_point_point_strategy());
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
@@ -441,9 +443,8 @@ struct areal_areal
, m_exit_detected(false)
{}
template <typename Result,
typename TurnIt>
void apply(Result & result, TurnIt it)
template <typename Result, typename TurnIt, typename EqPPStrategy>
void apply(Result & result, TurnIt it, EqPPStrategy const& strategy)
{
//BOOST_GEOMETRY_ASSERT( it != last );
@@ -468,7 +469,7 @@ struct areal_areal
{
// real exit point - may be multiple
if ( first_in_range
|| ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
|| ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it, strategy) )
{
update_exit(result);
m_exit_detected = false;
@@ -484,7 +485,7 @@ struct areal_areal
{
// real entry point
if ( first_in_range
|| ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
|| ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it, strategy) )
{
update_enter(result);
m_enter_detected = false;
@@ -581,19 +582,24 @@ struct areal_areal
// call analyser.apply() for each turn in range
// IMPORTANT! The analyser is also called for the end iterator - last
template <typename Result,
typename Analyser,
typename TurnIt>
template
<
typename Result,
typename Analyser,
typename TurnIt,
typename EqPPStrategy
>
static inline void analyse_each_turn(Result & res,
Analyser & analyser,
TurnIt first, TurnIt last)
TurnIt first, TurnIt last,
EqPPStrategy const& strategy)
{
if ( first == last )
return;
for ( TurnIt it = first ; it != last ; ++it )
{
analyser.apply(res, it);
analyser.apply(res, it, strategy);
if ( BOOST_GEOMETRY_CONDITION(res.interrupt) )
return;

View File

@@ -1,17 +1,18 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014 Oracle and/or its affiliates.
// Copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_BOUNDARY_CHECKER_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
@@ -29,19 +30,26 @@ namespace detail { namespace relate {
enum boundary_query { boundary_front, boundary_back, boundary_any };
template <typename Geometry,
typename WithinStrategy, // Point/Point equals (within) strategy
typename Tag = typename geometry::tag<Geometry>::type>
class boundary_checker {};
template <typename Geometry>
class boundary_checker<Geometry, linestring_tag>
template <typename Geometry, typename WithinStrategy>
class boundary_checker<Geometry, WithinStrategy, linestring_tag>
{
typedef typename point_type<Geometry>::type point_type;
public:
typedef WithinStrategy equals_strategy_type;
boundary_checker(Geometry const& g)
: has_boundary( boost::size(g) >= 2
&& !detail::equals::equals_point_point(range::front(g), range::back(g)) )
&& !detail::equals::equals_point_point(range::front(g),
range::back(g),
equals_strategy_type()) )
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
, geometry(g)
#endif
{}
template <boundary_query BoundaryQuery>
@@ -51,24 +59,28 @@ public:
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
// may give false positives for INT
BOOST_GEOMETRY_ASSERT( (BoundaryQuery == boundary_front || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::front(geometry))
&& detail::equals::equals_point_point(pt, range::front(geometry), WithinStrategy())
|| (BoundaryQuery == boundary_back || BoundaryQuery == boundary_any)
&& detail::equals::equals_point_point(pt, range::back(geometry)) );
&& detail::equals::equals_point_point(pt, range::back(geometry), WithinStrategy()) );
#endif
return has_boundary;
}
private:
bool has_boundary;
#ifdef BOOST_GEOMETRY_DEBUG_RELATE_BOUNDARY_CHECKER
Geometry const& geometry;
#endif
};
template <typename Geometry>
class boundary_checker<Geometry, multi_linestring_tag>
template <typename Geometry, typename WithinStrategy>
class boundary_checker<Geometry, WithinStrategy, multi_linestring_tag>
{
typedef typename point_type<Geometry>::type point_type;
public:
typedef WithinStrategy equals_strategy_type;
boundary_checker(Geometry const& g)
: is_filled(false), geometry(g)
{}
@@ -111,7 +123,7 @@ public:
point_reference back_pt = range::back(ls);
// linear ring or point - no boundary
if (! equals::equals_point_point(front_pt, back_pt))
if (! equals::equals_point_point(front_pt, back_pt, equals_strategy_type()))
{
// do not add points containing NaN coordinates
// because they cannot be reasonably compared, e.g. with MSVC

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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, 2014, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -333,8 +333,9 @@ private:
std::vector<point_info> m_other_entry_points; // TODO: use map here or sorted vector?
};
template <std::size_t OpId, typename Turn>
inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn)
template <std::size_t OpId, typename Turn, typename EqPPStrategy>
inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn,
EqPPStrategy const& strategy)
{
segment_identifier const& prev_seg_id = prev_turn.operations[OpId].seg_id;
segment_identifier const& curr_seg_id = curr_turn.operations[OpId].seg_id;
@@ -354,7 +355,7 @@ inline bool turn_on_the_same_ip(Turn const& prev_turn, Turn const& curr_turn)
return false;
}
return detail::equals::equals_point_point(prev_turn.point, curr_turn.point);
return detail::equals::equals_point_point(prev_turn.point, curr_turn.point, strategy);
}
template <boundary_query BoundaryQuery,

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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
@@ -262,13 +262,22 @@ struct linear_areal
typedef typename IntersectionStrategy::template point_in_geometry_strategy<Geometry1, Geometry2>::type within_strategy_type;
within_strategy_type const within_strategy = intersection_strategy.template get_point_in_geometry_strategy<Geometry1, Geometry2>();
boundary_checker<Geometry1> boundary_checker1(geometry1);
typedef typename within_strategy_type::equals_point_point_strategy_type eq_pp_strategy_type;
typedef boundary_checker
<
Geometry1,
eq_pp_strategy_type
> boundary_checker1_type;
boundary_checker1_type boundary_checker1(geometry1);
no_turns_la_linestring_pred
<
Geometry2,
Result,
within_strategy_type,
boundary_checker<Geometry1>,
boundary_checker1_type,
TransposeResult
> pred1(geometry2,
result,
@@ -393,12 +402,14 @@ struct linear_areal
typedef turns::less<1, turns::less_op_areal_linear<1> > less;
std::sort(it, next, less());
eq_pp_strategy_type const eq_pp_strategy = within_strategy.get_equals_point_point_strategy();
// analyse
areal_boundary_analyser<turn_type> analyser;
for ( turn_iterator rit = it ; rit != next ; ++rit )
{
// if the analyser requests, break the search
if ( !analyser.apply(it, rit, next) )
if ( !analyser.apply(it, rit, next, eq_pp_strategy) )
break;
}
@@ -701,7 +712,8 @@ struct linear_areal
{
// real exit point - may be multiple
// we know that we entered and now we exit
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
side_strategy.get_equals_point_point_strategy()) )
{
m_exit_watcher.reset_detected_exit();
@@ -743,7 +755,8 @@ struct linear_areal
if ( ( op == overlay::operation_intersection
|| op == overlay::operation_continue )
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it,
side_strategy.get_equals_point_point_strategy()) )
{
fake_enter_detected = true;
}
@@ -763,7 +776,8 @@ struct linear_areal
&& ( op != overlay::operation_blocked // operation different than block
|| seg_id.multi_index != m_previous_turn_ptr->operations[op_id].seg_id.multi_index ) ) // or the next single-geometry
|| ( m_previous_operation == overlay::operation_union
&& ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
&& ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
side_strategy.get_equals_point_point_strategy()) )
)
{
update<interior, exterior, '1', TransposeResult>(res);
@@ -795,7 +809,8 @@ struct linear_areal
BOOST_GEOMETRY_ASSERT_MSG(m_previous_turn_ptr, "non-NULL ptr expected");
// real interior overlap
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it) )
if ( ! turn_on_the_same_ip<op_id>(*m_previous_turn_ptr, *it,
side_strategy.get_equals_point_point_strategy()) )
{
update<interior, interior, '1', TransposeResult>(res);
m_interior_detected = false;
@@ -1234,7 +1249,7 @@ struct linear_areal
point2_type const& qj = range::at(range2, q_seg_ij + 1);
point1_type qi_conv;
geometry::convert(qi, qi_conv);
bool const is_ip_qj = equals::equals_point_point(turn.point, qj);
bool const is_ip_qj = equals::equals_point_point(turn.point, qj, side_strategy.get_equals_point_point_strategy());
// TODO: test this!
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, pi));
// BOOST_GEOMETRY_ASSERT(!equals::equals_point_point(turn.point, qi));
@@ -1248,7 +1263,8 @@ struct linear_areal
// It would be good to replace it with some O(1) mechanism
range2_iterator qk_it = find_next_non_duplicated(boost::begin(range2),
range::pos(range2, q_seg_jk),
boost::end(range2));
boost::end(range2),
side_strategy.get_equals_point_point_strategy());
// Will this sequence of points be always correct?
la_side_calculator<cs_tag, point1_type, point2_type, SideStrategy>
@@ -1268,8 +1284,9 @@ struct linear_areal
}
}
template <typename It>
static inline It find_next_non_duplicated(It first, It current, It last)
template <typename It, typename EqPPStrategy>
static inline It find_next_non_duplicated(It first, It current, It last,
EqPPStrategy const& strategy)
{
BOOST_GEOMETRY_ASSERT( current != last );
@@ -1277,14 +1294,14 @@ struct linear_areal
for ( ++it ; it != last ; ++it )
{
if ( !equals::equals_point_point(*current, *it) )
if ( !equals::equals_point_point(*current, *it, strategy) )
return it;
}
// if not found start from the beginning
for ( it = first ; it != current ; ++it )
{
if ( !equals::equals_point_point(*current, *it) )
if ( !equals::equals_point_point(*current, *it, strategy) )
return it;
}
@@ -1427,8 +1444,9 @@ struct linear_areal
, m_previous_turn_ptr(NULL)
{}
template <typename TurnIt>
bool apply(TurnIt /*first*/, TurnIt it, TurnIt last)
template <typename TurnIt, typename EqPPStrategy>
bool apply(TurnIt /*first*/, TurnIt it, TurnIt last,
EqPPStrategy const& strategy)
{
overlay::operation_type op = it->operations[1].operation;
@@ -1443,7 +1461,7 @@ struct linear_areal
if ( is_union_detected )
{
BOOST_GEOMETRY_ASSERT(m_previous_turn_ptr != NULL);
if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point) )
if ( !detail::equals::equals_point_point(it->point, m_previous_turn_ptr->point, strategy) )
{
// break
return false;

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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
@@ -42,6 +42,8 @@ namespace detail { namespace relate {
template <typename Result, typename BoundaryChecker, bool TransposeResult>
class disjoint_linestring_pred
{
typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
public:
disjoint_linestring_pred(Result & res,
BoundaryChecker const& boundary_checker)
@@ -80,7 +82,8 @@ public:
// point-like linestring
if ( count == 2
&& equals::equals_point_point(range::front(linestring),
range::back(linestring)) )
range::back(linestring),
equals_strategy_type()) )
{
update<interior, exterior, '0', TransposeResult>(m_result);
}
@@ -145,14 +148,24 @@ struct linear_linear
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
boundary_checker<Geometry1> boundary_checker1(geometry1);
disjoint_linestring_pred<Result, boundary_checker<Geometry1>, false> pred1(result, boundary_checker1);
typedef boundary_checker
<
Geometry1,
typename IntersectionStrategy::point_in_point_strategy_type
> boundary_checker1_type;
boundary_checker1_type boundary_checker1(geometry1);
disjoint_linestring_pred<Result, boundary_checker1_type, false> pred1(result, boundary_checker1);
for_each_disjoint_geometry_if<0, Geometry1>::apply(turns.begin(), turns.end(), geometry1, pred1);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
boundary_checker<Geometry2> boundary_checker2(geometry2);
disjoint_linestring_pred<Result, boundary_checker<Geometry2>, true> pred2(result, boundary_checker2);
typedef boundary_checker
<
Geometry2,
typename IntersectionStrategy::point_in_point_strategy_type
> boundary_checker2_type;
boundary_checker2_type boundary_checker2(geometry2);
disjoint_linestring_pred<Result, boundary_checker2_type, true> pred2(result, boundary_checker2);
for_each_disjoint_geometry_if<1, Geometry2>::apply(turns.begin(), turns.end(), geometry2, pred2);
if ( BOOST_GEOMETRY_CONDITION( result.interrupt ) )
return;
@@ -274,6 +287,8 @@ struct linear_linear
BoundaryChecker const& boundary_checker,
OtherBoundaryChecker const& other_boundary_checker)
{
typedef typename BoundaryChecker::equals_strategy_type equals_strategy_type;
overlay::operation_type const op = it->operations[op_id].operation;
segment_identifier const& seg_id = it->operations[op_id].seg_id;
@@ -323,7 +338,9 @@ struct linear_linear
{
// real exit point - may be multiple
// we know that we entered and now we exit
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
if ( ! turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
*it,
equals_strategy_type()) )
{
m_exit_watcher.reset_detected_exit();
@@ -344,7 +361,9 @@ struct linear_linear
return;
if ( op == overlay::operation_intersection
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(), *it) )
&& turn_on_the_same_ip<op_id>(m_exit_watcher.get_exit_turn(),
*it,
equals_strategy_type()) )
{
fake_enter_detected = true;
}
@@ -647,6 +666,11 @@ struct linear_linear
OtherBoundaryChecker const& /*other_boundary_checker*/,
bool first_in_range)
{
typedef typename BoundaryChecker::equals_strategy_type
equals_strategy1_type;
typedef typename OtherBoundaryChecker::equals_strategy_type
equals_strategy2_type;
typename detail::single_geometry_return_type<Geometry const>::type
ls1_ref = detail::single_geometry(geometry, turn.operations[op_id].seg_id);
typename detail::single_geometry_return_type<OtherGeometry const>::type
@@ -714,9 +738,13 @@ struct linear_linear
// here we don't know which one is degenerated
bool const is_point1 = boost::size(ls1_ref) == 2
&& equals::equals_point_point(range::front(ls1_ref), range::back(ls1_ref));
&& equals::equals_point_point(range::front(ls1_ref),
range::back(ls1_ref),
equals_strategy1_type());
bool const is_point2 = boost::size(ls2_ref) == 2
&& equals::equals_point_point(range::front(ls2_ref), range::back(ls2_ref));
&& equals::equals_point_point(range::front(ls2_ref),
range::back(ls2_ref),
equals_strategy2_type());
// if the second one is degenerated
if ( !is_point1 && is_point2 )

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017 Oracle and/or its affiliates.
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -40,20 +40,21 @@ namespace detail { namespace relate
template
<
typename Geometry,
typename EqPPStrategy,
typename Tag = typename tag<Geometry>::type
>
struct multi_point_geometry_eb
{
template <typename MultiPoint>
static inline bool apply(MultiPoint const& ,
detail::relate::topology_check<Geometry> const& )
detail::relate::topology_check<Geometry, EqPPStrategy> const& )
{
return true;
}
};
template <typename Geometry>
struct multi_point_geometry_eb<Geometry, linestring_tag>
template <typename Geometry, typename EqPPStrategy>
struct multi_point_geometry_eb<Geometry, EqPPStrategy, linestring_tag>
{
template <typename Points>
struct boundary_visitor
@@ -73,7 +74,7 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
template <typename Pt>
bool operator()(Pt const& pt) const
{
return detail::equals::equals_point_point(pt, m_point);
return detail::equals::equals_point_point(pt, m_point, EqPPStrategy());
}
Point const& m_point;
@@ -99,7 +100,7 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
template <typename MultiPoint>
static inline bool apply(MultiPoint const& multi_point,
detail::relate::topology_check<Geometry> const& tc)
detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
{
boundary_visitor<MultiPoint> visitor(multi_point);
tc.for_each_boundary_point(visitor);
@@ -107,9 +108,12 @@ struct multi_point_geometry_eb<Geometry, linestring_tag>
}
};
template <typename Geometry>
struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename Geometry, typename EqPPStrategy>
struct multi_point_geometry_eb<Geometry, EqPPStrategy, multi_linestring_tag>
{
// TODO: CS-specific less compare strategy derived from EqPPStrategy
typedef geometry::less<> less_type;
template <typename Points>
struct boundary_visitor
{
@@ -121,7 +125,7 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename Point>
bool apply(Point const& boundary_point)
{
if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, geometry::less<>()))
if (! std::binary_search(m_points.begin(), m_points.end(), boundary_point, less_type()))
{
m_boundary_found = true;
return false;
@@ -138,12 +142,12 @@ struct multi_point_geometry_eb<Geometry, multi_linestring_tag>
template <typename MultiPoint>
static inline bool apply(MultiPoint const& multi_point,
detail::relate::topology_check<Geometry> const& tc)
detail::relate::topology_check<Geometry, EqPPStrategy> const& tc)
{
typedef typename boost::range_value<MultiPoint>::type point_type;
typedef std::vector<point_type> points_type;
points_type points(boost::begin(multi_point), boost::end(multi_point));
std::sort(points.begin(), points.end(), geometry::less<>());
std::sort(points.begin(), points.end(), less_type());
boundary_visitor<points_type> visitor(points);
tc.for_each_boundary_point(visitor);
@@ -165,6 +169,8 @@ struct multi_point_single_geometry
{
typedef typename point_type<SingleGeometry>::type point2_type;
typedef model::box<point2_type> box2_type;
typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
typedef typename Strategy::disjoint_point_box_strategy_type d_pb_strategy_type;
box2_type box2;
geometry::envelope(single_geometry, box2, strategy.get_envelope_strategy());
@@ -181,7 +187,7 @@ struct multi_point_single_geometry
}
// The default strategy is enough for Point/Box
if (detail::disjoint::disjoint_point_box(*it, box2))
if (detail::disjoint::disjoint_point_box(*it, box2, d_pb_strategy_type()))
{
relate::set<interior, exterior, '0', Transpose>(result);
}
@@ -209,7 +215,10 @@ struct multi_point_single_geometry
}
}
typedef detail::relate::topology_check<SingleGeometry> tc_t;
typedef detail::relate::topology_check
<
SingleGeometry, eq_pp_strategy_type
> tc_t;
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
{
@@ -226,8 +235,13 @@ struct multi_point_single_geometry
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
&& tc.has_boundary() )
{
if (multi_point_geometry_eb<SingleGeometry>::apply(multi_point, tc))
if (multi_point_geometry_eb
<
SingleGeometry, eq_pp_strategy_type
>::apply(multi_point, tc))
{
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
}
}
@@ -260,32 +274,40 @@ class multi_point_multi_geometry_ii_ib
}
};
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);
return ! detail::disjoint::disjoint_point_box(point, box,
DisjointPointBoxStrategy());
}
};
template <typename DisjointBoxBoxStrategy>
struct overlaps_box_box_pair
{
template <typename Box, typename BoxPair>
static inline bool apply(Box const& box, BoxPair const& box_pair)
{
// The default strategy is enough for Box/Box
return ! detail::disjoint::disjoint_box_box(box_pair.first, box);
return ! detail::disjoint::disjoint_box_box(box_pair.first, box,
DisjointBoxBoxStrategy());
}
};
template <typename Result, typename PtSegStrategy>
class item_visitor_type
{
typedef typename PtSegStrategy::equals_point_point_strategy_type pp_strategy_type;
typedef typename PtSegStrategy::disjoint_point_box_strategy_type d_pp_strategy_type;
typedef detail::relate::topology_check<MultiGeometry, pp_strategy_type> topology_check_type;
public:
item_visitor_type(MultiGeometry const& multi_geometry,
detail::relate::topology_check<MultiGeometry> const& tc,
topology_check_type const& tc,
Result & result,
PtSegStrategy const& strategy)
: m_multi_geometry(multi_geometry)
@@ -298,7 +320,7 @@ class multi_point_multi_geometry_ii_ib
inline bool apply(Point const& point, BoxPair const& box_pair)
{
// The default strategy is enough for Point/Box
if (! detail::disjoint::disjoint_point_box(point, box_pair.first))
if (! detail::disjoint::disjoint_point_box(point, box_pair.first, d_pp_strategy_type()))
{
typename boost::range_value<MultiGeometry>::type const&
single = range::at(m_multi_geometry, box_pair.second);
@@ -335,7 +357,7 @@ class multi_point_multi_geometry_ii_ib
private:
MultiGeometry const& m_multi_geometry;
detail::relate::topology_check<MultiGeometry> const& m_tc;
topology_check_type const& m_tc;
Result & m_result;
PtSegStrategy const& m_strategy;
};
@@ -351,20 +373,33 @@ public:
static inline void apply(MultiPoint const& multi_point,
MultiGeometry const& multi_geometry,
std::vector<box_pair_type> const& boxes,
detail::relate::topology_check<MultiGeometry> const& tc,
detail::relate::topology_check
<
MultiGeometry,
typename Strategy::equals_point_point_strategy_type
> const& tc,
Result & result,
Strategy const& strategy)
{
item_visitor_type<Result, Strategy> visitor(multi_geometry, tc, result, 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(),
overlaps_box_point_type(),
expand_box_box_pair(),
overlaps_box_box_pair());
overlaps_box_box_pair_type());
}
};
@@ -387,7 +422,11 @@ struct multi_point_multi_geometry_ii_ib_ie
static inline void apply(MultiPoint const& multi_point,
MultiGeometry const& multi_geometry,
std::vector<box_pair_type> const& boxes,
detail::relate::topology_check<MultiGeometry> const& tc,
detail::relate::topology_check
<
MultiGeometry,
typename Strategy::equals_point_point_strategy_type
> const& tc,
Result & result,
Strategy const& strategy)
{
@@ -461,6 +500,8 @@ struct multi_point_multi_geometry
typedef model::box<point2_type> box2_type;
typedef std::pair<box2_type, std::size_t> box_pair_type;
typedef typename Strategy::equals_point_point_strategy_type eq_pp_strategy_type;
typename Strategy::envelope_strategy_type const
envelope_strategy = strategy.get_envelope_strategy();
@@ -473,7 +514,7 @@ struct multi_point_multi_geometry
boxes[i].second = i;
}
typedef detail::relate::topology_check<MultiGeometry> tc_t;
typedef detail::relate::topology_check<MultiGeometry, eq_pp_strategy_type> tc_t;
tc_t tc(multi_geometry);
if ( relate::may_update<interior, interior, '0', Transpose>(result)
@@ -512,8 +553,13 @@ struct multi_point_multi_geometry
if ( relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result)
&& tc.has_boundary() )
{
if (multi_point_geometry_eb<MultiGeometry>::apply(multi_point, tc))
if (multi_point_geometry_eb
<
MultiGeometry, eq_pp_strategy_type
>::apply(multi_point, tc))
{
relate::set<exterior, boundary, tc_t::boundary, Transpose>(result);
}
}
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// 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
@@ -60,7 +60,11 @@ struct point_geometry
if ( BOOST_GEOMETRY_CONDITION(result.interrupt) )
return;
typedef detail::relate::topology_check<Geometry> tc_t;
typedef detail::relate::topology_check
<
Geometry,
typename Strategy::equals_point_point_strategy_type
> tc_t;
if ( relate::may_update<exterior, interior, tc_t::interior, Transpose>(result)
|| relate::may_update<exterior, boundary, tc_t::boundary, Transpose>(result) )
{

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -39,9 +39,9 @@ struct point_point
template <typename Result, typename Strategy>
static inline void apply(Point1 const& point1, Point2 const& point2,
Result & result,
Strategy const& /*strategy*/)
Strategy const& strategy)
{
bool equal = detail::equals::equals_point_point(point1, point2);
bool equal = detail::equals::equals_point_point(point1, point2, strategy);
if ( equal )
{
relate::set<interior, interior, '0'>(result);
@@ -56,8 +56,10 @@ struct point_point
}
};
template <typename Point, typename MultiPoint>
std::pair<bool, bool> point_multipoint_check(Point const& point, MultiPoint const& multi_point)
template <typename Point, typename MultiPoint, typename EqPPStrategy>
std::pair<bool, bool> point_multipoint_check(Point const& point,
MultiPoint const& multi_point,
EqPPStrategy const& strategy)
{
bool found_inside = false;
bool found_outside = false;
@@ -70,7 +72,7 @@ std::pair<bool, bool> point_multipoint_check(Point const& point, MultiPoint cons
iterator last = boost::end(multi_point);
for ( ; it != last ; ++it )
{
bool ii = detail::equals::equals_point_point(point, *it);
bool ii = detail::equals::equals_point_point(point, *it, strategy);
if ( ii )
found_inside = true;
@@ -92,7 +94,7 @@ struct point_multipoint
template <typename Result, typename Strategy>
static inline void apply(Point const& point, MultiPoint const& multi_point,
Result & result,
Strategy const& /*strategy*/)
Strategy const& strategy)
{
if ( boost::empty(multi_point) )
{
@@ -101,7 +103,7 @@ struct point_multipoint
return;
}
std::pair<bool, bool> rel = point_multipoint_check(point, multi_point);
std::pair<bool, bool> rel = point_multipoint_check(point, multi_point, strategy);
if ( rel.first ) // some point of MP is equal to P
{

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017, Oracle and/or its affiliates.
// Copyright (c) 2014-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -28,6 +28,7 @@ namespace detail { namespace relate {
// TODO: change the name for e.g. something with the word "exterior"
template <typename Geometry,
typename EqPPStrategy,
typename Tag = typename geometry::tag<Geometry>::type>
struct topology_check
: not_implemented<Tag>
@@ -47,8 +48,8 @@ struct topology_check
// topology_check(Point const&, IgnoreBoundaryPoint const&) {}
//};
template <typename Linestring>
struct topology_check<Linestring, linestring_tag>
template <typename Linestring, typename EqPPStrategy>
struct topology_check<Linestring, EqPPStrategy, linestring_tag>
{
static const char interior = '1';
static const char boundary = '0';
@@ -100,7 +101,9 @@ private:
m_has_interior = count > 0;
// NOTE: Linestring with all points equal is treated as 1d linear ring
m_has_boundary = count > 1
&& ! detail::equals::equals_point_point(range::front(m_ls), range::back(m_ls));
&& ! detail::equals::equals_point_point(range::front(m_ls),
range::back(m_ls),
EqPPStrategy());
m_is_initialized = true;
}
@@ -112,8 +115,8 @@ private:
mutable bool m_has_boundary;
};
template <typename MultiLinestring>
struct topology_check<MultiLinestring, multi_linestring_tag>
template <typename MultiLinestring, typename EqPPStrategy>
struct topology_check<MultiLinestring, EqPPStrategy, multi_linestring_tag>
{
static const char interior = '1';
static const char boundary = '0';
@@ -159,6 +162,9 @@ struct topology_check<MultiLinestring, multi_linestring_tag>
}
private:
// TODO: CS-specific less derived from EqPPStrategy
typedef geometry::less<> less_type;
void init() const
{
if (m_is_initialized)
@@ -192,7 +198,7 @@ private:
point_reference back_pt = range::back(ls);
// don't store boundaries of linear rings, this doesn't change anything
if (! equals::equals_point_point(front_pt, back_pt))
if (! equals::equals_point_point(front_pt, back_pt, EqPPStrategy()))
{
// do not add points containing NaN coordinates
// because they cannot be reasonably compared, e.g. with MSVC
@@ -215,7 +221,7 @@ private:
if (! m_endpoints.empty() )
{
std::sort(m_endpoints.begin(), m_endpoints.end(), geometry::less<>());
std::sort(m_endpoints.begin(), m_endpoints.end(), less_type());
m_has_boundary = find_odd_count(m_endpoints.begin(), m_endpoints.end());
}
@@ -225,7 +231,7 @@ private:
template <typename It, typename Point>
static inline std::size_t count_equal(It first, It last, Point const& point)
{
std::pair<It, It> rng = std::equal_range(first, last, point, geometry::less<>());
std::pair<It, It> rng = std::equal_range(first, last, point, less_type());
return (std::size_t)std::distance(rng.first, rng.second);
}
@@ -261,7 +267,7 @@ private:
for ( ; first != last ; ++first, ++prev )
{
// the end of the equal points subrange
if ( ! equals::equals_point_point(*first, *prev) )
if ( ! equals::equals_point_point(*first, *prev, EqPPStrategy()) )
{
// odd count -> boundary
if ( count % 2 != 0 )
@@ -298,40 +304,35 @@ private:
mutable std::vector<point_type> m_endpoints;
};
template <typename Ring>
struct topology_check<Ring, ring_tag>
struct topology_check_areal
{
static const char interior = '2';
static const char boundary = '1';
static bool has_interior() { return true; }
static bool has_boundary() { return true; }
};
template <typename Ring, typename EqPPStrategy>
struct topology_check<Ring, EqPPStrategy, ring_tag>
: topology_check_areal
{
topology_check(Ring const&) {}
static bool has_interior() { return true; }
static bool has_boundary() { return true; }
};
template <typename Polygon>
struct topology_check<Polygon, polygon_tag>
template <typename Polygon, typename EqPPStrategy>
struct topology_check<Polygon, EqPPStrategy, polygon_tag>
: topology_check_areal
{
static const char interior = '2';
static const char boundary = '1';
topology_check(Polygon const&) {}
static bool has_interior() { return true; }
static bool has_boundary() { return true; }
};
template <typename MultiPolygon>
struct topology_check<MultiPolygon, multi_polygon_tag>
template <typename MultiPolygon, typename EqPPStrategy>
struct topology_check<MultiPolygon, EqPPStrategy, multi_polygon_tag>
: topology_check_areal
{
static const char interior = '2';
static const char boundary = '1';
topology_check(MultiPolygon const&) {}
static bool has_interior() { return true; }
static bool has_boundary() { return true; }
template <typename Point>
static bool check_boundary_point(Point const& ) { return true; }
};

View File

@@ -2,6 +2,10 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
@@ -21,21 +25,25 @@ namespace boost { namespace geometry
namespace detail { namespace section
{
template <typename ExpandBoxStrategy>
struct get_section_box
{
template <typename Box, typename Section>
static inline void apply(Box& total, Section const& section)
{
geometry::expand(total, section.bounding_box);
geometry::expand(total, section.bounding_box,
ExpandBoxStrategy());
}
};
template <typename DisjointBoxBoxStrategy>
struct overlaps_section_box
{
template <typename Box, typename Section>
static inline bool apply(Box const& box, Section const& section)
{
return ! detail::disjoint::disjoint_box_box(box, section.bounding_box);
return ! detail::disjoint::disjoint_box_box(box, section.bounding_box,
DisjointBoxBoxStrategy());
}
};

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -30,6 +30,8 @@ namespace boost { namespace geometry
namespace detail { namespace section
{
// TODO: This code is CS-specific, should be moved to strategies
template
<
std::size_t Dimension,
@@ -68,7 +70,7 @@ struct preceding_check<0, Geometry, spherical_tag>
calc_t const other_min = get<min_corner, 0>(other_box);
calc_t const other_max = get<max_corner, 0>(other_box);
bool const pt_covered = strategy::within::covered_by_range
bool const pt_covered = strategy::within::detail::covered_by_range
<
Point, 0, spherical_tag
>::apply(value,

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-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
@@ -58,6 +58,7 @@
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
@@ -330,9 +331,9 @@ struct assign_loop<T, Count, Count>
template <typename CSTag>
struct box_first_in_section
{
template <typename Box, typename Point, typename Strategy>
template <typename Box, typename Point, typename EnvelopeStrategy>
static inline void apply(Box & box, Point const& prev, Point const& curr,
Strategy const& strategy)
EnvelopeStrategy const& strategy)
{
geometry::model::referring_segment<Point const> seg(prev, curr);
geometry::envelope(seg, box, strategy);
@@ -342,9 +343,9 @@ struct box_first_in_section
template <>
struct box_first_in_section<cartesian_tag>
{
template <typename Box, typename Point, typename Strategy>
template <typename Box, typename Point, typename ExpandStrategy>
static inline void apply(Box & box, Point const& prev, Point const& curr,
Strategy const& )
ExpandStrategy const& )
{
geometry::envelope(prev, box);
geometry::expand(box, curr);
@@ -399,11 +400,20 @@ struct sectionalize_part
{
typedef typename strategy::envelope::services::default_strategy
<
segment_tag,
typename cs_tag<typename Sections::box_type>::type
>::type envelope_strategy_type;
typedef typename strategy::expand::services::default_strategy
<
segment_tag,
typename cs_tag<typename Sections::box_type>::type
>::type expand_strategy_type;
apply(sections, begin, end,
robust_policy, envelope_strategy_type(),
robust_policy,
envelope_strategy_type(),
expand_strategy_type(),
ring_id, max_count);
}
@@ -412,12 +422,14 @@ struct sectionalize_part
typename Iterator,
typename RobustPolicy,
typename Sections,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
static inline void apply(Sections& sections,
Iterator begin, Iterator end,
RobustPolicy const& robust_policy,
EnvelopeStrategy const& strategy,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -535,14 +547,14 @@ struct sectionalize_part
// In cartesian this is envelope of previous point expanded with current point
// in non-cartesian this is envelope of a segment
box_first_in_section<typename cs_tag<robust_point_type>::type>
::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
::apply(section.bounding_box, previous_robust_point, current_robust_point, envelope_strategy);
}
else
{
// In cartesian this is expand with current point
// in non-cartesian this is expand with a segment
box_next_in_section<typename cs_tag<robust_point_type>::type>
::apply(section.bounding_box, previous_robust_point, current_robust_point, strategy);
::apply(section.bounding_box, previous_robust_point, current_robust_point, expand_strategy);
}
section.end_index = index + 1;
@@ -588,12 +600,14 @@ struct sectionalize_range
typename Range,
typename RobustPolicy,
typename Sections,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
static inline void apply(Range const& range,
RobustPolicy const& robust_policy,
Sections& sections,
EnvelopeStrategy const& strategy,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -622,7 +636,8 @@ struct sectionalize_range
sectionalize_part<Point, DimensionVector>::apply(sections,
boost::begin(view), boost::end(view),
robust_policy, strategy, ring_id, max_count);
robust_policy, envelope_strategy, expand_strategy,
ring_id, max_count);
}
};
@@ -638,12 +653,14 @@ struct sectionalize_polygon
typename Polygon,
typename RobustPolicy,
typename Sections,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
static inline void apply(Polygon const& poly,
RobustPolicy const& robust_policy,
Sections& sections,
EnvelopeStrategy const& strategy,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -655,7 +672,8 @@ struct sectionalize_polygon
> per_range;
ring_id.ring_index = -1;
per_range::apply(exterior_ring(poly), robust_policy, sections, strategy, ring_id, max_count);
per_range::apply(exterior_ring(poly), robust_policy, sections,
envelope_strategy, expand_strategy, ring_id, max_count);
ring_id.ring_index++;
typename interior_return_type<Polygon const>::type
@@ -663,7 +681,8 @@ struct sectionalize_polygon
for (typename detail::interior_iterator<Polygon const>::type
it = boost::begin(rings); it != boost::end(rings); ++it, ++ring_id.ring_index)
{
per_range::apply(*it, robust_policy, sections, strategy, ring_id, max_count);
per_range::apply(*it, robust_policy, sections,
envelope_strategy, expand_strategy, ring_id, max_count);
}
}
};
@@ -676,12 +695,14 @@ struct sectionalize_box
typename Box,
typename RobustPolicy,
typename Sections,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
static inline void apply(Box const& box,
RobustPolicy const& robust_policy,
Sections& sections,
EnvelopeStrategy const& ,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
ring_identifier const& ring_id, std::size_t max_count)
{
typedef typename point_type<Box>::type point_type;
@@ -714,7 +735,7 @@ struct sectionalize_box
point_type,
DimensionVector
>::apply(points, robust_policy, sections,
strategy::envelope::cartesian_segment<>(),
envelope_strategy, expand_strategy,
ring_id, max_count);
}
};
@@ -727,12 +748,14 @@ struct sectionalize_multi
typename MultiGeometry,
typename RobustPolicy,
typename Sections,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
static inline void apply(MultiGeometry const& multi,
RobustPolicy const& robust_policy,
Sections& sections,
EnvelopeStrategy const& strategy,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
ring_identifier ring_id,
std::size_t max_count)
{
@@ -742,7 +765,9 @@ struct sectionalize_multi
it != boost::end(multi);
++it, ++ring_id.multi_index)
{
Policy::apply(*it, robust_policy, sections, strategy, ring_id, max_count);
Policy::apply(*it, robust_policy, sections,
envelope_strategy, expand_strategy,
ring_id, max_count);
}
}
};
@@ -915,12 +940,14 @@ template
typename Geometry,
typename Sections,
typename RobustPolicy,
typename EnvelopeStrategy
typename EnvelopeStrategy,
typename ExpandStrategy
>
inline void sectionalize(Geometry const& geometry,
RobustPolicy const& robust_policy,
Sections& sections,
EnvelopeStrategy const& strategy,
EnvelopeStrategy const& envelope_strategy,
ExpandStrategy const& expand_strategy,
int source_index = 0,
std::size_t max_count = 10)
{
@@ -959,7 +986,9 @@ inline void sectionalize(Geometry const& geometry,
Geometry,
Reverse,
DimensionVector
>::apply(geometry, robust_policy, sections, strategy, ring_id, max_count);
>::apply(geometry, robust_policy, sections,
envelope_strategy, expand_strategy,
ring_id, max_count);
detail::sectionalize::enlarge_sections(sections);
}
@@ -981,14 +1010,27 @@ inline void sectionalize(Geometry const& geometry,
{
typedef typename strategy::envelope::services::default_strategy
<
typename tag<Geometry>::type,
typename cs_tag<Geometry>::type
>::type envelope_strategy_type;
typedef typename strategy::expand::services::default_strategy
<
typename boost::mpl::if_c
<
boost::is_same<typename tag<Geometry>::type, box_tag>::value,
box_tag,
segment_tag
>::type,
typename cs_tag<Geometry>::type
>::type expand_strategy_type;
boost::geometry::sectionalize
<
Reverse, DimensionVector
>(geometry, robust_policy, sections,
envelope_strategy_type(),
expand_strategy_type(),
source_index, max_count);
}

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -70,13 +70,7 @@ struct within
Geometry2 const& geometry2,
Strategy const& strategy)
{
concepts::within::check
<
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
Strategy
>();
concepts::within::check<Geometry1, Geometry2, Strategy>();
return dispatch::within<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
}

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2014 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
@@ -45,6 +45,11 @@ namespace boost { namespace geometry {
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within {
template <typename Point1, typename Point2, typename Strategy>
inline bool equals_point_point(Point1 const& p1, Point2 const& p2, Strategy const& strategy)
{
return equals::equals_point_point(p1, p2, strategy.get_equals_point_point_strategy());
}
// TODO: is this needed?
inline int check_result_type(int result)
@@ -139,8 +144,8 @@ struct point_in_geometry<Segment, segment_tag>
return -1; // exterior
// if the point is equal to the one of the terminal points
if ( detail::equals::equals_point_point(point, p0)
|| detail::equals::equals_point_point(point, p1) )
if ( detail::within::equals_point_point(point, p0, strategy)
|| detail::within::equals_point_point(point, p1, strategy) )
return 0; // boundary
else
return 1; // interior
@@ -161,11 +166,11 @@ struct point_in_geometry<Linestring, linestring_tag>
return -1; // exterior
// if the linestring doesn't have a boundary
if (detail::equals::equals_point_point(range::front(linestring), range::back(linestring)))
if (detail::within::equals_point_point(range::front(linestring), range::back(linestring), strategy))
return 1; // interior
// else if the point is equal to the one of the terminal points
else if (detail::equals::equals_point_point(point, range::front(linestring))
|| detail::equals::equals_point_point(point, range::back(linestring)))
else if (detail::within::equals_point_point(point, range::front(linestring), strategy)
|| detail::within::equals_point_point(point, range::back(linestring), strategy))
return 0; // boundary
else
return 1; // interior
@@ -304,12 +309,12 @@ struct point_in_geometry<Geometry, multi_linestring_tag>
point_type const& back = range::back(*it);
// is closed_ring - no boundary
if ( detail::equals::equals_point_point(front, back) )
if ( detail::within::equals_point_point(front, back, strategy) )
continue;
// is point on boundary
if ( detail::equals::equals_point_point(point, front)
|| detail::equals::equals_point_point(point, back) )
if ( detail::within::equals_point_point(point, front, strategy)
|| detail::within::equals_point_point(point, back, strategy) )
{
++boundaries;
}
@@ -361,13 +366,7 @@ namespace detail { namespace within {
template <typename Point, typename Geometry, typename Strategy>
inline int point_in_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
concepts::within::check
<
typename tag<Point>::type,
typename tag<Geometry>::type,
typename tag_cast<typename tag<Geometry>::type, areal_tag>::type,
Strategy
>();
concepts::within::check<Point, Geometry, Strategy>();
return detail_dispatch::within::point_in_geometry<Geometry>::apply(point, geometry, strategy);
}

View File

@@ -4,10 +4,11 @@
// 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.
// This file was modified by Oracle on 2015, 2018.
// Modifications copyright (c) 2015-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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -35,8 +36,7 @@ namespace dispatch
template
<
typename Geometry,
typename Tag = typename tag<Geometry>::type,
typename CS_Tag = typename cs_tag<Geometry>::type
typename Tag = typename tag<Geometry>::type
>
struct envelope : not_implemented<Tag>
{};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017, 2018.
// Modifications copyright (c) 2015-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
@@ -41,9 +41,7 @@ template
<
typename GeometryOut, typename Geometry,
typename TagOut = typename tag<GeometryOut>::type,
typename Tag = typename tag<Geometry>::type,
typename CSTagOut = typename cs_tag<GeometryOut>::type,
typename CSTag = typename cs_tag<Geometry>::type
typename Tag = typename tag<Geometry>::type
>
struct expand : not_implemented<TagOut, Tag>
{};

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017.
// Modifications copyright (c) 2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -45,6 +45,9 @@ struct ring_is_convex
template <typename Ring, typename SideStrategy>
static inline bool apply(Ring const& ring, SideStrategy const& strategy)
{
typename SideStrategy::equals_point_point_strategy_type
eq_pp_strategy = strategy.get_equals_point_point_strategy();
std::size_t n = boost::size(ring);
if (boost::size(ring) < core_detail::closure::minimum_ring_size
<
@@ -67,7 +70,8 @@ struct ring_is_convex
current++;
std::size_t index = 1;
while (equals::equals_point_point(*current, *previous) && index < n)
while (equals::equals_point_point(*current, *previous, eq_pp_strategy)
&& index < n)
{
current++;
index++;
@@ -81,7 +85,7 @@ struct ring_is_convex
it_type next = current;
next++;
while (equals::equals_point_point(*current, *next))
while (equals::equals_point_point(*current, *next, eq_pp_strategy))
{
next++;
}
@@ -105,7 +109,7 @@ struct ring_is_convex
// Advance next to next different point
// (because there are non-equal points, this loop is not infinite)
next++;
while (equals::equals_point_point(*current, *next))
while (equals::equals_point_point(*current, *next, eq_pp_strategy))
{
next++;
}

View File

@@ -4,6 +4,11 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// 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.
@@ -53,12 +58,13 @@ namespace boost { namespace geometry
namespace detail { namespace simplify
{
template <typename Range>
inline bool is_degenerate(Range const& range)
template <typename Range, typename EqualsStrategy>
inline bool is_degenerate(Range const& range, EqualsStrategy const& strategy)
{
return boost::size(range) == 2
&& detail::equals::equals_point_point(geometry::range::front(range),
geometry::range::back(range));
geometry::range::back(range),
strategy);
}
struct simplify_range_insert
@@ -67,9 +73,12 @@ struct simplify_range_insert
static inline void apply(Range const& range, OutputIterator out,
Distance const& max_distance, Strategy const& strategy)
{
typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type
equals_strategy_type;
boost::ignore_unused(strategy);
if (is_degenerate(range))
if (is_degenerate(range, equals_strategy_type()))
{
std::copy(boost::begin(range), boost::begin(range) + 1, out);
}
@@ -107,6 +116,9 @@ struct simplify_range
static inline void apply(RangeIn const& range, RangeOut& out,
Distance const& max_distance, Strategy const& strategy)
{
typedef typename Strategy::distance_strategy_type::equals_point_point_strategy_type
equals_strategy_type;
// For a RING:
// Note that, especially if max_distance is too large,
// the output ring might be self intersecting while the input ring is
@@ -126,7 +138,7 @@ struct simplify_range
// Verify the two remaining points are equal. If so, remove one of them.
// This can cause the output being under the minimum size
if (is_degenerate(out))
if (is_degenerate(out, equals_strategy_type()))
{
range::resize(out, 1);
}

View File

@@ -2,8 +2,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014, 2017.
// Modifications copyright (c) 2014-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017, 2018.
// Modifications 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
@@ -279,9 +279,10 @@ struct union_
{
typedef typename boost::range_value<Collection>::type geometry_out;
typedef typename strategy::intersection::services::default_strategy
typedef typename strategy::relate::services::default_strategy
<
typename cs_tag<geometry_out>::type
Geometry1,
Geometry2
>::type strategy_type;
dispatch::union_insert

View File

@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2018.
// Modifications 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -22,7 +23,6 @@
#include <cstddef>
#include <boost/mpl/assert.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
@@ -56,7 +56,7 @@ namespace core_detail
{
template <typename DegreeOrRadian>
struct coordinate_system_units
struct define_angular_units
{
BOOST_MPL_ASSERT_MSG
((false),
@@ -65,13 +65,13 @@ struct coordinate_system_units
};
template <>
struct coordinate_system_units<geometry::degree>
struct define_angular_units<geometry::degree>
{
typedef geometry::degree units;
};
template <>
struct coordinate_system_units<geometry::radian>
struct define_angular_units<geometry::radian>
{
typedef geometry::radian units;
};
@@ -107,12 +107,8 @@ known as lat,long or lo,la or phi,lambda
*/
template<typename DegreeOrRadian>
struct geographic
{
typedef typename core_detail::coordinate_system_units
<
DegreeOrRadian
>::units units;
};
: core_detail::define_angular_units<DegreeOrRadian>
{};
@@ -136,12 +132,8 @@ struct geographic
*/
template<typename DegreeOrRadian>
struct spherical
{
typedef typename core_detail::coordinate_system_units
<
DegreeOrRadian
>::units units;
};
: core_detail::define_angular_units<DegreeOrRadian>
{};
/*!
@@ -156,12 +148,8 @@ struct spherical
*/
template<typename DegreeOrRadian>
struct spherical_equatorial
{
typedef typename core_detail::coordinate_system_units
<
DegreeOrRadian
>::units units;
};
: core_detail::define_angular_units<DegreeOrRadian>
{};
@@ -174,12 +162,15 @@ struct spherical_equatorial
*/
template<typename DegreeOrRadian>
struct polar
{
typedef typename core_detail::coordinate_system_units
<
DegreeOrRadian
>::units units;
};
: core_detail::define_angular_units<DegreeOrRadian>
{};
/*!
\brief Undefined coordinate system
\ingroup cs
*/
struct undefined {};
} // namespace cs
@@ -227,9 +218,18 @@ struct cs_tag<cs::cartesian>
};
template <>
struct cs_tag<cs::undefined>
{
typedef cs_undefined_tag type;
};
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
} // namespace traits
/*!
\brief Meta-function returning coordinate system tag (cs family) of any geometry
\tparam Geometry \tparam_geometry
@@ -245,24 +245,97 @@ struct cs_tag
};
/*!
\brief Meta-function to verify if a coordinate system is radian
\tparam CoordinateSystem Any coordinate system.
\ingroup core
*/
template <typename CoordinateSystem>
struct is_radian : boost::true_type {};
#ifndef DOXYGEN_NO_SPECIALIZATIONS
// Specialization for any degree coordinate systems
template <template<typename> class CoordinateSystem>
struct is_radian< CoordinateSystem<degree> > : boost::false_type
namespace traits
{
// cartesian or undefined
template <typename CoordinateSystem>
struct cs_angular_units
{
typedef geometry::radian type;
};
#endif // DOXYGEN_NO_SPECIALIZATIONS
#ifndef DOXYGEN_NO_TRAITS_SPECIALIZATIONS
template<typename DegreeOrRadian>
struct cs_angular_units<cs::geographic<DegreeOrRadian> >
{
typedef DegreeOrRadian type;
};
template<typename DegreeOrRadian>
struct cs_angular_units<cs::spherical<DegreeOrRadian> >
{
typedef DegreeOrRadian type;
};
template<typename DegreeOrRadian>
struct cs_angular_units<cs::spherical_equatorial<DegreeOrRadian> >
{
typedef DegreeOrRadian type;
};
#endif // DOXYGEN_NO_TRAITS_SPECIALIZATIONS
} // namespace traits
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <typename Geometry>
struct cs_angular_units
{
typedef typename traits::cs_angular_units
<
typename geometry::coordinate_system<Geometry>::type
>::type type;
};
template <typename Units, typename CsTag>
struct cs_tag_to_coordinate_system
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM,
(types<CsTag>));
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, cs_undefined_tag>
{
typedef cs::undefined type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, cartesian_tag>
{
typedef cs::cartesian type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
{
typedef cs::spherical_equatorial<Units> type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, spherical_polar_tag>
{
typedef cs::spherical<Units> type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, geographic_tag>
{
typedef cs::geographic<Units> type;
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2018.
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -25,6 +25,9 @@ namespace boost { namespace geometry
// Tags defining strategies linked to coordinate systems
/// Tag used for undefined coordinate system
struct cs_undefined_tag {};
/// Tag used for casting spherical/geographic coordinate systems
struct spherical_tag {};

View File

@@ -13,6 +13,7 @@
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/radian_access.hpp>
#include <boost/geometry/core/radius.hpp>
@@ -98,7 +99,7 @@ static inline PointSph cart3d_to_sph(Point3d const& point_3d)
math::normalize_spheroidal_coordinates
<
typename coordinate_system<PointSph>::type::units,
typename detail::cs_angular_units<PointSph>::type,
coord_t
>(lon, lat);
@@ -183,6 +184,7 @@ inline T spherical_azimuth(T const& lon1, T const& lat1, T const& lon2, T const&
template <typename T>
inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2)
{
T const c0 = 0;
T const pi = math::pi<T>();
T const two_pi = math::two_pi<T>();
@@ -213,7 +215,7 @@ inline int azimuth_side_value(T const& azi_a1_p, T const& azi_a1_a2)
// the difference to 0 as well
// positive azimuth is on the right side
return math::equals(a_diff, 0)
return math::equals(a_diff, c0)
|| math::equals(a_diff, pi)
|| math::equals(a_diff, -pi) ? 0
: a_diff > 0 ? -1 // right

View File

@@ -32,60 +32,6 @@ namespace boost { namespace geometry
namespace detail { namespace helper_geometries
{
template <typename Geometry, typename CS_Tag = typename cs_tag<Geometry>::type>
struct default_units
{
typedef typename coordinate_system<Geometry>::type::units type;
};
// The Cartesian coordinate system does not define the type units.
// For that reason the generic implementation for default_units cannot be used
// and specialization needs to be defined.
// Moreover, it makes sense to define the units for the Cartesian
// coordinate system to be radians, as this way a Cartesian point can
// potentially be used in algorithms taking non-Cartesian strategies
// and work as if it was as point in the non-Cartesian coordinate
// system with radian units.
template <typename Geometry>
struct default_units<Geometry, cartesian_tag>
{
typedef radian type;
};
template <typename Units, typename CS_Tag>
struct cs_tag_to_coordinate_system
{
BOOST_MPL_ASSERT_MSG((false),
NOT_IMPLEMENTED_FOR_THIS_COORDINATE_SYSTEM,
(types<CS_Tag>));
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, cartesian_tag>
{
typedef cs::cartesian type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, spherical_equatorial_tag>
{
typedef cs::spherical_equatorial<Units> type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, spherical_polar_tag>
{
typedef cs::spherical<Units> type;
};
template <typename Units>
struct cs_tag_to_coordinate_system<Units, geographic_tag>
{
typedef cs::geographic<Units> type;
};
template
<
typename Point,
@@ -154,10 +100,7 @@ template
<
typename Geometry,
typename NewCoordinateType = typename coordinate_type<Geometry>::type,
typename NewUnits = typename detail::helper_geometries::default_units
<
Geometry
>::type
typename NewUnits = typename detail::cs_angular_units<Geometry>::type
>
struct helper_geometry
{

View File

@@ -2,7 +2,7 @@
//
// boxes union/intersection area/volume
//
// Copyright (c) 2011-2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -24,7 +24,12 @@ namespace boost { namespace geometry { namespace index { namespace detail {
template <typename Box>
inline typename default_content_result<Box>::type intersection_content(Box const& box1, Box const& box2)
{
bool const intersects = ! geometry::detail::disjoint::box_box<Box, Box>::apply(box1, box2);
typedef typename strategy::disjoint::services::default_strategy
<
Box, Box
>::type strategy_type;
bool const intersects = ! geometry::detail::disjoint::disjoint_box_box(box1, box2, strategy_type());
if ( intersects )
{

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2015.
// Modifications copyright (c) 2014-2015 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2015, 2018.
// Modifications copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -39,7 +39,7 @@
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/append.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_point.hpp>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
@@ -295,7 +295,7 @@ struct stateful_range_appender<Geometry, open>
should_append
= is_next_expected
|| pt_index < core_detail::closure::minimum_ring_size<open>::value
|| !detail::equals::equals_point_point(point, first_point);
|| disjoint(point, first_point);
}
++pt_index;
@@ -306,6 +306,17 @@ struct stateful_range_appender<Geometry, open>
}
private:
static inline bool disjoint(point_type const& p1, point_type const& p2)
{
// TODO: pass strategy
typedef typename strategy::disjoint::services::default_strategy
<
point_type, point_type
>::type strategy_type;
return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
}
size_type pt_index;
point_type first_point;
};

View File

@@ -5,8 +5,8 @@
// Copyright (c) 2009-2017 Mateusz Loskot, London, UK.
// Copyright (c) 2014-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2015.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@@ -162,7 +162,7 @@ struct wkt_range
if (ForceClosurePossible
&& force_closure
&& boost::size(range) > 1
&& detail::disjoint::disjoint_point_point(*begin, *(end - 1)))
&& wkt_range::disjoint(*begin, *(end - 1)))
{
os << ",";
stream_type::apply(os, *begin);
@@ -174,6 +174,17 @@ struct wkt_range
private:
typedef typename boost::range_value<Range>::type point_type;
static inline bool disjoint(point_type const& p1, point_type const& p2)
{
// TODO: pass strategy
typedef typename strategy::disjoint::services::default_strategy
<
point_type, point_type
>::type strategy_type;
return detail::disjoint::disjoint_point_point(p1, p2, strategy_type());
}
};
/*!

View File

@@ -59,15 +59,11 @@ template
<
typename PtIn,
typename PtOut,
bool SameUnits = geometry::is_radian
bool SameUnits = boost::is_same
<
typename geometry::coordinate_system<PtIn>::type
>::type::value
==
geometry::is_radian
<
typename geometry::coordinate_system<PtOut>::type
>::type::value
typename geometry::detail::cs_angular_units<PtIn>::type,
typename geometry::detail::cs_angular_units<PtOut>::type
>::value
>
struct transform_geometry_point_coordinates
{

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// 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.
@@ -60,16 +64,17 @@ struct decide_covered_by
// This strategy is not suitable for boxes in non-cartesian CSes having edges
// longer than 180deg because e.g. the SSF formula picks the side of the closer
// longitude, so for long edges the side is the opposite.
template <typename Point, typename Box, typename Decide = decide_within>
template <typename Decide = decide_within>
struct point_in_box_by_side
{
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Box>::type
>::type side_strategy_type;
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
typedef typename strategy::side::services::default_strategy
<
typename cs_tag<Box>::type
>::type side_strategy_type;
// Create (counterclockwise) array of points, the fifth one closes it
// Every point should be on the LEFT side (=1), or ON the border (=0),
// So >= 1 or >= 0

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2017 Oracle and/or its affiliates.
// Copyright (c) 2014-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,10 +12,12 @@
#ifndef BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP
#define BOOST_GEOMETRY_STRATEGY_AGNOSTIC_POINT_IN_POINT_HPP
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
namespace boost { namespace geometry
@@ -26,59 +28,32 @@ namespace strategy { namespace within
template
<
typename Point1, typename Point2
typename Point1, typename Point2,
typename CSTag = typename cs_tag<Point1>::type
>
struct point_in_point
{
static inline bool apply(Point1 const& point1, Point2 const& point2)
{
return geometry::detail::equals::equals_point_point(point1, point2);
}
};
: strategy::within::cartesian_point_point
{};
template <typename Point1, typename Point2>
struct point_in_point<Point1, Point2, spherical_equatorial_tag>
: strategy::within::spherical_point_point
{};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
template <typename Point1, typename Point2>
struct point_in_point<Point1, Point2, spherical_polar_tag>
: strategy::within::spherical_point_point
{};
namespace services
{
template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2, typename AnyCS1, typename AnyCS2>
struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, AnyCS1, AnyCS2>
{
typedef strategy::within::point_in_point
<
typename point_type<PointLike1>::type,
typename point_type<PointLike2>::type
> type;
};
} // namespace services
#endif
template <typename Point1, typename Point2>
struct point_in_point<Point1, Point2, geographic_tag>
: strategy::within::spherical_point_point
{};
}} // namespace strategy::within
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace strategy { namespace covered_by { namespace services
{
template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2, typename AnyCS1, typename AnyCS2>
struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, AnyCS1, AnyCS2>
{
typedef strategy::within::point_in_point
<
typename point_type<PointLike1>::type,
typename point_type<PointLike2>::type
> type;
};
}}} // namespace strategy::covered_by::services
#endif
}} // namespace boost::geometry

View File

@@ -0,0 +1,111 @@
// 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.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland.
// 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
// 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_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
namespace boost { namespace geometry { namespace strategy { namespace disjoint
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template
<
typename Box1, typename Box2,
std::size_t Dimension = 0,
std::size_t DimensionCount = dimension<Box1>::value
>
struct box_box
{
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>
struct box_box<Box1, Box2, DimensionCount, DimensionCount>
{
static inline bool apply(Box1 const& , Box2 const& )
{
return false;
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
struct cartesian_box_box
{
template <typename Box1, typename Box2>
static inline bool apply(Box1 const& box1, Box2 const& box2)
{
return detail::box_box<Box1, Box2>::apply(box1, box2);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Box1, typename Box2, int TopDim1, int TopDim2>
struct default_strategy<Box1, Box2, box_tag, box_tag, TopDim1, TopDim2, cartesian_tag, cartesian_tag>
{
typedef disjoint::cartesian_box_box type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}}}} // namespace boost::geometry::strategy::disjoint
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_DISJOINT_BOX_BOX_HPP

View File

@@ -4,10 +4,11 @@
// Copyright (c) 2008-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2018.
// Modifications 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
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
@@ -36,6 +37,7 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/default_distance_result.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
@@ -76,6 +78,8 @@ template
class projected_point
{
public :
typedef within::cartesian_point_point equals_point_point_strategy_type;
// The three typedefs below are necessary to calculate distances
// from segments defined in integer coordinates.

View File

@@ -0,0 +1,153 @@
// 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, 2016, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// 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_STRATEGIES_CARTESIAN_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/geometry/algorithms/detail/envelope/initialize.hpp>
#include <boost/geometry/strategies/cartesian/envelope_box.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/cartesian/expand_box.hpp>
#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template <typename CalculationType = void>
class cartesian
{
public:
typedef cartesian_point element_envelope_strategy_type;
static inline element_envelope_strategy_type get_element_envelope_strategy()
{
return element_envelope_strategy_type();
}
typedef expand::cartesian_point element_expand_strategy_type;
static inline element_expand_strategy_type get_element_expand_strategy()
{
return element_expand_strategy_type();
}
typedef expand::cartesian_box box_expand_strategy_type;
static inline box_expand_strategy_type get_box_expand_strategy()
{
return box_expand_strategy_type();
}
// Linestring, Ring, Polygon
template <typename Range>
static inline typename boost::range_iterator<Range const>::type begin(Range const& range)
{
return boost::begin(range);
}
template <typename Range>
static inline typename boost::range_iterator<Range const>::type end(Range const& range)
{
return boost::end(range);
}
// MultiLinestring, MultiPolygon
template <typename Box>
struct multi_state
{
multi_state()
: m_initialized(false)
{}
void apply(Box const& single_box)
{
if (! m_initialized)
{
m_box = single_box;
m_initialized = true;
}
else
{
box_expand_strategy_type::apply(m_box, single_box);
}
}
void result(Box & box)
{
if (m_initialized)
{
box = m_box;
}
else
{
geometry::detail::envelope::initialize<Box, 0, dimension<Box>::value>::apply(box);
}
}
private:
bool m_initialized;
Box m_box;
};
// Segment
template <typename Point1, typename Point2, typename Box>
static inline void apply(Point1 const& point1, Point2 const& point2,
Box& box)
{
cartesian_segment<CalculationType>::apply(point1, point2, box);
}
// Box
template <typename BoxIn, typename Box>
static inline void apply(BoxIn const& box_in, Box& box)
{
cartesian_box::apply(box_in, box);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian<CalculationType> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_HPP

View File

@@ -0,0 +1,119 @@
// 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-2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/algorithms/detail/envelope/transform_units.hpp>
#include <boost/geometry/algorithms/dispatch/envelope.hpp>
#include <boost/geometry/strategies/envelope.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace envelope
{
template
<
std::size_t Index,
std::size_t Dimension,
std::size_t DimensionCount
>
struct envelope_indexed_box
{
template <typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
detail::indexed_point_view<BoxIn const, Index> box_in_corner(box_in);
detail::indexed_point_view<BoxOut, Index> mbr_corner(mbr);
detail::conversion::point_to_point
<
detail::indexed_point_view<BoxIn const, Index>,
detail::indexed_point_view<BoxOut, Index>,
Dimension,
DimensionCount
>::apply(box_in_corner, mbr_corner);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace envelope
{
struct cartesian_box
{
template<typename BoxIn, typename BoxOut>
static inline void apply(BoxIn const& box_in, BoxOut& mbr)
{
geometry::detail::envelope::envelope_indexed_box
<
min_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
geometry::detail::envelope::envelope_indexed_box
<
max_corner, 0, dimension<BoxIn>::value
>::apply(box_in, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_box type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_BOX_HPP

View File

@@ -0,0 +1,59 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/envelope/range.hpp>
#include <boost/geometry/strategies/cartesian/envelope.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
class cartesian_multipoint
{
public:
template <typename MultiPoint, typename Box>
static inline void apply(MultiPoint const& multipoint, Box& mbr)
{
geometry::detail::envelope::envelope_range::apply(multipoint, mbr, cartesian<>());
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<multi_point_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_multipoint type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_MULTIPOINT_HPP

View File

@@ -0,0 +1,111 @@
// 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, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/coordinate_system.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/strategies/envelope.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
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);
}
};
}} // namespace detail::envelope
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace envelope
{
struct cartesian_point
{
template <typename Point, typename Box>
static inline void apply(Point const& point, Box& mbr)
{
geometry::detail::envelope::envelope_one_point
<
0, dimension<Point>::value
>::apply(point, mbr);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_point type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_POINT_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017 Oracle and/or its affiliates.
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -11,40 +11,61 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_ENVELOPE_SEGMENT_HPP
#include <cstddef>
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/cartesian/envelope_point.hpp>
#include <boost/geometry/strategies/cartesian/expand_point.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
namespace boost { namespace geometry { namespace strategy { namespace envelope
{
namespace strategy { namespace envelope
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
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)
{
geometry::detail::envelope::envelope_one_point
<
Dimension, DimensionCount
>::apply(p1, mbr);
strategy::expand::detail::point_loop
<
Dimension, DimensionCount
>::apply(mbr, p2);
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
template
<
typename CalculationType = void
>
class cartesian_segment
{
public :
template <typename Point1, typename Point2, typename Box>
inline void
apply(Point1 const& point1, Point2 const& point2, Box& box) const
public:
template <typename Point, typename Box>
static inline void apply(Point const& point1, Point const& point2, Box& box)
{
geometry::detail::envelope::envelope_one_segment
<
0,
dimension<Point1>::value
>
::apply(point1,
point2,
box,
strategy::envelope::cartesian_segment<CalculationType>());
strategy::envelope::detail::envelope_one_segment
<
0,
dimension<Point>::value
>::apply(point1, point2, box);
}
};
@@ -55,7 +76,7 @@ namespace services
{
template <typename CalculationType>
struct default_strategy<cartesian_tag, CalculationType>
struct default_strategy<segment_tag, cartesian_tag, CalculationType>
{
typedef strategy::envelope::cartesian_segment<CalculationType> type;
};

View File

@@ -0,0 +1,69 @@
// 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.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
struct cartesian_box
{
template <typename BoxOut, typename BoxIn>
static void apply(BoxOut & box_out, BoxIn const& box_in)
{
geometry::detail::expand::expand_indexed
<
0, dimension<BoxIn>::value
>::apply(box_out, box_in);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<box_tag, cartesian_tag, CalculationType>
{
typedef cartesian_box type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_BOX_HPP

View File

@@ -0,0 +1,125 @@
// 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.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015-2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// 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_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP
#include <cstddef>
#include <functional>
#include <boost/geometry/core/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/tags.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
template <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 select_coordinate_type
<
Point, Box
>::type coordinate_type;
std::less<coordinate_type> less;
std::greater<coordinate_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<Dimension + 1, DimensionCount>::apply(box, source);
}
};
template <std::size_t DimensionCount>
struct point_loop<DimensionCount, DimensionCount>
{
template <typename Box, typename Point>
static inline void apply(Box&, Point const&) {}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
struct cartesian_point
{
template <typename Box, typename Point>
static void apply(Box & box, Point const& point)
{
expand::detail::point_loop
<
0, dimension<Point>::value
>::apply(box, point);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<point_tag, cartesian_tag, CalculationType>
{
typedef cartesian_point type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_POINT_HPP

View File

@@ -0,0 +1,71 @@
// 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.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#include <boost/geometry/strategies/expand.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
class cartesian_segment
{
public:
template <typename Box, typename Segment>
static void apply(Box & box, Segment const& segment)
{
geometry::detail::expand::expand_indexed
<
0, dimension<Segment>::value
>::apply(box, segment);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, cartesian_tag, CalculationType>
{
typedef cartesian_segment type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_CARTESIAN_EXPAND_SEGMENT_HPP

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013-2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2014, 2016, 2017.
// Modifications copyright (c) 2014-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2016, 2017, 2018.
// Modifications 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
@@ -34,8 +34,12 @@
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/cartesian/area.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/distance_pythagoras.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/cartesian/envelope.hpp>
#include <boost/geometry/strategies/cartesian/expand_box.hpp>
#include <boost/geometry/strategies/cartesian/expand_segment.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
@@ -132,14 +136,44 @@ struct cartesian_segments
return strategy_type();
}
typedef envelope::cartesian_segment<CalculationType>
envelope_strategy_type;
typedef envelope::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
return envelope_strategy_type();
}
typedef expand::cartesian_segment expand_strategy_type;
static inline expand_strategy_type get_expand_strategy()
{
return expand_strategy_type();
}
typedef within::cartesian_point_point point_in_point_strategy_type;
static inline point_in_point_strategy_type get_point_in_point_strategy()
{
return point_in_point_strategy_type();
}
typedef within::cartesian_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type;
static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
{
return disjoint_box_box_strategy_type();
}
typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type;
typedef expand::cartesian_box expand_box_strategy_type;
template <typename CoordinateType, typename SegmentRatio>
struct segment_intersection_info
{
@@ -314,12 +348,12 @@ struct cartesian_segments
BOOST_CONCEPT_ASSERT( (concepts::ConstSegment<Segment2>) );
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);
bool const a_is_point = equals_point_point(robust_a1, robust_a2, point_in_point_strategy_type());
bool const b_is_point = equals_point_point(robust_b1, robust_b2, point_in_point_strategy_type());
if(a_is_point && b_is_point)
{
return equals_point_point(robust_a1, robust_b2)
return equals_point_point(robust_a1, robust_b2, point_in_point_strategy_type())
? Policy::degenerate(a, true)
: Policy::disjoint()
;

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015-2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015-2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -22,6 +22,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
@@ -33,6 +34,10 @@ namespace boost { namespace geometry { namespace strategy
namespace within
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
struct within_coord
{
template <typename Value1, typename Value2>
@@ -101,7 +106,7 @@ struct longitude_range
<
Value1, Value2
>::type calc_t;
typedef typename coordinate_system<Geometry>::type::units units_t;
typedef typename geometry::detail::cs_angular_units<Geometry>::type units_t;
typedef math::detail::constants_on_spheroid<calc_t, units_t> constants;
if (CoordCheck::apply(value, min_value, max_value))
@@ -142,18 +147,16 @@ struct covered_by_range<Geometry, 0, spherical_tag>
template
<
template <typename, std::size_t, typename> class SubStrategy,
typename Point,
typename Box,
typename CSTag, // cartesian_tag or spherical_tag
std::size_t Dimension,
std::size_t DimensionCount
>
struct relate_point_box_loop
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
typedef typename tag_cast<typename cs_tag<Point>::type, spherical_tag>::type cs_tag_t;
if (! SubStrategy<Point, Dimension, cs_tag_t>::apply(get<Dimension>(point),
if (! SubStrategy<Point, Dimension, CSTag>::apply(get<Dimension>(point),
get<min_corner, Dimension>(box),
get<max_corner, Dimension>(box))
)
@@ -164,7 +167,7 @@ struct relate_point_box_loop
return relate_point_box_loop
<
SubStrategy,
Point, Box,
CSTag,
Dimension + 1, DimensionCount
>::apply(point, box);
}
@@ -174,78 +177,119 @@ struct relate_point_box_loop
template
<
template <typename, std::size_t, typename> class SubStrategy,
typename Point,
typename Box,
typename CSTag,
std::size_t DimensionCount
>
struct relate_point_box_loop<SubStrategy, Point, Box, DimensionCount, DimensionCount>
struct relate_point_box_loop<SubStrategy, CSTag, DimensionCount, DimensionCount>
{
template <typename Point, typename Box>
static inline bool apply(Point const& , Box const& )
{
return true;
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
template
<
typename Point,
typename Box,
template <typename, std::size_t, typename> class SubStrategy = within_range
>
struct point_in_box
struct cartesian_point_box
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
return relate_point_box_loop
return detail::relate_point_box_loop
<
SubStrategy,
Point, Box,
0, dimension<Point>::type::value
detail::within_range,
cartesian_tag,
0, dimension<Point>::value
>::apply(point, box);
}
};
struct spherical_point_box
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
return detail::relate_point_box_loop
<
detail::within_range,
spherical_tag,
0, dimension<Point>::value
>::apply(point, box);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Point, typename Box>
struct default_strategy
<
Point, Box,
point_tag, box_tag,
pointlike_tag, areal_tag,
cartesian_tag, cartesian_tag
>
{
typedef within::cartesian_point_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Point, typename Box>
struct default_strategy
<
Point, Box,
point_tag, box_tag,
pointlike_tag, areal_tag,
spherical_tag, spherical_tag
>
{
typedef within::spherical_point_box type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
} // namespace within
namespace covered_by
{
struct cartesian_point_box
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
return within::detail::relate_point_box_loop
<
within::detail::covered_by_range,
cartesian_tag,
0, dimension<Point>::value
>::apply(point, box);
}
};
struct spherical_point_box
{
template <typename Point, typename Box>
static inline bool apply(Point const& point, Box const& box)
{
return within::detail::relate_point_box_loop
<
within::detail::covered_by_range,
spherical_tag,
0, dimension<Point>::value
>::apply(point, box);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace within { namespace services
{
template <typename Point, typename Box>
struct default_strategy
<
Point, Box,
point_tag, box_tag,
pointlike_tag, areal_tag,
cartesian_tag, cartesian_tag
>
{
typedef within::point_in_box<Point, Box> type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
template <typename Point, typename Box>
struct default_strategy
<
Point, Box,
point_tag, box_tag,
pointlike_tag, areal_tag,
spherical_tag, spherical_tag
>
{
typedef within::point_in_box<Point, Box> type;
};
}} // namespace within::services
namespace covered_by { namespace services
namespace services
{
@@ -258,11 +302,7 @@ struct default_strategy
cartesian_tag, cartesian_tag
>
{
typedef within::point_in_box
<
Point, Box,
within::covered_by_range
> type;
typedef covered_by::cartesian_point_box type;
};
// spherical_equatorial_tag, spherical_polar_tag and geographic_cat are casted to spherical_tag
@@ -275,20 +315,17 @@ struct default_strategy
spherical_tag, spherical_tag
>
{
typedef within::point_in_box
<
Point, Box,
within::covered_by_range
> type;
typedef covered_by::spherical_point_box type;
};
}} // namespace covered_by::services
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
} // namespace covered_by
}}} // namespace boost::geometry::strategy

View File

@@ -0,0 +1,124 @@
// 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.
// Copyright (c) 2013-2015 Adam Wulkiewicz, Lodz, Poland
// 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
// 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_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP
#define BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP
#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/math.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace within
{
template <std::size_t Dimension, std::size_t DimensionCount>
struct point_point_generic
{
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 false;
}
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 true;
}
};
}} // namespace detail::within
#endif // DOXYGEN_NO_DETAIL
namespace strategy { namespace within
{
struct cartesian_point_point
{
template <typename Point1, typename Point2>
static inline bool apply(Point1 const& point1, Point2 const& point2)
{
return geometry::detail::within::point_point_generic
<
0, dimension<Point1>::type::value
>::apply(point1, point2);
}
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, cartesian_tag, cartesian_tag>
{
typedef strategy::within::cartesian_point_point type;
};
} // namespace services
#endif
}} // namespace strategy::within
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace strategy { namespace covered_by { namespace services
{
template <typename PointLike1, typename PointLike2, typename Tag1, typename Tag2>
struct default_strategy<PointLike1, PointLike2, Tag1, Tag2, pointlike_tag, pointlike_tag, cartesian_tag, cartesian_tag>
{
typedef strategy::within::cartesian_point_point type;
};
}}} // namespace strategy::covered_by::services
#endif
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGY_CARTESIAN_POINT_IN_POINT_HPP

View File

@@ -3,8 +3,8 @@
// Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013, 2014, 2016, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2016, 2017, 2018.
// Modifications copyright (c) 2013-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
@@ -23,6 +23,8 @@
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_box_box.hpp>
#include <boost/geometry/strategies/cartesian/side_by_triangle.hpp>
#include <boost/geometry/strategies/covered_by.hpp>
#include <boost/geometry/strategies/within.hpp>
@@ -103,6 +105,20 @@ public:
return side_strategy_type::get_disjoint_strategy();
}
typedef typename side_strategy_type::equals_point_point_strategy_type equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return side_strategy_type::get_equals_point_point_strategy();
}
typedef disjoint::cartesian_box_box disjoint_box_box_strategy_type;
static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
{
return disjoint_box_box_strategy_type();
}
typedef covered_by::cartesian_point_box disjoint_point_box_strategy_type;
// Typedefs and static methods to fulfill the concept
typedef Point point_type;
typedef PointOfSegment segment_point_type;

View File

@@ -4,8 +4,8 @@
// Copyright (c) 2008-2015 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2015 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2015, 2017.
// Modifications copyright (c) 2015-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2015, 2017, 2018.
// Modifications copyright (c) 2015-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
@@ -29,7 +29,8 @@
#include <boost/geometry/util/select_coordinate_type.hpp>
#include <boost/geometry/strategies/cartesian/disjoint_segment_box.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/cartesian/envelope.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/geometry/strategies/compare.hpp>
#include <boost/geometry/strategies/side.hpp>
@@ -70,7 +71,7 @@ class side_by_triangle
};
public :
typedef strategy::envelope::cartesian_segment<CalculationType> envelope_strategy_type;
typedef strategy::envelope::cartesian<CalculationType> envelope_strategy_type;
static inline envelope_strategy_type get_envelope_strategy()
{
@@ -84,6 +85,12 @@ public :
return disjoint_strategy_type();
}
typedef strategy::within::cartesian_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
// Template member function, because it is not always trivial
// or convenient to explicitly mention the typenames in the
// strategy-struct itself.
@@ -166,9 +173,9 @@ public :
// For robustness purposes, first check if any two points are
// the same; in this case simply return that the points are
// collinear
if (geometry::detail::equals::equals_point_point(p1, p2)
|| geometry::detail::equals::equals_point_point(p1, p)
|| geometry::detail::equals::equals_point_point(p2, p))
if (equals_point_point(p1, p2)
|| equals_point_point(p1, p)
|| equals_point_point(p2, p))
{
return PromotedType(0);
}
@@ -258,6 +265,13 @@ public :
: -1;
}
private:
template <typename P1, typename P2>
static inline bool equals_point_point(P1 const& p1, P2 const& p2)
{
typedef equals_point_point_strategy_type strategy_t;
return geometry::detail::equals::equals_point_point(p1, p2, strategy_t());
}
};

View File

@@ -4,6 +4,10 @@
// Copyright (c) 2008-2012 Bruno Lalande, Paris, France.
// Copyright (c) 2009-2012 Mateusz Loskot, London, UK.
// This file was modified by Oracle on 2018.
// Modifications copyright (c) 2018 Oracle and/or its affiliates.
// 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.
@@ -20,6 +24,10 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/function_types/result_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/parameter_type_of.hpp>
@@ -107,7 +115,7 @@ public :
#endif
};
template <typename Strategy>
template <typename Point, typename Box, typename Strategy>
class WithinStrategyPointBox
{
#ifndef DOXYGEN_NO_CONCEPT_MEMBERS
@@ -165,7 +173,7 @@ class WithinStrategyPointBox
public :
BOOST_CONCEPT_USAGE(WithinStrategyPointBox)
{
checker::apply(&Strategy::apply);
checker::apply(&Strategy::template apply<Point, Box>);
}
#endif
};
@@ -241,26 +249,36 @@ namespace within
namespace dispatch
{
template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
template
<
typename Geometry1, typename Geometry2,
typename FirstTag, typename SecondTag, typename CastedTag,
typename Strategy
>
struct check_within
{};
template <typename AnyTag, typename Strategy>
struct check_within<point_tag, AnyTag, areal_tag, Strategy>
template
<
typename Geometry1, typename Geometry2,
typename AnyTag,
typename Strategy
>
struct check_within<Geometry1, Geometry2, point_tag, AnyTag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyPolygonal<Strategy>) );
};
template <typename Strategy>
struct check_within<point_tag, box_tag, areal_tag, Strategy>
template <typename Geometry1, typename Geometry2, typename Strategy>
struct check_within<Geometry1, Geometry2, point_tag, box_tag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Strategy>) );
BOOST_CONCEPT_ASSERT( (WithinStrategyPointBox<Geometry1, Geometry2, Strategy>) );
};
template <typename Strategy>
struct check_within<box_tag, box_tag, areal_tag, Strategy>
template <typename Geometry1, typename Geometry2, typename Strategy>
struct check_within<Geometry1, Geometry2, box_tag, box_tag, areal_tag, Strategy>
{
BOOST_CONCEPT_ASSERT( (WithinStrategyBoxBox<Strategy>) );
};
@@ -274,10 +292,18 @@ struct check_within<box_tag, box_tag, areal_tag, Strategy>
\brief Checks, in compile-time, the concept of any within-strategy
\ingroup concepts
*/
template <typename FirstTag, typename SecondTag, typename CastedTag, typename Strategy>
template <typename Geometry1, typename Geometry2, typename Strategy>
inline void check()
{
dispatch::check_within<FirstTag, SecondTag, CastedTag, Strategy> c;
dispatch::check_within
<
Geometry1,
Geometry2,
typename tag<Geometry1>::type,
typename tag<Geometry2>::type,
typename tag_cast<typename tag<Geometry2>::type, areal_tag>::type,
Strategy
> c;
boost::ignore_unused(c);
}

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017, Oracle and/or its affiliates.
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -77,13 +77,6 @@ struct default_strategy<Box, MultiPoint, box_tag, multi_point_tag, 2, 0>
>
{};
template <typename Box1, typename Box2>
struct default_strategy<Box1, Box2, box_tag, box_tag, 2, 2>
{
// dummy strategy which will be ignored
typedef geometry::default_strategy type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2016-2017 Oracle and/or its affiliates.
// Copyright (c) 2016-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -23,16 +23,17 @@ namespace strategy { namespace envelope { namespace services
/*!
\brief Traits class binding a default envelope strategy to a coordinate system
\ingroup util
\tparam Tag tag of geometry
\tparam CSTag tag of coordinate system
\tparam CalculationType \tparam_calculation
*/
template <typename CSTag, typename CalculationType = void>
template <typename Tag, typename CSTag, typename CalculationType = void>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_TYPE
, (types<CSTag>)
, (types<Tag, CSTag>)
);
};

View File

@@ -0,0 +1,45 @@
// Boost.Geometry
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP
#define BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP
#include <boost/mpl/assert.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand { namespace services
{
/*!
\brief Traits class binding a default envelope strategy to a coordinate system
\ingroup util
\tparam Tag tag of geometry
\tparam CSTag tag of coordinate system
\tparam CalculationType \tparam_calculation
*/
template <typename Tag, typename CSTag, typename CalculationType = void>
struct default_strategy
{
BOOST_MPL_ASSERT_MSG
(
false, NOT_IMPLEMENTED_FOR_THIS_TYPE
, (types<Tag, CSTag>)
);
};
}}} // namespace strategy::expand::services
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_EXPAND_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017 Oracle and/or its affiliates.
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -29,9 +29,14 @@
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
namespace boost { namespace geometry { namespace strategy { namespace disjoint
@@ -89,7 +94,13 @@ public:
> azimuth_geographic(m_spheroid);
return geometry::detail::disjoint::disjoint_segment_box_sphere_or_spheroid
<geographic_tag>::apply(segment, box, azimuth_geographic);
<
geographic_tag
>::apply(segment, box,
azimuth_geographic,
strategy::normalize::spherical_point(),
strategy::covered_by::spherical_point_box(),
strategy::disjoint::spherical_box_box());
}
private:

View File

@@ -28,6 +28,7 @@
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/concepts/distance_concept.hpp>
#include <boost/geometry/strategies/spherical/distance_haversine.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
@@ -84,6 +85,8 @@ template
class geographic_cross_track
{
public :
typedef within::spherical_point_point equals_point_point_strategy_type;
template <typename Point, typename PointOfSegment>
struct return_type
: promote_floating_point
@@ -105,7 +108,7 @@ public :
inline typename return_type<Point, PointOfSegment>::type
apply(Point const& p, PointOfSegment const& sp1, PointOfSegment const& sp2) const
{
typedef typename coordinate_system<Point>::type::units units_type;
typedef typename geometry::detail::cs_angular_units<Point>::type units_type;
return (apply<units_type>(get<0>(sp1), get<1>(sp1),
get<0>(sp2), get<1>(sp2),

View File

@@ -2,6 +2,7 @@
// Copyright (c) 2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -10,8 +11,21 @@
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_DISTANCE_SEGMENT_BOX_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/algorithms/detail/distance/segment_to_box.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/distance_cross_track.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/distance_segment_box.hpp>
#include <boost/geometry/util/promote_floating_point.hpp>
#include <boost/geometry/util/select_calculation_type.hpp>
namespace boost { namespace geometry
{
@@ -107,7 +121,10 @@ struct geographic_segment_box
ReturnType
>(p0,p1,top_left,top_right,bottom_left,bottom_right,
geographic_segment_box<FormulaPolicy, Spheroid, CalculationType>(),
az_strategy, es_strategy);
az_strategy, es_strategy,
normalize::spherical_point(),
covered_by::spherical_point_box(),
disjoint::spherical_box_box());
}
template <typename SPoint, typename BPoint>

View File

@@ -0,0 +1,111 @@
// 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, 2016, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Parts of Boost.Geometry are redesigned from Geodan's Geographic Library
// (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands.
// 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_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/expand_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/spherical/envelope.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace envelope
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic
: public spherical<CalculationType>
{
public:
typedef Spheroid model_type;
inline geographic()
: m_spheroid()
{}
explicit inline geographic(Spheroid const& spheroid)
: m_spheroid(spheroid)
{}
typedef geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> element_envelope_strategy_type;
inline element_envelope_strategy_type get_element_envelope_strategy() const
{
return element_envelope_strategy_type(m_spheroid);
}
typedef expand::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> element_expand_strategy_type;
inline element_expand_strategy_type get_element_expand_strategy() const
{
return element_expand_strategy_type(m_spheroid);
}
template <typename Point1, typename Point2, typename Box>
inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const
{
geographic_segment
<
FormulaPolicy,
Spheroid,
CalculationType
>(m_spheroid).apply(point1, point2, box);
}
private:
Spheroid m_spheroid;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename Tag, typename CalculationType>
struct default_strategy<Tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::geographic<CalculationType> type;
};
}
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::envelope
}} //namepsace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_HPP

View File

@@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2017 Oracle and/or its affiliates.
// Copyright (c) 2017-2018 Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fisikopoulos, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@@ -12,15 +12,15 @@
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_ENVELOPE_SEGMENT_HPP
#include <boost/geometry/algorithms/detail/envelope/segment.hpp>
#include <boost/geometry/algorithms/detail/normalize.hpp>
#include <boost/geometry/srs/spheroid.hpp>
#include <boost/geometry/strategies/cartesian/envelope_segment.hpp>
#include <boost/geometry/strategies/envelope.hpp>
#include <boost/geometry/strategies/geographic/azimuth.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/normalize.hpp>
#include <boost/geometry/strategies/spherical/envelope_segment.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
namespace boost { namespace geometry
{
@@ -47,11 +47,18 @@ public:
: m_spheroid(spheroid)
{}
template <typename Point1, typename Point2, typename Box>
inline void apply(Point1 const& point1, Point2 const& point2, Box& box) const
typedef strategy::expand::spherical_box box_expand_strategy_type;
static inline box_expand_strategy_type get_box_expand_strategy()
{
Point1 p1_normalized = detail::return_normalized<Point1>(point1);
Point2 p2_normalized = detail::return_normalized<Point2>(point2);
return box_expand_strategy_type();
}
template <typename Point, typename Box>
inline void apply(Point const& point1, Point const& point2, Box& box) const
{
Point p1_normalized, p2_normalized;
strategy::normalize::spherical_point::apply(point1, p1_normalized);
strategy::normalize::spherical_point::apply(point2, p2_normalized);
geometry::strategy::azimuth::geographic
<
@@ -60,9 +67,13 @@ public:
CalculationType
> azimuth_geographic(m_spheroid);
typedef typename coordinate_system<Point1>::type::units units_type;
typedef typename geometry::detail::cs_angular_units
<
Point
>::type units_type;
detail::envelope::envelope_segment_impl
// first compute the envelope range for the first two coordinates
strategy::envelope::detail::envelope_segment_impl
<
geographic_tag
>::template apply<units_type>(geometry::get<0>(p1_normalized),
@@ -72,6 +83,12 @@ public:
box,
azimuth_geographic);
// now compute the envelope range for coordinates of
// dimension 2 and higher
strategy::envelope::detail::envelope_one_segment
<
2, dimension<Point>::value
>::apply(point1, point2, box);
}
private:
@@ -84,7 +101,7 @@ namespace services
{
template <typename CalculationType>
struct default_strategy<geographic_tag, CalculationType>
struct default_strategy<segment_tag, geographic_tag, CalculationType>
{
typedef strategy::envelope::geographic_segment
<

View File

@@ -0,0 +1,102 @@
// 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.
// Copyright (c) 2014-2015 Samuel Debionne, Grenoble, France.
// This file was modified by Oracle on 2015, 2016, 2017, 2018.
// Modifications copyright (c) 2015-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
#define BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP
#include <cstddef>
#include <functional>
#include <boost/geometry/core/access.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/srs/spheroid.hpp>
#include <boost/geometry/strategies/expand.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/spherical/expand_segment.hpp>
namespace boost { namespace geometry
{
namespace strategy { namespace expand
{
template
<
typename FormulaPolicy = strategy::andoyer,
typename Spheroid = geometry::srs::spheroid<double>,
typename CalculationType = void
>
class geographic_segment
{
public:
inline geographic_segment()
: m_envelope_strategy()
{}
explicit inline geographic_segment(Spheroid const& spheroid)
: m_envelope_strategy(spheroid)
{}
template <typename Box, typename Segment>
inline void apply(Box& box, Segment const& segment) const
{
detail::segment_on_spheroid::apply(box, segment, m_envelope_strategy);
}
private:
strategy::envelope::geographic_segment
<
FormulaPolicy, Spheroid, CalculationType
> m_envelope_strategy;
};
#ifndef DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
namespace services
{
template <typename CalculationType>
struct default_strategy<segment_tag, geographic_tag, CalculationType>
{
typedef geographic_segment
<
strategy::andoyer,
geometry::srs::spheroid<double>,
CalculationType
> type;
};
} // namespace services
#endif // DOXYGEN_NO_STRATEGY_SPECIALIZATIONS
}} // namespace strategy::expand
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_STRATEGIES_GEOGRAPHIC_EXPAND_SEGMENT_HPP

View File

@@ -38,10 +38,13 @@
#include <boost/geometry/strategies/geographic/area.hpp>
#include <boost/geometry/strategies/geographic/distance.hpp>
#include <boost/geometry/strategies/geographic/envelope_segment.hpp>
#include <boost/geometry/strategies/geographic/envelope.hpp>
#include <boost/geometry/strategies/geographic/parameters.hpp>
#include <boost/geometry/strategies/geographic/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/geographic/side.hpp>
#include <boost/geometry/strategies/spherical/expand_box.hpp>
#include <boost/geometry/strategies/spherical/disjoint_box_box.hpp>
#include <boost/geometry/strategies/spherical/point_in_point.hpp>
#include <boost/geometry/strategies/intersection.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
#include <boost/geometry/strategies/side_info.hpp>
@@ -141,7 +144,7 @@ struct geographic_segments
return strategy_type(m_spheroid);
}
typedef envelope::geographic_segment<FormulaPolicy, Spheroid, CalculationType>
typedef envelope::geographic<FormulaPolicy, Spheroid, CalculationType>
envelope_strategy_type;
inline envelope_strategy_type get_envelope_strategy() const
@@ -149,6 +152,38 @@ struct geographic_segments
return envelope_strategy_type(m_spheroid);
}
typedef expand::geographic_segment<FormulaPolicy, Spheroid, CalculationType>
expand_strategy_type;
inline expand_strategy_type get_expand_strategy() const
{
return expand_strategy_type(m_spheroid);
}
typedef within::spherical_point_point point_in_point_strategy_type;
static inline point_in_point_strategy_type get_point_in_point_strategy()
{
return point_in_point_strategy_type();
}
typedef within::spherical_point_point equals_point_point_strategy_type;
static inline equals_point_point_strategy_type get_equals_point_point_strategy()
{
return equals_point_point_strategy_type();
}
typedef disjoint::spherical_box_box disjoint_box_box_strategy_type;
static inline disjoint_box_box_strategy_type get_disjoint_box_box_strategy()
{
return disjoint_box_box_strategy_type();
}
typedef covered_by::spherical_point_box disjoint_point_box_strategy_type;
typedef expand::spherical_box expand_box_strategy_type;
enum intersection_point_flag { ipi_inters = 0, ipi_at_a1, ipi_at_a2, ipi_at_b1, ipi_at_b2 };
template <typename CoordinateType, typename SegmentRatio>
@@ -285,7 +320,6 @@ private:
spheroid_type spheroid = formula::unit_spheroid<spheroid_type>(m_spheroid);
// TODO: check only 2 first coordinates here?
using geometry::detail::equals::equals_point_point;
bool a_is_point = equals_point_point(a1, a2);
bool b_is_point = equals_point_point(b1, b2);
@@ -688,7 +722,6 @@ private:
dist_b1_b2 = res_b1_b2.distance;
// assign the IP if some endpoints overlap
using geometry::detail::equals::equals_point_point;
if (equals_point_point(a1, b1))
{
lon = a1_lon;
@@ -888,7 +921,6 @@ private:
P1 const& ai, P2 const& b1)
{
static CalcT const c0 = 0;
using geometry::detail::equals::equals_point_point;
return is_near(dist) && (math::equals(dist, c0) || equals_point_point(ai, b1));
}
@@ -948,6 +980,13 @@ private:
ip_flag;
}
template <typename Point1, typename Point2>
static inline bool equals_point_point(Point1 const& point1, Point2 const& point2)
{
return detail::equals::equals_point_point(point1, point2,
point_in_point_strategy_type());
}
private:
Spheroid m_spheroid;
};

Some files were not shown because too many files have changed in this diff Show More