Merge branch 'develop' of https://github.com/boostorg/geometry into develop

This commit is contained in:
Barend Gehrels 2019-01-23 21:58:57 +01:00
commit 809d33bb5a
268 changed files with 6447 additions and 3651 deletions

View File

@ -1,10 +1,10 @@
[/============================================================================
Boost.Geometry (aka GGL, Generic Geometry Library)
Copyright (c) 2009-2018 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2018 Mateusz Loskot, London, UK.
Copyright (c) 2009-2018 Bruno Lalande, Paris, France.
Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
Copyright (c) 2009-2019 Barend Gehrels, Amsterdam, the Netherlands.
Copyright (c) 2009-2019 Mateusz Loskot, London, UK.
Copyright (c) 2009-2019 Bruno Lalande, Paris, France.
Copyright (c) 2011-2019 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
@ -14,7 +14,7 @@
[library Geometry
[quickbook 1.5]
[authors [Gehrels, Barend], [Lalande, Bruno], [Loskot, Mateusz], [Wulkiewicz, Adam], [Karavelas, Menelaos], [Fisikopoulos, Vissarion]]
[copyright 2009-2018 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates]
[copyright 2009-2019 Barend Gehrels, Bruno Lalande, Mateusz Loskot, Adam Wulkiewicz, Oracle and/or its affiliates]
[purpose Documentation of Boost.Geometry library]
[license
Distributed under the Boost Software License, Version 1.0.

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

@ -15,6 +15,7 @@
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>

View File

@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 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
// Use, modification and distribution is subject to the Boost Software License,
@ -26,6 +26,7 @@
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
#include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/strategies/buffer.hpp>

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,
@ -635,6 +635,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
<
@ -642,8 +651,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();
@ -906,12 +915,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,
@ -319,7 +319,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,
@ -16,6 +16,7 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/detail/buffer/buffer_policies.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/strategies/agnostic/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/buffer.hpp>
@ -38,12 +39,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 +59,7 @@ struct include_turn_policy
}
};
template <typename DisjointPointBoxStrategy>
struct turn_in_original_ovelaps_box
{
template <typename Box, typename Turn>
@ -68,7 +72,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,
@ -58,6 +58,7 @@ struct piece_get_box
}
};
template <typename DisjointBoxBoxStrategy>
struct piece_ovelaps_box
{
template <typename Box, typename Piece>
@ -73,7 +74,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());
}
};
@ -86,12 +88,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, 2019.
// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -36,7 +36,7 @@ struct use_point_in_geometry
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return detail::within::point_in_geometry(geometry1, geometry2, strategy) >= 0;
return detail::within::covered_by_point_geometry(geometry1, geometry2, strategy);
}
};

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

@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2018.
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -41,8 +41,9 @@
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_linear.hpp>
#include <boost/geometry/algorithms/detail/disjoint/linear_segment_or_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/multirange_geometry.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>

View File

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

@ -5,10 +5,11 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// 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, 2019.
// Modifications copyright (c) 2014-2019, 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.
@ -39,13 +40,12 @@
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/assign.hpp>
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/within.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/geometry_to_range.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/distance/iterator_selector.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
@ -160,7 +160,8 @@ struct point_to_ring
Ring const& ring,
Strategy const& strategy)
{
if (geometry::within(point, ring))
// TODO: pass strategy
if (within::within_point_geometry(point, ring))
{
return return_type(0);
}
@ -204,7 +205,8 @@ private:
{
for (InteriorRingIterator it = first; it != last; ++it)
{
if (geometry::within(point, *it))
// TODO: pass strategy
if (within::within_point_geometry(point, *it))
{
// the point is inside a polygon hole, so its distance
// to the polygon its distance to the polygon's
@ -233,7 +235,8 @@ public:
Polygon const& polygon,
Strategy const& strategy)
{
if (!geometry::covered_by(point, exterior_ring(polygon)))
// TODO: pass strategy
if (! within::covered_by_point_geometry(point, exterior_ring(polygon)))
{
// the point is outside the exterior ring, so its distance
// to the polygon is its distance to the polygon's exterior ring
@ -330,7 +333,8 @@ struct point_to_multigeometry<Point, MultiPolygon, Strategy, true>
MultiPolygon const& multipolygon,
Strategy const& strategy)
{
if (geometry::covered_by(point, multipolygon))
// TODO: pass strategy
if (within::covered_by_point_geometry(point, multipolygon))
{
return 0;
}

View File

@ -1,15 +1,17 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2018 Oracle and/or its affiliates.
// Copyright (c) 2014-2019 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
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_DISTANCE_SEGMENT_TO_BOX_HPP
#include <cstddef>
#include <functional>
@ -27,25 +29,26 @@
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/closest_feature/point_to_range.hpp>
#include <boost/geometry/algorithms/detail/disjoint/segment_box.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/intersects.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/util/calculation_type.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/assign_indexed_point.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/detail/distance/is_comparable.hpp>
#include <boost/geometry/algorithms/dispatch/distance.hpp>
#include <boost/geometry/strategies/disjoint.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/tags.hpp>
namespace boost { namespace geometry
@ -57,6 +60,20 @@ namespace detail { namespace distance
{
// TODO: Take strategy
template <typename Segment, typename Box>
inline bool intersects_segment_box(Segment const& segment, Box const& box)
{
typedef typename strategy::disjoint::services::default_strategy
<
Segment, Box
>::type strategy_type;
return ! detail::disjoint::disjoint_segment_box::apply(segment, box,
strategy_type());
}
template
<
typename Segment,
@ -99,7 +116,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
if (check_intersection && geometry::intersects(segment, box))
if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
@ -214,7 +231,7 @@ public:
Strategy const& strategy,
bool check_intersection = true)
{
if (check_intersection && geometry::intersects(segment, box))
if (check_intersection && intersects_segment_box(segment, box))
{
return 0;
}
@ -753,7 +770,8 @@ public:
detail::assign_point_from_index<0>(segment, p[0]);
detail::assign_point_from_index<1>(segment, p[1]);
if (geometry::equals(p[0], p[1]))
if (detail::equals::equals_point_point(p[0], p[1],
sb_strategy.get_equals_point_point_strategy()))
{
typedef typename boost::mpl::if_
<

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

@ -20,17 +20,20 @@
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#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/util/math.hpp>
#include <boost/geometry/util/normalize_spheroidal_coordinates.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/algorithms/detail/convert_point_to_point.hpp>
#include <boost/geometry/algorithms/detail/max_interval_gap.hpp>
#include <boost/geometry/algorithms/detail/expand/indexed.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
namespace boost { namespace geometry
@ -151,10 +154,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 +199,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 +226,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 +325,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

@ -5,8 +5,8 @@
// Copyright (c) 2009-2013 Mateusz Loskot, London, UK.
// Copyright (c) 2013-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
@ -25,6 +25,7 @@
#include <boost/geometry/algorithms/detail/interior_iterator.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>

View File

@ -2,8 +2,8 @@
// Copyright (c) 2012-2014 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
@ -14,11 +14,14 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_LEFT_TURNS_HPP
#include <set>
#include <vector>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/iterators/closing_iterator.hpp>
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/strategies/side.hpp>

View File

@ -5,6 +5,11 @@
// Copyright (c) 2014 Mateusz Loskot, London, UK.
// Copyright (c) 2014 Adam Wulkiewicz, Lodz, Poland.
// 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)
@ -12,10 +17,10 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_MAX_SIZE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_GET_MAX_SIZE_HPP
#include <cstddef>
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/util/math.hpp>
namespace boost { namespace geometry

View File

@ -1,8 +1,9 @@
// 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@ -19,6 +20,7 @@
#include <boost/core/addressof.hpp>
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/compare.hpp>
@ -221,9 +223,11 @@ public:
return false;
}
#ifdef BOOST_GEOMETRY_TEST_DEBUG
template <typename OStream, typename TP>
friend inline
void debug_print_complement_graph(OStream&, complement_graph<TP> const&);
#endif // BOOST_GEOMETRY_TEST_DEBUG
private:
std::size_t m_num_rings, m_num_turns;

View File

@ -1,8 +1,9 @@
// 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@ -14,6 +15,8 @@
#include <iostream>
#endif
#include <boost/geometry/algorithms/detail/is_valid/complement_graph.hpp>
namespace boost { namespace geometry
{

View File

@ -1,8 +1,9 @@
// 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 Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Licensed under the Boost Software License version 1.0.
// http://www.boost.org/users/license.html
@ -12,11 +13,10 @@
#ifdef GEOMETRY_TEST_DEBUG
#include <iostream>
#endif
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#endif
namespace boost { namespace geometry
{

View File

@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, 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
@ -15,15 +15,17 @@
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/core/coordinate_type.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/util/has_non_finite_coordinate.hpp>
#include <boost/geometry/iterators/point_iterator.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/algorithms/detail/check_iterator_range.hpp>
#include <boost/geometry/views/detail/indexed_point_view.hpp>
#include <boost/geometry/util/has_non_finite_coordinate.hpp>
namespace boost { namespace geometry
{

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
@ -16,6 +16,12 @@
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
#include <boost/geometry/algorithms/validity_failure_type.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/point_type.hpp>
@ -23,12 +29,6 @@
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/self_turn_points.hpp>
#include <boost/geometry/algorithms/detail/is_valid/is_acceptable_turn.hpp>
namespace boost { namespace geometry
{

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

@ -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
@ -20,6 +20,7 @@
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/core/cs.hpp>
#include <boost/geometry/core/point_order.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/order_as_direction.hpp>
#include <boost/geometry/util/range.hpp>
@ -36,6 +37,7 @@
#include <boost/geometry/algorithms/detail/is_valid/has_invalid_coordinate.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_spikes.hpp>
#include <boost/geometry/algorithms/detail/is_valid/has_valid_self_turns.hpp>
#include <boost/geometry/algorithms/dispatch/is_valid.hpp>
#include <boost/geometry/strategies/area.hpp>

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,11 +15,14 @@
#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>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/core/closure.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
@ -33,12 +36,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 +63,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 +87,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 +126,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,
@ -135,12 +135,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());
}
};
@ -328,11 +330,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,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)
@ -9,11 +14,18 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CHECK_ENRICH_HPP
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
#include <iostream>
#endif // BOOST_GEOMETRY_DEBUG_ENRICH
#include <cstddef>
#include <vector>
#include <boost/range.hpp>
#include <boost/range/begin.hpp>
#include <boost/range/end.hpp>
#include <boost/range/value_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
@ -42,7 +54,7 @@ struct meta_turn
template <typename MetaTurn>
inline void display(MetaTurn const& meta_turn, std::string const& reason = "")
inline void display(MetaTurn const& meta_turn, const char* reason = "")
{
#ifdef BOOST_GEOMETRY_DEBUG_ENRICH
std::cout << meta_turn.index

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,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)
@ -9,18 +14,16 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_CONVERT_RING_HPP
#include <boost/mpl/assert.hpp>
#include <boost/range.hpp>
#include <boost/range/algorithm/reverse.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/algorithms/detail/ring_identifier.hpp>
#include <boost/geometry/algorithms/convert.hpp>
namespace boost { namespace geometry
{

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
@ -23,23 +23,27 @@
#include <boost/range.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/geometry/algorithms/detail/assign_box_corners.hpp>
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/ring_type.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
#include <boost/geometry/algorithms/detail/overlay/append_no_duplicates.hpp>
#include <boost/geometry/algorithms/detail/overlay/append_no_dups_or_spikes.hpp>
#include <boost/geometry/algorithms/detail/signed_size_type.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
#include <boost/geometry/iterators/ever_circling_iterator.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/views/closeable_view.hpp>
#include <boost/geometry/views/reversible_view.hpp>
namespace boost { namespace geometry
{
@ -137,11 +141,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

@ -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 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
@ -21,6 +21,7 @@
#include <boost/geometry/core/access.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exception.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>

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
@ -15,8 +15,10 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_FOR_ENDPOINT_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
namespace boost { namespace geometry {
@ -109,11 +111,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 +136,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 +236,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 +267,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

@ -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
@ -14,9 +14,16 @@
#ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_GET_TURN_INFO_HELPERS_HPP
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/algorithms/detail/direction_code.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/recalculate.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/geometries/segment.hpp> // referring_segment
#include <boost/geometry/policies/relate/direction.hpp>
#include <boost/geometry/policies/relate/intersection_points.hpp>
#include <boost/geometry/policies/relate/tupled.hpp>
#include <boost/geometry/policies/robustness/no_rescale_policy.hpp>
#include <boost/geometry/strategies/intersection_result.hpp>
namespace boost { namespace geometry {

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;
}
@ -324,6 +336,8 @@ inline void self_turns(Geometry const& geometry,
\param turns container which will contain intersection points
\param interrupt_policy policy determining if process is stopped
when intersection is found
\param source_index source index for generated turns
\param skip_adjacent indicates if adjacent turns should be skipped
*/
template
<

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)
@ -12,7 +17,7 @@
#include <string>
#include <boost/array.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
namespace boost { namespace geometry
@ -32,8 +37,8 @@ namespace detail { namespace overlay
return h == 0 ? "-" : (h == 1 ? "A" : "D");
}
template <typename P>
std::ostream& operator<<(std::ostream &os, turn_info<P> const& info)
template <typename P, typename SR, typename O, typename C>
std::ostream& operator<<(std::ostream &os, turn_info<P, SR, O, C> const& info)
{
os << "\t"
<< " src " << info.seg_id.source_index
@ -46,10 +51,10 @@ namespace detail { namespace overlay
<< (info.opposite ? " o" : "")
<< "]"
<< " sd "
<< dir(info.sides.get<0,0>())
<< dir(info.sides.get<0,1>())
<< dir(info.sides.get<1,0>())
<< dir(info.sides.get<1,1>())
<< dir(info.sides.template get<0,0>())
<< dir(info.sides.template get<0,1>())
<< dir(info.sides.template get<1,0>())
<< dir(info.sides.template get<1,1>())
<< " nxt seg " << info.travels_to_vertex_index
<< " , ip " << info.travels_to_ip_index
<< " , or " << info.next_ip_index

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 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
@ -15,9 +15,11 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_HPP
#include <cstddef>
#include <set>
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/overlay/cluster_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/is_self_turn.hpp>
#include <boost/geometry/algorithms/detail/overlay/sort_by_side.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2012 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
// Use, modification and distribution is subject to the Boost Software License,
@ -17,6 +17,7 @@
#include <boost/range.hpp>
#include <boost/geometry/algorithms/detail/overlay/backtrack_check_si.hpp>
#include <boost/geometry/algorithms/detail/overlay/copy_segments.hpp>
#include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
#include <boost/geometry/algorithms/detail/overlay/traversal.hpp>

View File

@ -2,6 +2,11 @@
// Copyright (c) 2015-2016 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,6 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_TRAVERSAL_SWITCH_DETECTOR_HPP
#include <cstddef>
#include <map>
#include <boost/range.hpp>

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,24 +1,26 @@
// 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>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/sub_range.hpp>
#include <boost/geometry/algorithms/num_points.hpp>
#include <boost/geometry/policies/compare.hpp>
#include <boost/geometry/util/has_nan_coordinate.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
{
@ -29,19 +31,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 +60,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 +124,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,25 +2,33 @@
// 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.
// 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_FOLLOW_HELPERS_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_RELATE_FOLLOW_HELPERS_HPP
#include <vector>
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/detail/overlay/get_turn_info_helpers.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/segment_identifier.hpp>
#include <boost/geometry/algorithms/detail/relate/boundary_checker.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/util/condition.hpp>
#include <boost/geometry/util/range.hpp>
//#include <boost/geometry/algorithms/detail/sub_range.hpp>
namespace boost { namespace geometry
{
@ -333,8 +341,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 +363,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
@ -17,6 +17,7 @@
#include <boost/geometry/algorithms/detail/disjoint/box_box.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_box.hpp>
#include <boost/geometry/algorithms/detail/expand_by_epsilon.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/relate/result.hpp>
#include <boost/geometry/algorithms/detail/relate/topology_check.hpp>
#include <boost/geometry/algorithms/detail/within/point_in_geometry.hpp>
@ -40,20 +41,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 +75,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 +101,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 +109,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 +126,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 +143,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 +170,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 +188,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 +216,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 +236,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 +275,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 +321,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 +358,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 +374,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 +423,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 +501,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 +515,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 +554,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

@ -3,8 +3,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2016.
// Modifications copyright (c) 2013-2016 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
@ -25,6 +25,7 @@
#include <boost/mpl/end.hpp>
#include <boost/mpl/is_sequence.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/size.hpp>
#include <boost/static_assert.hpp>
#include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp>

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
@ -13,6 +13,7 @@
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/policies/compare.hpp>
@ -28,6 +29,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 +49,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 +102,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 +116,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 +163,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 +199,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 +222,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 +232,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 +268,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 +305,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
@ -22,6 +22,8 @@
// For spherical/geographic longitudes covered_by point/box
#include <boost/geometry/strategies/cartesian/point_in_box.hpp>
#include <boost/geometry/util/select_coordinate_type.hpp>
namespace boost { namespace geometry
{
@ -30,6 +32,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 +72,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);
}
}
};
@ -903,6 +928,8 @@ struct sectionalize<multi_linestring_tag, MultiLinestring, Reverse, DimensionVec
\param geometry geometry to create sections from
\param robust_policy policy to handle robustness issues
\param sections structure with sections
\param envelope_strategy strategy for envelope calculation
\param expand_strategy strategy for partitions
\param source_index index to assign to the ring_identifiers
\param max_count maximal number of points per section
(defaults to 10, this seems to give the fastest results)
@ -915,12 +942,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 +988,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 +1012,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

@ -2,21 +2,29 @@
// 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.
// 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_SUB_RANGE_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_SUB_RANGE_HPP
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/exterior_ring.hpp>
#include <boost/geometry/core/interior_rings.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace 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 2013, 2014, 2017.
// Modifications copyright (c) 2013-2017 Oracle and/or its affiliates.
// This file was modified by Oracle on 2013, 2014, 2017, 2019.
// Modifications copyright (c) 2013-2019 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -61,7 +61,7 @@ struct use_point_in_geometry
template <typename Geometry1, typename Geometry2, typename Strategy>
static inline bool apply(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
{
return detail::within::point_in_geometry(geometry1, geometry2, strategy) == 1;
return detail::within::within_point_geometry(geometry1, geometry2, strategy);
}
};

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, 2019.
// Modifications copyright (c) 2013-2019, 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);
}
@ -383,6 +382,30 @@ inline int point_in_geometry(Point const& point, Geometry const& geometry)
return point_in_geometry(point, geometry, strategy_type());
}
template <typename Point, typename Geometry, typename Strategy>
inline bool within_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
return point_in_geometry(point, geometry, strategy) > 0;
}
template <typename Point, typename Geometry>
inline bool within_point_geometry(Point const& point, Geometry const& geometry)
{
return point_in_geometry(point, geometry) > 0;
}
template <typename Point, typename Geometry, typename Strategy>
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry, Strategy const& strategy)
{
return point_in_geometry(point, geometry, strategy) >= 0;
}
template <typename Point, typename Geometry>
inline bool covered_by_point_geometry(Point const& point, Geometry const& geometry)
{
return point_in_geometry(point, geometry) >= 0;
}
}} // namespace detail::within
#endif // DOXYGEN_NO_DETAIL

View File

@ -1,8 +1,12 @@
// Boost.Geometry
// Copyright (c) 2018 Yaghyavardhan Singh Khangarot, Hyderabad, India.
// Contributed and/or modified by Yaghyavardhan Singh Khangarot,
// as part of Google Summer of Code 2018 program.
// Contributed and/or modified by Yaghyavardhan Singh Khangarot, as part of Google Summer of Code 2018 program.
// 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
@ -22,13 +26,15 @@
#include <vector>
#include <limits>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/range.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/assert.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/distance_result.hpp>
#include <boost/geometry/util/range.hpp>
namespace boost { namespace geometry
@ -48,7 +54,7 @@ public:
result_type & operator()(size_type1 i, size_type2 j)
{
BOOST_ASSERT(i < m_width && j < m_height);
BOOST_GEOMETRY_ASSERT(i < m_width && j < m_height);
return m_data[j * m_width + i];
}
@ -86,28 +92,31 @@ struct linestring_linestring
//Coupling Matrix CoupMat(a,b,-1);
coup_mat<size_type1,size_type2,result_type> coup_matrix(a,b);
coup_mat<size_type1,size_type2,result_type> coup_matrix(a,b);
result_type const not_feasible = -100;
//findin the Coupling Measure
for(size_type1 i=0;i<a;i++)
for (size_type1 i = 0 ; i < a ; i++ )
{
for(size_type2 j=0;j<b;j++)
{
result_type dis = geometry::distance(range::at(ls1,i),range::at(ls2,j),strategy);
result_type dis = strategy.apply(range::at(ls1,i), range::at(ls2,j));
if(i==0 && j==0)
coup_matrix(i,j)= dis;
coup_matrix(i,j) = dis;
else if(i==0 && j>0)
coup_matrix(i,j)=
(std::max)(coup_matrix(i,j-1),dis);
coup_matrix(i,j) =
(std::max)(coup_matrix(i,j-1), dis);
else if(i>0 && j==0)
coup_matrix(i,j)=
(std::max)(coup_matrix(i-1,j),dis);
coup_matrix(i,j) =
(std::max)(coup_matrix(i-1,j), dis);
else if(i>0 && j>0)
coup_matrix(i,j)=
(std::max)((std::min)(coup_matrix(i,j-1),(std::min)(coup_matrix(i-1,j),coup_matrix(i-1,j-1))),dis);
coup_matrix(i,j) =
(std::max)((std::min)(coup_matrix(i,j-1),
(std::min)(coup_matrix(i-1,j),
coup_matrix(i-1,j-1))),
dis);
else
coup_matrix(i,j)=not_feasible;
coup_matrix(i,j) = not_feasible;
}
}
@ -140,8 +149,15 @@ template
>
struct discrete_frechet_distance : not_implemented<Tag1, Tag2>
{};
template <typename Linestring1, typename Linestring2>
struct discrete_frechet_distance<Linestring1,Linestring2,linestring_tag,linestring_tag>
struct discrete_frechet_distance
<
Linestring1,
Linestring2,
linestring_tag,
linestring_tag
>
: detail::discrete_frechet_distance::linestring_linestring
{};
@ -151,7 +167,7 @@ struct discrete_frechet_distance<Linestring1,Linestring2,linestring_tag,linestri
/*!
\brief Calculate discrete Frechet distance between two geometries (currently
works for LineString-LineString) using specified strategy.
works for LineString-LineString) using specified strategy.
\ingroup discrete_frechet_distance
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry
@ -181,16 +197,21 @@ inline typename distance_result
typename point_type<Geometry2>::type,
Strategy
>::type
discrete_frechet_distance(Geometry1 const& geometry1, Geometry2 const& geometry2, Strategy const& strategy)
discrete_frechet_distance(Geometry1 const& geometry1,
Geometry2 const& geometry2,
Strategy const& strategy)
{
return dispatch::discrete_frechet_distance<Geometry1, Geometry2>::apply(geometry1, geometry2, strategy);
return dispatch::discrete_frechet_distance
<
Geometry1, Geometry2
>::apply(geometry1, geometry2, strategy);
}
// Algorithm overload using default Pt-Pt distance strategy
/*!
\brief Calculate discrete Frechet distance between two geometries (currently
work for LineString-LineString).
work for LineString-LineString).
\ingroup discrete_frechet_distance
\tparam Geometry1 \tparam_geometry
\tparam Geometry2 \tparam_geometry

View File

@ -26,16 +26,18 @@
#include <vector>
#include <limits>
#include <boost/geometry/geometry.hpp>
#include <boost/geometry/geometries/linestring.hpp>
#include <boost/geometry/geometries/point_xy.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/range.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/core/point_type.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/index/rtree.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/strategies/distance_result.hpp>
#include <boost/geometry/util/range.hpp>
namespace bgi = boost::geometry::index;
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
#include <boost/geometry/index/rtree.hpp>
#endif // BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
namespace boost { namespace geometry
{
@ -70,7 +72,7 @@ struct point_range
for (size_type i = 0 ; i < n ; i++)
{
result_type dis_temp = geometry::distance(pnt, range::at(rng, i), strategy);
result_type dis_temp = strategy.apply(pnt, range::at(rng, i));
if (! is_dis_min_set || dis_temp < dis_min)
{
dis_min = dis_temp;
@ -110,6 +112,7 @@ struct range_range
result_type dis_max = 0;
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
namespace bgi = boost::geometry::index;
typedef typename point_type<Range1>::type point_t;
typedef bgi::rtree<point_t, bgi::linear<4> > rtree_type;
rtree_type rtree(boost::begin(r2), boost::end(r2));
@ -120,7 +123,7 @@ struct range_range
{
#ifdef BOOST_GEOMETRY_ENABLE_SIMILARITY_RTREE
size_type found = rtree.query(bgi::nearest(range::at(r1, i), 1), &res);
result_type dis_min = geometry::distance(range::at(r1,i), res);
result_type dis_min = strategy.apply(range::at(r1,i), res);
#else
result_type dis_min = point_range::apply(range::at(r1, i), r2, strategy);
#endif
@ -246,15 +249,15 @@ struct discrete_hausdorff_distance<MultiPoint1, MultiPoint2, multi_point_tag, mu
: detail::discrete_hausdorff_distance::range_range
{};
// Specialization for linestring and multi_linestring
template <typename linestring, typename multi_linestring>
struct discrete_hausdorff_distance<linestring, multi_linestring, linestring_tag, multi_linestring_tag>
// Specialization for Linestring and MultiLinestring
template <typename Linestring, typename MultiLinestring>
struct discrete_hausdorff_distance<Linestring, MultiLinestring, linestring_tag, multi_linestring_tag>
: detail::discrete_hausdorff_distance::range_multi_range
{};
// Specialization for multi_linestring and multi_linestring
template <typename multi_linestring1, typename multi_linestring2>
struct discrete_hausdorff_distance<multi_linestring1, multi_linestring2, multi_linestring_tag, multi_linestring_tag>
// Specialization for MultiLinestring and MultiLinestring
template <typename MultiLinestring1, typename MultiLinestring2>
struct discrete_hausdorff_distance<MultiLinestring1, MultiLinestring2, multi_linestring_tag, multi_linestring_tag>
: detail::discrete_hausdorff_distance::multi_range_multi_range
{};

View File

@ -5,8 +5,8 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// This file was modified by Oracle on 2013-2017.
// Modifications copyright (c) 2013-2017, Oracle and/or its affiliates.
// This file was modified by Oracle on 2013-2018.
// Modifications copyright (c) 2013-2018, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
@ -23,6 +23,7 @@
#include <cstddef>
#include <boost/geometry/core/coordinate_dimension.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>

View File

@ -5,10 +5,11 @@
// Copyright (c) 2009-2014 Mateusz Loskot, London, UK.
// Copyright (c) 2013-2014 Adam Wulkiewicz, Lodz, Poland.
// 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.
@ -25,8 +26,9 @@
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tag_cast.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/strategies/distance.hpp>
#include <boost/geometry/algorithms/detail/distance/default_strategies.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/strategies/distance.hpp>
namespace boost { namespace geometry

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.
@ -15,6 +20,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_SIMPLIFY_HPP
#include <cstddef>
#include <set>
#include <boost/core/ignore_unused.hpp>
#include <boost/range.hpp>
@ -53,12 +59,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 +74,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 +117,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 +139,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

@ -2,6 +2,10 @@
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// 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)
@ -12,7 +16,14 @@
// TODO - for multiplication of coordinates
// if coordinate_type is_integral - use double as the result type
#include <boost/geometry/extensions/algebra/core/access.hpp>
#include <boost/geometry/extensions/algebra/core/coordinate_type.hpp>
#include <boost/geometry/extensions/algebra/core/coordinate_dimension.hpp>
#include <boost/geometry/util/math.hpp>
#include <boost/geometry/util/select_most_precise.hpp>
#include <boost/static_assert.hpp>
namespace boost { namespace geometry
{
@ -37,8 +48,8 @@ struct dot_impl
BOOST_STATIC_ASSERT(0 < N);
typedef typename geometry::select_most_precise<
typename traits::coordinate_type<S1>::type,
typename traits::coordinate_type<S2>::type
typename geometry::coordinate_type<S1>::type,
typename geometry::coordinate_type<S2>::type
>::type coordinate_type;
static inline coordinate_type apply(S1 const& s1, S2 const& s2)
@ -51,8 +62,8 @@ template <typename S1, typename S2, std::size_t IS1, std::size_t IS2>
struct dot_impl<S1, S2, IS1, IS2, 1>
{
typedef typename geometry::select_most_precise<
typename traits::coordinate_type<S1>::type,
typename traits::coordinate_type<S2>::type
typename geometry::coordinate_type<S1>::type,
typename geometry::coordinate_type<S2>::type
>::type coordinate_type;
static inline coordinate_type apply(S1 const& s1, S2 const& s2)
@ -64,8 +75,8 @@ struct dot_impl<S1, S2, IS1, IS2, 1>
template <std::size_t IS1, std::size_t IS2, std::size_t N, typename S1, typename S2>
inline static
typename geometry::select_most_precise<
typename traits::coordinate_type<S1>::type,
typename traits::coordinate_type<S2>::type
typename geometry::coordinate_type<S1>::type,
typename geometry::coordinate_type<S2>::type
>::type
dot(S1 const& s1, S2 const& s2)
{
@ -143,7 +154,7 @@ struct matrix_mul_row_impl
{
BOOST_STATIC_ASSERT(0 < N);
static const std::size_t dimension = traits::dimension<M>::value;
static const std::size_t dimension = geometry::dimension<M>::value;
static inline
typename traits::coordinate_type<VD>::type
@ -156,7 +167,7 @@ struct matrix_mul_row_impl
template <typename M, typename V, typename VD, std::size_t I>
struct matrix_mul_row_impl<M, V, VD, I, 1>
{
static const std::size_t dimension = traits::dimension<M>::value;
static const std::size_t dimension = geometry::dimension<M>::value;
static inline
typename traits::coordinate_type<VD>::type
@ -187,7 +198,7 @@ struct matrix_mul_impl<M, V, VD, N, N>
template <typename M, typename V, typename VD>
inline static void matrix_rotate(M const& m, V const& v, VD & vd)
{
static const std::size_t dimension = traits::dimension<M>::value;
static const std::size_t dimension = geometry::dimension<M>::value;
matrix_mul_impl<M, V, VD, 0, dimension>::apply(m, v, vd);
}
@ -200,8 +211,8 @@ inline static void quaternion_rotate(V & v, Q const& r)
// TODO - choose more precise type?
typedef typename geometry::select_most_precise<
typename traits::coordinate_type<V>::type,
typename traits::coordinate_type<Q>::type
typename geometry::coordinate_type<V>::type,
typename geometry::coordinate_type<Q>::type
>::type T;
// Hamilton product T=Q*V

View File

@ -2,6 +2,10 @@
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// 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)
@ -14,6 +18,7 @@
#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
#include <boost/geometry/extensions/algebra/geometries/vector.hpp>
// TODO - for multiplication of coordinates
// if coordinate_type is_integral - use double as the result type

View File

@ -2,6 +2,10 @@
// Copyright (c) 2013 Adam Wulkiewicz, Lodz, Poland.
// 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)
@ -9,10 +13,13 @@
#ifndef BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
#define BOOST_GEOMETRY_EXTENSIONS_ALGEBRA_ALGORITHMS_TRANSFORM_HPP
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/extensions/algebra/algorithms/detail.hpp>
#include <boost/geometry/extensions/algebra/geometries/concepts/vector_concept.hpp>
#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_quaternion_concept.hpp>
#include <boost/geometry/extensions/algebra/geometries/concepts/rotation_matrix_concept.hpp>
#include <boost/geometry/arithmetic/arithmetic.hpp>
#include <boost/geometry/geometries/concepts/check.hpp>
namespace boost { namespace geometry {

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