Merge pull request #650 from awulkiew/feature/setops_output

Missing input combinations in intersection() and introduction of tupled-output.
This commit is contained in:
Adam Wulkiewicz 2020-03-26 15:13:01 +01:00 committed by GitHub
commit 201530285a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 3501 additions and 739 deletions

View File

@ -0,0 +1,348 @@
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_INTERSECTION_AREAL_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP
#include <boost/core/ignore_unused.hpp>
#include <boost/geometry/algorithms/detail/intersection/interface.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace intersection
{
template
<
typename GeometryOut,
typename OutTag = typename detail::intersection::tag
<
typename geometry::detail::output_geometry_value
<
GeometryOut
>::type
>::type
>
struct intersection_areal_areal_
{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename Strategy
>
static inline void apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Areal1, Areal2,
typename boost::range_value<GeometryOut>::type,
overlay_intersection
>::apply(areal1, areal2, robust_policy,
geometry::range::back_inserter(geometry_out),
strategy);
}
};
// TODO: Ideally this should be done in one call of intersection_insert
// just like it's done for all other combinations
template <typename TupledOut>
struct intersection_areal_areal_<TupledOut, tupled_output_tag>
{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename Strategy
>
static inline void apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
TupledOut& geometry_out,
Strategy const& strategy)
{
typedef typename geometry::detail::output_geometry_value
<
TupledOut
>::type single_out;
boost::ignore_unused
<
detail::intersection::expect_output_pla
<
Areal1, Areal2, single_out
>
>();
typedef geometry::detail::output_geometry_access
<
single_out, polygon_tag, polygon_tag
> areal;
typedef geometry::detail::output_geometry_access
<
single_out, linestring_tag, linestring_tag
> linear;
typedef geometry::detail::output_geometry_access
<
single_out, point_tag, point_tag
> pointlike;
typedef typename geometry::tuples::element
<
areal::index, TupledOut
>::type areal_out_type;
typedef typename geometry::tuples::element
<
pointlike::index, TupledOut
>::type pointlike_out_type;
// NOTE: The same robust_policy is used in each call of
// intersection_insert. Is that correct?
// A * A -> A
call_intersection(areal1, areal2, robust_policy,
areal::get(geometry_out),
strategy);
bool const is_areal_empty = boost::empty(areal::get(geometry_out));
TupledOut temp_out;
// L * L -> (L, P)
call_intersection(geometry::detail::boundary_view<Areal1 const>(areal1),
geometry::detail::boundary_view<Areal2 const>(areal2),
robust_policy,
! is_areal_empty
? temp_out
: geometry_out,
strategy);
if (! is_areal_empty)
{
// NOTE: the original areal geometry could be used instead of boundary here
// however this results in static assert failure related to rescale policy
typedef geometry::detail::boundary_view
<
areal_out_type const
> areal_out_boundary_type;
areal_out_boundary_type areal_out_boundary(areal::get(geometry_out));
// L - L -> L
call_difference(linear::get(temp_out),
areal_out_boundary,
robust_policy,
linear::get(geometry_out),
strategy);
// P - L -> P
call_difference(pointlike::get(temp_out),
areal_out_boundary,
robust_policy,
pointlike::get(geometry_out),
strategy.template get_point_in_geometry_strategy
<
pointlike_out_type,
areal_out_boundary_type
>());
}
return;
}
private:
template
<
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline void call_intersection(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Geometry1,
Geometry2,
typename geometry::detail::output_geometry_value
<
GeometryOut
>::type,
overlay_intersection
>::apply(geometry1,
geometry2,
robust_policy,
geometry::detail::output_geometry_back_inserter(geometry_out),
strategy);
}
template
<
typename Geometry1,
typename Geometry2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline void call_difference(Geometry1 const& geometry1,
Geometry2 const& geometry2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
geometry::dispatch::intersection_insert
<
Geometry1,
Geometry2,
typename boost::range_value<GeometryOut>::type,
overlay_difference
>::apply(geometry1,
geometry2,
robust_policy,
geometry::range::back_inserter(geometry_out),
strategy);
}
};
struct intersection_areal_areal
{
template
<
typename Areal1,
typename Areal2,
typename RobustPolicy,
typename GeometryOut,
typename Strategy
>
static inline bool apply(Areal1 const& areal1,
Areal2 const& areal2,
RobustPolicy const& robust_policy,
GeometryOut& geometry_out,
Strategy const& strategy)
{
intersection_areal_areal_
<
GeometryOut
>::apply(areal1, areal2, robust_policy, geometry_out, strategy);
return true;
}
};
}} // namespace detail::intersection
#endif // DOXYGEN_NO_DETAIL
#ifndef DOXYGEN_NO_DISPATCH
namespace dispatch
{
template
<
typename Polygon1, typename Polygon2
>
struct intersection
<
Polygon1, Polygon2,
polygon_tag, polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
template
<
typename Polygon, typename Ring
>
struct intersection
<
Polygon, Ring,
polygon_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
template
<
typename Ring1, typename Ring2
>
struct intersection
<
Ring1, Ring2,
ring_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
template
<
typename Polygon, typename MultiPolygon
>
struct intersection
<
Polygon, MultiPolygon,
polygon_tag, multi_polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
template
<
typename MultiPolygon, typename Ring
>
struct intersection
<
MultiPolygon, Ring,
multi_polygon_tag, ring_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
template
<
typename MultiPolygon1, typename MultiPolygon2
>
struct intersection
<
MultiPolygon1, MultiPolygon2,
multi_polygon_tag, multi_polygon_tag,
false
>
: detail::intersection::intersection_areal_areal
{};
} // namespace dispatch
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_AREAL_AREAL_HPP

View File

@ -15,6 +15,7 @@
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_INTERSECTION_IMPLEMENTATION_HPP
#include <boost/geometry/algorithms/detail/intersection/areal_areal.hpp>
#include <boost/geometry/algorithms/detail/intersection/box_box.hpp>
#include <boost/geometry/algorithms/detail/intersection/multi.hpp>

View File

@ -20,6 +20,7 @@
#include <boost/variant/variant_fwd.hpp>
#include <boost/geometry/algorithms/detail/overlay/intersection_insert.hpp>
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
#include <boost/geometry/strategies/default_strategy.hpp>
#include <boost/geometry/util/range.hpp>
@ -50,14 +51,18 @@ struct intersection
GeometryOut& geometry_out,
Strategy const& strategy)
{
typedef typename boost::range_value<GeometryOut>::type OneOut;
typedef typename geometry::detail::output_geometry_value
<
GeometryOut
>::type SingleOut;
intersection_insert
<
Geometry1, Geometry2, OneOut,
Geometry1, Geometry2, SingleOut,
overlay_intersection
>::apply(geometry1, geometry2, robust_policy,
range::back_inserter(geometry_out), strategy);
geometry::detail::output_geometry_back_inserter(geometry_out),
strategy);
return true;
}

View File

@ -2,8 +2,8 @@
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2014.
// Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2020.
// Modifications copyright (c) 2014-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -123,7 +123,8 @@ template
<
bool ReverseAreal,
typename LineStringOut,
overlay_type OverlayType
overlay_type OverlayType,
bool FollowIsolatedPoints
>
struct intersection_of_multi_linestring_with_areal
{
@ -147,7 +148,7 @@ struct intersection_of_multi_linestring_with_areal
{
out = intersection_of_linestring_with_areal
<
ReverseAreal, LineStringOut, OverlayType
ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
>::apply(*it, areal, robust_policy, out, strategy);
}
@ -161,7 +162,8 @@ template
<
bool ReverseAreal,
typename LineStringOut,
overlay_type OverlayType
overlay_type OverlayType,
bool FollowIsolatedPoints
>
struct intersection_of_areal_with_multi_linestring
{
@ -178,7 +180,7 @@ struct intersection_of_areal_with_multi_linestring
{
return intersection_of_multi_linestring_with_areal
<
ReverseAreal, LineStringOut, OverlayType
ReverseAreal, LineStringOut, OverlayType, FollowIsolatedPoints
>::apply(ml, areal, robust_policy, out, strategy);
}
};
@ -228,14 +230,14 @@ template
typename MultiLinestring1, typename MultiLinestring2,
typename GeometryOut,
overlay_type OverlayType,
bool Reverse1, bool Reverse2, bool ReverseOut
bool Reverse1, bool Reverse2
>
struct intersection_insert
<
MultiLinestring1, MultiLinestring2,
GeometryOut,
OverlayType,
Reverse1, Reverse2, ReverseOut,
Reverse1, Reverse2,
multi_linestring_tag, multi_linestring_tag, point_tag,
linear_tag, linear_tag, pointlike_tag
> : detail::intersection::intersection_multi_linestring_multi_linestring_point
@ -250,14 +252,14 @@ template
typename Linestring, typename MultiLinestring,
typename GeometryOut,
overlay_type OverlayType,
bool Reverse1, bool Reverse2, bool ReverseOut
bool Reverse1, bool Reverse2
>
struct intersection_insert
<
Linestring, MultiLinestring,
GeometryOut,
OverlayType,
Reverse1, Reverse2, ReverseOut,
Reverse1, Reverse2,
linestring_tag, multi_linestring_tag, point_tag,
linear_tag, linear_tag, pointlike_tag
> : detail::intersection::intersection_linestring_multi_linestring_point
@ -272,14 +274,14 @@ template
typename MultiLinestring, typename Box,
typename GeometryOut,
overlay_type OverlayType,
bool Reverse1, bool Reverse2, bool ReverseOut
bool Reverse1, bool Reverse2
>
struct intersection_insert
<
MultiLinestring, Box,
GeometryOut,
OverlayType,
Reverse1, Reverse2, ReverseOut,
Reverse1, Reverse2,
multi_linestring_tag, box_tag, linestring_tag,
linear_tag, areal_tag, linear_tag
> : detail::intersection::clip_multi_linestring
@ -294,21 +296,22 @@ template
typename Linestring, typename MultiPolygon,
typename GeometryOut,
overlay_type OverlayType,
bool ReverseLinestring, bool ReverseMultiPolygon, bool ReverseOut
bool ReverseLinestring, bool ReverseMultiPolygon
>
struct intersection_insert
<
Linestring, MultiPolygon,
GeometryOut,
OverlayType,
ReverseLinestring, ReverseMultiPolygon, ReverseOut,
ReverseLinestring, ReverseMultiPolygon,
linestring_tag, multi_polygon_tag, linestring_tag,
linear_tag, areal_tag, linear_tag
> : detail::intersection::intersection_of_linestring_with_areal
<
ReverseMultiPolygon,
GeometryOut,
OverlayType
OverlayType,
false
>
{};
@ -320,21 +323,22 @@ template
typename Polygon, typename MultiLinestring,
typename GeometryOut,
overlay_type OverlayType,
bool ReversePolygon, bool ReverseMultiLinestring, bool ReverseOut
bool ReversePolygon, bool ReverseMultiLinestring
>
struct intersection_insert
<
Polygon, MultiLinestring,
GeometryOut,
OverlayType,
ReversePolygon, ReverseMultiLinestring, ReverseOut,
ReversePolygon, ReverseMultiLinestring,
polygon_tag, multi_linestring_tag, linestring_tag,
areal_tag, linear_tag, linear_tag
> : detail::intersection::intersection_of_areal_with_multi_linestring
<
ReversePolygon,
GeometryOut,
OverlayType
OverlayType,
false
>
{};
@ -344,21 +348,22 @@ template
typename MultiLinestring, typename Ring,
typename GeometryOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
bool ReverseMultiLinestring, bool ReverseRing
>
struct intersection_insert
<
MultiLinestring, Ring,
GeometryOut,
OverlayType,
ReverseMultiLinestring, ReverseRing, ReverseOut,
ReverseMultiLinestring, ReverseRing,
multi_linestring_tag, ring_tag, linestring_tag,
linear_tag, areal_tag, linear_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReverseRing,
GeometryOut,
OverlayType
OverlayType,
false
>
{};
@ -367,21 +372,22 @@ template
typename MultiLinestring, typename Polygon,
typename GeometryOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReverseRing, bool ReverseOut
bool ReverseMultiLinestring, bool ReversePolygon
>
struct intersection_insert
<
MultiLinestring, Polygon,
GeometryOut,
OverlayType,
ReverseMultiLinestring, ReverseRing, ReverseOut,
ReverseMultiLinestring, ReversePolygon,
multi_linestring_tag, polygon_tag, linestring_tag,
linear_tag, areal_tag, linear_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReverseRing,
ReversePolygon,
GeometryOut,
OverlayType
OverlayType,
false
>
{};
@ -392,25 +398,129 @@ template
typename MultiLinestring, typename MultiPolygon,
typename GeometryOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReverseMultiPolygon, bool ReverseOut
bool ReverseMultiLinestring, bool ReverseMultiPolygon
>
struct intersection_insert
<
MultiLinestring, MultiPolygon,
GeometryOut,
OverlayType,
ReverseMultiLinestring, ReverseMultiPolygon, ReverseOut,
ReverseMultiLinestring, ReverseMultiPolygon,
multi_linestring_tag, multi_polygon_tag, linestring_tag,
linear_tag, areal_tag, linear_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReverseMultiPolygon,
GeometryOut,
OverlayType
OverlayType,
false
>
{};
template
<
typename MultiLinestring, typename Ring,
typename TupledOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReverseRing
>
struct intersection_insert
<
MultiLinestring, Ring,
TupledOut,
OverlayType,
ReverseMultiLinestring, ReverseRing,
multi_linestring_tag, ring_tag, detail::intersection::tupled_output_tag,
linear_tag, areal_tag, detail::intersection::tupled_output_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReverseRing,
TupledOut,
OverlayType,
true
>
, detail::intersection::expect_output_pl<MultiLinestring, Ring, TupledOut>
{};
template
<
typename MultiLinestring, typename Polygon,
typename TupledOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReversePolygon
>
struct intersection_insert
<
MultiLinestring, Polygon,
TupledOut,
OverlayType,
ReverseMultiLinestring, ReversePolygon,
multi_linestring_tag, polygon_tag, detail::intersection::tupled_output_tag,
linear_tag, areal_tag, detail::intersection::tupled_output_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReversePolygon,
TupledOut,
OverlayType,
true
>
, detail::intersection::expect_output_pl<MultiLinestring, Polygon, TupledOut>
{};
template
<
typename Polygon, typename MultiLinestring,
typename TupledOut,
overlay_type OverlayType,
bool ReversePolygon, bool ReverseMultiLinestring
>
struct intersection_insert
<
Polygon, MultiLinestring,
TupledOut,
OverlayType,
ReversePolygon, ReverseMultiLinestring,
polygon_tag, multi_linestring_tag, detail::intersection::tupled_output_tag,
areal_tag, linear_tag, detail::intersection::tupled_output_tag
> : detail::intersection::intersection_of_areal_with_multi_linestring
<
ReversePolygon,
TupledOut,
OverlayType,
true
>
, detail::intersection::expect_output_pl<Polygon, MultiLinestring, TupledOut>
{};
template
<
typename MultiLinestring, typename MultiPolygon,
typename TupledOut,
overlay_type OverlayType,
bool ReverseMultiLinestring, bool ReverseMultiPolygon
>
struct intersection_insert
<
MultiLinestring, MultiPolygon,
TupledOut,
OverlayType,
ReverseMultiLinestring, ReverseMultiPolygon,
multi_linestring_tag, multi_polygon_tag, detail::intersection::tupled_output_tag,
linear_tag, areal_tag, detail::intersection::tupled_output_tag
> : detail::intersection::intersection_of_multi_linestring_with_areal
<
ReverseMultiPolygon,
TupledOut,
OverlayType,
true
>
, detail::intersection::expect_output_pl<MultiLinestring, MultiPolygon, TupledOut>
{};
} // namespace dispatch
#endif

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, 2018, 2019.
// Modifications copyright (c) 2014-2019 Oracle and/or its affiliates.
// This file was modified by Oracle on 2014, 2017, 2018, 2019, 2020.
// Modifications copyright (c) 2014-2020 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
@ -28,7 +28,7 @@
#include <boost/geometry/algorithms/covered_by.hpp>
#include <boost/geometry/algorithms/clear.hpp>
#include <boost/geometry/algorithms/detail/relate/turns.hpp>
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
namespace boost { namespace geometry
{
@ -42,7 +42,7 @@ namespace following
{
template <typename Turn, typename Operation>
static inline bool is_entering(Turn const& /* TODO remove this parameter */, Operation const& op)
inline bool is_entering(Turn const& /* TODO remove this parameter */, Operation const& op)
{
// (Blocked means: blocked for polygon/polygon intersection, because
// they are reversed. But for polygon/line it is similar to continue)
@ -60,7 +60,7 @@ template
typename Polygon,
typename PtInPolyStrategy
>
static inline bool last_covered_by(Turn const& /*turn*/, Operation const& op,
inline bool last_covered_by(Turn const& /*turn*/, Operation const& op,
LineString const& linestring, Polygon const& polygon,
PtInPolyStrategy const& strategy)
{
@ -76,7 +76,7 @@ template
typename Polygon,
typename PtInPolyStrategy
>
static inline bool is_leaving(Turn const& turn, Operation const& op,
inline bool is_leaving(Turn const& turn, Operation const& op,
bool entered, bool first,
LineString const& linestring, Polygon const& polygon,
PtInPolyStrategy const& strategy)
@ -85,7 +85,9 @@ static inline bool is_leaving(Turn const& turn, Operation const& op,
{
return entered
|| turn.method == method_crosses
|| (first && last_covered_by(turn, op, linestring, polygon, strategy))
|| (first
&& op.position != position_front
&& last_covered_by(turn, op, linestring, polygon, strategy))
;
}
return false;
@ -100,7 +102,7 @@ template
typename Polygon,
typename PtInPolyStrategy
>
static inline bool is_staying_inside(Turn const& turn, Operation const& op,
inline bool is_staying_inside(Turn const& turn, Operation const& op,
bool entered, bool first,
LineString const& linestring, Polygon const& polygon,
PtInPolyStrategy const& strategy)
@ -128,7 +130,7 @@ template
typename Polygon,
typename PtInPolyStrategy
>
static inline bool was_entered(Turn const& turn, Operation const& op, bool first,
inline bool was_entered(Turn const& turn, Operation const& op, bool first,
Linestring const& linestring, Polygon const& polygon,
PtInPolyStrategy const& strategy)
{
@ -139,6 +141,60 @@ static inline bool was_entered(Turn const& turn, Operation const& op, bool first
return false;
}
template
<
typename Turn,
typename Operation
>
inline bool is_touching(Turn const& turn, Operation const& op,
bool entered)
{
return (op.operation == operation_union || op.operation == operation_blocked)
&& (turn.method == method_touch || turn.method == method_touch_interior)
&& !entered
&& !op.is_collinear;
}
template
<
typename GeometryOut,
typename Tag = typename geometry::tag<GeometryOut>::type
>
struct add_isolated_point
{};
template <typename LineStringOut>
struct add_isolated_point<LineStringOut, linestring_tag>
{
template <typename Point, typename OutputIterator>
static inline void apply(Point const& point, OutputIterator& out)
{
LineStringOut isolated_point_ls;
geometry::append(isolated_point_ls, point);
#ifndef BOOST_GEOMETRY_ALLOW_ONE_POINT_LINESTRINGS
geometry::append(isolated_point_ls, point);
#endif // BOOST_GEOMETRY_ALLOW_ONE_POINT_LINESTRINGS
*out++ = isolated_point_ls;
}
};
template <typename PointOut>
struct add_isolated_point<PointOut, point_tag>
{
template <typename Point, typename OutputIterator>
static inline void apply(Point const& point, OutputIterator& out)
{
PointOut isolated_point;
geometry::detail::conversion::convert_point_to_point(point, isolated_point);
*out++ = isolated_point;
}
};
// Template specialization structure to call the right actions for the right type
template <overlay_type OverlayType, bool RemoveSpikes = true>
@ -213,26 +269,14 @@ struct action_selector<overlay_intersection, RemoveSpikes>
template
<
typename OutputIterator,
typename LineStringOut,
typename LineString,
typename LineStringOrPointOut,
typename Point,
typename Operation
typename OutputIterator
>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
signed_size_type, Point const& point,
Operation const& , OutputIterator& out)
static inline void isolated_point(Point const& point,
OutputIterator& out)
{
LineStringOut isolated_point_ls;
geometry::append(isolated_point_ls, point);
#ifndef BOOST_GEOMETRY_ALLOW_ONE_POINT_LINESTRINGS
geometry::append(isolated_point_ls, point);
#endif // BOOST_GEOMETRY_ALLOW_ONE_POINT_LINESTRINGS
*out++ = isolated_point_ls;
add_isolated_point<LineStringOrPointOut>::apply(point, out);
}
static inline bool is_entered(bool entered)
@ -301,17 +345,12 @@ struct action_selector<overlay_difference, RemoveSpikes>
template
<
typename OutputIterator,
typename LineStringOut,
typename LineString,
typename LineStringOrPointOut,
typename Point,
typename Operation
typename OutputIterator
>
static inline void isolated_point(LineStringOut&,
LineString const&,
segment_identifier&,
signed_size_type, Point const&,
Operation const&, OutputIterator&)
static inline void isolated_point(Point const&,
OutputIterator const&)
{
}
@ -327,7 +366,7 @@ struct action_selector<overlay_difference, RemoveSpikes>
};
}
} // namespace following
/*!
\brief Follows a linestring from intersection point to intersection point, outputting which
@ -336,64 +375,23 @@ struct action_selector<overlay_difference, RemoveSpikes>
*/
template
<
typename LineStringOut,
typename GeometryOut,
typename LineString,
typename Polygon,
overlay_type OverlayType,
bool RemoveSpikes = true
bool RemoveSpikes,
bool FollowIsolatedPoints
>
class follow
{
#ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
template <typename Turn>
struct sort_on_segment
{
// In case of turn point at the same location, we want to have continue/blocked LAST
// because that should be followed (intersection) or skipped (difference).
inline int operation_order(Turn const& turn) const
{
operation_type const& operation = turn.operations[0].operation;
switch(operation)
{
case operation_opposite : return 0;
case operation_none : return 0;
case operation_union : return 1;
case operation_intersection : return 2;
case operation_blocked : return 3;
case operation_continue : return 4;
}
return -1;
};
inline bool use_operation(Turn const& left, Turn const& right) const
{
// If they are the same, OK.
return operation_order(left) < operation_order(right);
}
inline bool use_distance(Turn const& left, Turn const& right) const
{
return left.operations[0].fraction == right.operations[0].fraction
? use_operation(left, right)
: left.operations[0].fraction < right.operations[0].fraction
;
}
inline bool operator()(Turn const& left, Turn const& right) const
{
segment_identifier const& sl = left.operations[0].seg_id;
segment_identifier const& sr = right.operations[0].seg_id;
return sl == sr
? use_distance(left, right)
: sl < sr
;
}
};
#endif // BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
typedef geometry::detail::output_geometry_access
<
GeometryOut, linestring_tag, linestring_tag
> linear;
typedef geometry::detail::output_geometry_access
<
GeometryOut, point_tag, linestring_tag
> pointlike;
public :
@ -441,17 +439,13 @@ public :
// sort turns by Linear seg_id, then by fraction, then
// for same ring id: x, u, i, c
// for different ring id: c, i, u, x
#ifdef BOOST_GEOMETRY_SETOPS_LA_OLD_BEHAVIOR
std::sort(boost::begin(turns), boost::end(turns), sort_on_segment<turn_type>());
#else
typedef relate::turns::less
<
0, relate::turns::less_op_linear_areal_single<0>, cs_tag
> turn_less;
std::sort(boost::begin(turns), boost::end(turns), turn_less());
#endif
LineStringOut current_piece;
typename linear::type current_piece;
geometry::segment_identifier current_segment_id(0, -1, -1, -1);
// Iterate through all intersection points (they are ordered along the line)
@ -481,7 +475,7 @@ public :
action::enter(current_piece, linestring, current_segment_id,
iit->seg_id.segment_index, it->point, *iit,
strategy, robust_policy,
out);
linear::get(out));
}
else if (following::is_leaving(*it, *iit, entered, first, linestring, polygon, pt_in_poly_strategy))
{
@ -491,8 +485,19 @@ public :
action::leave(current_piece, linestring, current_segment_id,
iit->seg_id.segment_index, it->point, *iit,
strategy, robust_policy,
out);
linear::get(out));
}
else if (FollowIsolatedPoints
&& following::is_touching(*it, *iit, entered))
{
debug_traverse(*it, *iit, "-> Isolated point");
action::template isolated_point
<
typename pointlike::type
>(it->point, pointlike::get(out));
}
first = false;
}
@ -509,10 +514,20 @@ public :
}
// Output the last one, if applicable
if (::boost::size(current_piece) > 1)
std::size_t current_piece_size = ::boost::size(current_piece);
if (current_piece_size > 1)
{
*out++ = current_piece;
*linear::get(out)++ = current_piece;
}
else if (FollowIsolatedPoints
&& current_piece_size == 1)
{
action::template isolated_point
<
typename pointlike::type
>(range::front(current_piece), pointlike::get(out));
}
return out;
}

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-2020, Oracle and/or its affiliates.
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
@ -34,6 +34,8 @@
#include <boost/geometry/algorithms/detail/turns/debug_turn.hpp>
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
#include <boost/geometry/algorithms/convert.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
@ -161,29 +163,36 @@ static inline bool is_isolated_point(Turn const& turn,
// GeometryOut - linestring or tuple of at least point and linestring
template
<
typename LinestringOut,
typename GeometryOut,
typename Linestring,
typename Linear,
overlay_type OverlayType,
bool FollowIsolatedPoints,
bool FollowContinueTurns
>
class follow_linestring_linear_linestring
class follow_linestring_linear
{
protected:
// allow spikes (false indicates: do not remove spikes)
typedef following::action_selector<OverlayType, false> action;
typedef geometry::detail::output_geometry_access
<
GeometryOut, linestring_tag, linestring_tag
> linear;
typedef geometry::detail::output_geometry_access
<
GeometryOut, point_tag, linestring_tag
> pointlike;
template
<
typename TurnIterator,
typename TurnOperationIterator,
typename LinestringOut,
typename SegmentIdentifier,
typename OutputIterator,
typename SideStrategy
@ -209,10 +218,12 @@ protected:
entered = true;
if ( enter_count == 0 )
{
action::enter(current_piece, linestring,
action::enter(current_piece,
linestring,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, strategy, robust_policy, oit);
it->point, *op_it, strategy, robust_policy,
linear::get(oit));
}
++enter_count;
}
@ -224,10 +235,12 @@ protected:
if ( enter_count == 0 )
{
entered = false;
action::leave(current_piece, linestring,
action::leave(current_piece,
linestring,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, strategy, robust_policy, oit);
it->point, *op_it, strategy, robust_policy,
linear::get(oit));
}
}
else if ( FollowIsolatedPoints
@ -235,10 +248,10 @@ protected:
{
detail::turns::debug_turn(*it, *op_it, "-> Isolated point");
action::isolated_point(current_piece, linestring,
current_segment_id,
op_it->seg_id.segment_index,
it->point, *op_it, oit);
action::template isolated_point
<
typename pointlike::type
>(it->point, pointlike::get(oit));
}
else if ( FollowContinueTurns
&& is_staying_inside(*it, *op_it, entered) )
@ -253,6 +266,7 @@ protected:
template
<
typename SegmentIdentifier,
typename LinestringOut,
typename OutputIterator,
typename SideStrategy
>
@ -283,7 +297,7 @@ protected:
// Output the last one, if applicable
if (::boost::size(current_piece) > 1)
{
*oit++ = current_piece;
*linear::get(oit)++ = current_piece;
}
return oit;
@ -300,7 +314,7 @@ public:
// Iterate through all intersection points (they are
// ordered along the each line)
LinestringOut current_piece;
typename linear::type current_piece;
geometry::segment_identifier current_segment_id(0, -1, -1, -1);
bool entered = false;
@ -344,8 +358,8 @@ template
bool FollowIsolatedPoints,
bool FollowContinueTurns
>
class follow_multilinestring_linear_linestring
: follow_linestring_linear_linestring
class follow_multilinestring_linear
: follow_linestring_linear
<
LinestringOut,
typename boost::range_value<MultiLinestring>::type,
@ -358,7 +372,7 @@ class follow_multilinestring_linear_linestring
protected:
typedef typename boost::range_value<MultiLinestring>::type Linestring;
typedef follow_linestring_linear_linestring
typedef follow_linestring_linear
<
LinestringOut, Linestring, Linear,
OverlayType, FollowIsolatedPoints, FollowContinueTurns
@ -492,11 +506,10 @@ template
overlay_type OverlayType,
bool FollowIsolatedPoints,
bool FollowContinueTurns,
typename TagOut = typename tag<LinestringOut>::type,
typename TagIn1 = typename tag<Geometry1>::type
>
struct follow
: not_implemented<LinestringOut, Geometry1>
: not_implemented<Geometry1>
{};
@ -514,8 +527,8 @@ struct follow
<
LinestringOut, Linestring, Linear,
OverlayType, FollowIsolatedPoints, FollowContinueTurns,
linestring_tag, linestring_tag
> : follow_linestring_linear_linestring
linestring_tag
> : follow_linestring_linear
<
LinestringOut, Linestring, Linear,
OverlayType, FollowIsolatedPoints, FollowContinueTurns
@ -536,8 +549,8 @@ struct follow
<
LinestringOut, MultiLinestring, Linear,
OverlayType, FollowIsolatedPoints, FollowContinueTurns,
linestring_tag, multi_linestring_tag
> : follow_multilinestring_linear_linestring
multi_linestring_tag
> : follow_multilinestring_linear
<
LinestringOut, MultiLinestring, Linear,
OverlayType, FollowIsolatedPoints, FollowContinueTurns

View File

@ -0,0 +1,304 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_OVERLAY_POINTLIKE_AREAL_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_AREAL_HPP
#include <vector>
#include <boost/range.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/algorithms/disjoint.hpp>
#include <boost/geometry/algorithms/envelope.hpp>
#include <boost/geometry/algorithms/expand.hpp>
#include <boost/geometry/algorithms/not_implemented.hpp>
#include <boost/geometry/algorithms/detail/not.hpp>
#include <boost/geometry/algorithms/detail/partition.hpp>
#include <boost/geometry/algorithms/detail/disjoint/point_geometry.hpp>
#include <boost/geometry/algorithms/detail/equals/point_point.hpp>
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail { namespace overlay
{
// difference/intersection of multipoint-multipolygon
template
<
typename MultiPoint,
typename MultiPolygon,
typename PointOut,
overlay_type OverlayType,
typename Policy
>
class multipoint_multipolygon_point
{
private:
template <typename ExpandPointStrategy>
struct expand_box_point
{
template <typename Box, typename Point>
static inline void apply(Box& total, Point const& point)
{
geometry::expand(total, point, ExpandPointStrategy());
}
};
template <typename ExpandBoxStrategy>
struct expand_box_boxpair
{
template <typename Box1, typename Box2, typename SizeT>
static inline void apply(Box1& total, std::pair<Box2, SizeT> const& box_pair)
{
geometry::expand(total, box_pair.first, ExpandBoxStrategy());
}
};
template <typename DisjointPointBoxStrategy>
struct overlaps_box_point
{
template <typename Box, typename Point>
static inline bool apply(Box const& box, Point const& point)
{
return ! geometry::disjoint(point, box, DisjointPointBoxStrategy());
}
};
template <typename DisjointBoxBoxStrategy>
struct overlaps_box_boxpair
{
template <typename Box1, typename Box2, typename SizeT>
static inline bool apply(Box1 const& box, std::pair<Box2, SizeT> const& box_pair)
{
return ! geometry::disjoint(box, box_pair.first, DisjointBoxBoxStrategy());
}
};
template <typename OutputIterator, typename Strategy>
class item_visitor_type
{
public:
item_visitor_type(MultiPolygon const& multipolygon,
OutputIterator& oit,
Strategy const& strategy)
: m_multipolygon(multipolygon)
, m_oit(oit)
, m_strategy(strategy)
{}
template <typename Point, typename Box, typename SizeT>
inline bool apply(Point const& item1, std::pair<Box, SizeT> const& item2)
{
action_selector_pl
<
PointOut, overlay_intersection
>::apply(item1,
Policy::apply(item1,
range::at(m_multipolygon,
item2.second),
m_strategy),
m_oit);
return true;
}
private:
MultiPolygon const& m_multipolygon;
OutputIterator& m_oit;
Strategy const& m_strategy;
};
template <typename Iterator, typename Box, typename SizeT, typename EnvelopeStrategy>
static inline void fill_box_pairs(Iterator first, Iterator last,
std::vector<std::pair<Box, SizeT> > & box_pairs,
EnvelopeStrategy const& strategy)
{
SizeT index = 0;
for (; first != last; ++first, ++index)
{
box_pairs.push_back(
std::make_pair(geometry::return_envelope<Box>(*first, strategy),
index));
}
}
template <typename OutputIterator, typename Strategy>
static inline OutputIterator get_common_points(MultiPoint const& multipoint,
MultiPolygon const& multipolygon,
OutputIterator oit,
Strategy const& strategy)
{
item_visitor_type<OutputIterator, Strategy> item_visitor(multipolygon, oit, strategy);
typedef geometry::model::point
<
typename geometry::coordinate_type<MultiPoint>::type,
geometry::dimension<MultiPoint>::value,
typename geometry::coordinate_system<MultiPoint>::type
> point_type;
typedef geometry::model::box<point_type> box_type;
typedef std::pair<box_type, std::size_t> box_pair;
std::vector<box_pair> box_pairs;
box_pairs.reserve(boost::size(multipolygon));
fill_box_pairs(boost::begin(multipolygon),
boost::end(multipolygon),
box_pairs,
strategy.get_envelope_strategy());
typedef typename Strategy::envelope_strategy_type::box_expand_strategy_type expand_box_strategy_type;
typedef typename Strategy::disjoint_box_box_strategy_type disjoint_box_box_strategy_type;
typedef typename Strategy::disjoint_point_box_strategy_type disjoint_point_box_strategy_type;
typedef typename Strategy::expand_point_strategy_type expand_point_strategy_type;
geometry::partition
<
box_type
>::apply(multipoint, box_pairs, item_visitor,
expand_box_point<expand_point_strategy_type>(),
overlaps_box_point<disjoint_point_box_strategy_type>(),
expand_box_boxpair<expand_box_strategy_type>(),
overlaps_box_boxpair<disjoint_box_box_strategy_type>());
return oit;
}
public:
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(MultiPoint const& multipoint,
MultiPolygon const& multipolygon,
RobustPolicy const& robust_policy,
OutputIterator oit,
Strategy const& strategy)
{
typedef std::vector
<
typename boost::range_value<MultiPoint>::type
> point_vector_type;
point_vector_type common_points;
// compute the common points
get_common_points(multipoint, multipolygon,
std::back_inserter(common_points),
strategy);
return multipoint_multipoint_point
<
MultiPoint, point_vector_type, PointOut, OverlayType
>::apply(multipoint, common_points, robust_policy, oit, strategy);
}
};
}} // namespace detail::overlay
#endif // DOXYGEN_NO_DISPATCH
#ifndef DOXYGEN_NO_DISPATCH
namespace detail_dispatch { namespace overlay
{
// dispatch struct for pointlike-areal difference/intersection computation
template
<
typename PointLike,
typename Areal,
typename PointOut,
overlay_type OverlayType,
typename Tag1,
typename Tag2
>
struct pointlike_areal_point
: not_implemented<PointLike, Areal, PointOut>
{};
template
<
typename Point,
typename Areal,
typename PointOut,
overlay_type OverlayType,
typename Tag2
>
struct pointlike_areal_point
<
Point, Areal, PointOut, OverlayType, point_tag, Tag2
> : detail::overlay::point_single_point
<
Point, Areal, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>
>
{};
// TODO: Consider implementing Areal-specific version
// calculating envelope first in order to reject Points without
// calling disjoint for Rings and Polygons
template
<
typename MultiPoint,
typename Areal,
typename PointOut,
overlay_type OverlayType,
typename Tag2
>
struct pointlike_areal_point
<
MultiPoint, Areal, PointOut, OverlayType, multi_point_tag, Tag2
> : detail::overlay::multipoint_single_point
<
MultiPoint, Areal, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>
>
{};
template
<
typename MultiPoint,
typename MultiPolygon,
typename PointOut,
overlay_type OverlayType
>
struct pointlike_areal_point
<
MultiPoint, MultiPolygon, PointOut, OverlayType, multi_point_tag, multi_polygon_tag
> : detail::overlay::multipoint_multipolygon_point
<
MultiPoint, MultiPolygon, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>
>
{};
}} // namespace detail_dispatch::overlay
#endif // DOXYGEN_NO_DISPATCH
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_POINTLIKE_AREAL_HPP

View File

@ -2,7 +2,7 @@
// Copyright (c) 2017 Adam Wulkiewicz, Lodz, Poland.
// Copyright (c) 2015-2019, Oracle and/or its affiliates.
// Copyright (c) 2015-2020, 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
@ -47,36 +47,28 @@ namespace detail { namespace overlay
{
// action struct for pointlike-linear difference/intersection
// it works the same as its pointlike-pointlike counterpart, hence the
// derivation
template <typename PointOut, overlay_type OverlayType>
struct action_selector_pl_l
: action_selector_pl_pl<PointOut, OverlayType>
{};
// difference/intersection of point-linear
template
<
typename Point,
typename Linear,
typename Geometry,
typename PointOut,
overlay_type OverlayType,
typename Policy
>
struct point_linear_point
struct point_single_point
{
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(Point const& point,
Linear const& linear,
Geometry const& geometry,
RobustPolicy const&,
OutputIterator oit,
Strategy const& strategy)
{
action_selector_pl_l
action_selector_pl
<
PointOut, OverlayType
>::apply(point, Policy::apply(point, linear, strategy), oit);
>::apply(point, Policy::apply(point, geometry, strategy), oit);
return oit;
}
};
@ -85,16 +77,16 @@ struct point_linear_point
template
<
typename MultiPoint,
typename Segment,
typename Geometry,
typename PointOut,
overlay_type OverlayType,
typename Policy
>
struct multipoint_segment_point
struct multipoint_single_point
{
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
static inline OutputIterator apply(MultiPoint const& multipoint,
Segment const& segment,
Geometry const& geometry,
RobustPolicy const&,
OutputIterator oit,
Strategy const& strategy)
@ -104,10 +96,10 @@ struct multipoint_segment_point
it != boost::end(multipoint);
++it)
{
action_selector_pl_l
action_selector_pl
<
PointOut, OverlayType
>::apply(*it, Policy::apply(*it, segment, strategy), oit);
>::apply(*it, Policy::apply(*it, geometry, strategy), oit);
}
return oit;
@ -194,7 +186,7 @@ private:
template <typename Item1, typename Item2>
inline bool apply(Item1 const& item1, Item2 const& item2)
{
action_selector_pl_l
action_selector_pl
<
PointOut, overlay_intersection
>::apply(item1, Policy::apply(item1, item2, m_strategy), m_oit);
@ -326,7 +318,7 @@ template
struct pointlike_linear_point
<
Point, Linear, PointOut, OverlayType, point_tag, linear_tag
> : detail::overlay::point_linear_point
> : detail::overlay::point_single_point
<
Point, Linear, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>
@ -344,7 +336,7 @@ template
struct pointlike_linear_point
<
Point, Segment, PointOut, OverlayType, point_tag, segment_tag
> : detail::overlay::point_linear_point
> : detail::overlay::point_single_point
<
Point, Segment, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>
@ -380,7 +372,7 @@ template
struct pointlike_linear_point
<
MultiPoint, Segment, PointOut, OverlayType, multi_point_tag, segment_tag
> : detail::overlay::multipoint_segment_point
> : detail::overlay::multipoint_single_point
<
MultiPoint, Segment, PointOut, OverlayType,
detail::not_<detail::disjoint::reverse_covered_by>

View File

@ -1,6 +1,6 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2019, Oracle and/or its affiliates.
// Copyright (c) 2014-2020, 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
@ -87,11 +87,11 @@ struct copy_points<PointOut, MultiPointIn, multi_point_tag>
// action struct for difference/intersection
template <typename PointOut, overlay_type OverlayType>
struct action_selector_pl_pl
struct action_selector_pl
{};
template <typename PointOut>
struct action_selector_pl_pl<PointOut, overlay_intersection>
struct action_selector_pl<PointOut, overlay_intersection>
{
template
<
@ -112,7 +112,7 @@ struct action_selector_pl_pl<PointOut, overlay_intersection>
template <typename PointOut>
struct action_selector_pl_pl<PointOut, overlay_difference>
struct action_selector_pl<PointOut, overlay_difference>
{
template
<
@ -150,7 +150,7 @@ struct point_point_point
OutputIterator oit,
Strategy const& strategy)
{
action_selector_pl_pl
action_selector_pl
<
PointOut, OverlayType
>::apply(point1,
@ -190,7 +190,7 @@ struct multipoint_point_point
it = boost::begin(multipoint);
it != boost::end(multipoint); ++it)
{
action_selector_pl_pl
action_selector_pl
<
PointOut, OverlayType
>::apply(*it,
@ -220,7 +220,7 @@ struct point_multipoint_point
OutputIterator oit,
Strategy const& strategy)
{
typedef action_selector_pl_pl<PointOut, OverlayType> action;
typedef action_selector_pl<PointOut, OverlayType> action;
for (typename boost::range_iterator<MultiPoint const>::type
it = boost::begin(multipoint);
@ -283,7 +283,7 @@ struct multipoint_multipoint_point
bool found = std::binary_search(points2.begin(), points2.end(),
*it1, less);
action_selector_pl_pl
action_selector_pl
<
PointOut, OverlayType
>::apply(*it1, found, oit);

View File

@ -25,8 +25,7 @@
#include <boost/geometry/core/topological_dimension.hpp>
#include <boost/geometry/core/tag.hpp>
// TEMP - move this header to geometry/detail
#include <boost/geometry/index/detail/tuples.hpp>
#include <boost/geometry/util/tuples.hpp>
namespace boost { namespace geometry
{
@ -202,7 +201,7 @@ operator||(mask const& m1, mask const& m2)
template <typename Tail>
inline
typename index::detail::tuples::push_back
typename geometry::tuples::push_back
<
boost::tuples::cons<mask, Tail>,
mask
@ -211,7 +210,7 @@ operator||(boost::tuples::cons<mask, Tail> const& t, mask const& m)
{
namespace bt = boost::tuples;
return index::detail::tuples::push_back
return geometry::tuples::push_back
<
bt::cons<mask, Tail>,
mask

View File

@ -0,0 +1,535 @@
// Boost.Geometry
// Copyright (c) 2019-2020, Oracle and/or its affiliates.
// 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_TUPLED_OUTPUT_HPP
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_TUPLED_OUTPUT_HPP
#include <boost/geometry/core/config.hpp>
#include <boost/geometry/core/tag.hpp>
#include <boost/geometry/core/tags.hpp>
#include <boost/geometry/util/range.hpp>
#include <boost/geometry/util/tuples.hpp>
#include <boost/mpl/and.hpp>
#include <boost/range/value_type.hpp>
#include <boost/type_traits/detail/yes_no_type.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_base_of.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
namespace boost { namespace geometry
{
#ifndef DOXYGEN_NO_DETAIL
namespace detail
{
// true for any geometry
template <typename T>
struct is_geometry
: boost::integral_constant
<
bool,
(! boost::is_void<typename geometry::tag<T>::type>::value)
>
{};
// true for multi-point, multi-linestring or multi-polygon
template <typename Geometry>
struct is_multi_geometry
: boost::is_base_of
<
geometry::multi_tag,
typename geometry::tag<Geometry>::type
>
{};
// true for point, linestring or polygon
template <typename T>
struct is_multi_geometry_value
: boost::integral_constant
<
bool,
((boost::is_same<typename geometry::tag<T>::type, point_tag>::value)
|| (boost::is_same<typename geometry::tag<T>::type, linestring_tag>::value)
|| (boost::is_same<typename geometry::tag<T>::type, polygon_tag>::value))
>
{};
template <typename T>
struct is_range_impl
{
typedef boost::type_traits::yes_type yes_type;
typedef boost::type_traits::no_type no_type;
template <typename U>
static yes_type test(typename boost::range_iterator<U>::type*);
template <typename U>
static no_type test(...);
static const bool value = (sizeof(test<T>(0)) == sizeof(yes_type));
};
// true if T is range (boost::range_iterator<T>::type is defined)
template <typename T>
struct is_range
: boost::integral_constant<bool, is_range_impl<T>::value>
{};
// geometry tag of Rng value_type
template <typename Rng>
struct range_value_tag
: geometry::tag<typename boost::range_value<Rng>::type>
{};
// true if geometry tag of Rng is the same as Tag
template <typename Rng, typename Tag>
struct is_range_value_tag_same_as
: boost::is_same
<
typename range_value_tag<Rng>::type,
Tag
>
{};
template <typename T, bool IsRange = is_range<T>::value>
struct is_tupled_output_element_base
: boost::integral_constant<bool, false>
{};
template <typename T>
struct is_tupled_output_element_base<T, true>
: boost::integral_constant
<
bool,
(is_multi_geometry<T>::value
||
((! is_geometry<T>::value)
&&
((is_range_value_tag_same_as<T, point_tag>::value)
|| (is_range_value_tag_same_as<T, linestring_tag>::value)
|| (is_range_value_tag_same_as<T, polygon_tag>::value))))
>
{};
// true if T is a multi-geometry or is a range of points, linestrings or
// polygons
template <typename T>
struct is_tupled_output_element
: is_tupled_output_element_base<T>
{};
// true if Output is not a geometry (so e.g. tuple was not adapted to any
// concept) and at least one of the tuple elements is a multi-geometry or
// a range of points linestrings or polygons
template <typename Output>
struct is_tupled_output_check
: boost::mpl::and_
<
boost::is_same<typename geometry::tag<Output>::type, void>,
//geometry::tuples::exists_if<Output, is_multi_geometry>
geometry::tuples::exists_if<Output, is_tupled_output_element>
>
{};
// true if T is a point, linestring or polygon
template <typename T>
struct is_tupled_range_values_element
: boost::integral_constant
<
bool,
((boost::is_same<typename geometry::tag<T>::type, point_tag>::value)
|| (boost::is_same<typename geometry::tag<T>::type, linestring_tag>::value)
|| (boost::is_same<typename geometry::tag<T>::type, polygon_tag>::value))
>
{};
// true if T is not a geometry (so e.g. tuple was not adapted to any
// concept) and at least one of the tuple elements is a point, linesting
// or polygon
template <typename T>
struct is_tupled_range_values_check
: boost::mpl::and_
<
boost::is_same<typename geometry::tag<T>::type, void>,
geometry::tuples::exists_if<T, is_tupled_range_values_element>
>
{};
// true if Output is boost::tuple, boost::tuples::cons, std::pair or std::tuple
template <typename T>
struct is_tupled
: boost::integral_constant<bool, false>
{};
template
<
class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9
>
struct is_tupled<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
: boost::integral_constant<bool, true>
{};
template <typename HT, typename TT>
struct is_tupled<boost::tuples::cons<HT, TT> >
: boost::integral_constant<bool, true>
{};
template <typename F, typename S>
struct is_tupled<std::pair<F, S> >
: boost::integral_constant<bool, true>
{};
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
template <typename ...Ts>
struct is_tupled<std::tuple<Ts...> >
: boost::integral_constant<bool, true>
{};
#endif // BOOST_GEOMETRY_CXX11_TUPLE
// true if Output is boost::tuple, boost::tuples::cons, std::pair or std::tuple
// and is_tupled_output_check defiend above passes
template <typename Output, bool IsTupled = is_tupled<Output>::value>
struct is_tupled_output
: boost::integral_constant<bool, false>
{};
template <typename Output>
struct is_tupled_output<Output, true>
: is_tupled_output_check<Output>
{};
// true if T is boost::tuple, boost::tuples::cons, std::pair or std::tuple
// and is_tupled_range_values_check defiend above passes
template <typename T, bool IsTupled = is_tupled<T>::value>
struct is_tupled_range_values
: boost::integral_constant<bool, false>
{};
template <typename T>
struct is_tupled_range_values<T, true>
: is_tupled_range_values_check<T>
{};
template <typename Tag>
struct tupled_output_find_index_pred
{
template <typename T>
struct pred
: boost::is_same<typename geometry::tag<T>::type, Tag>
{};
};
// Valid only if tupled_output_has<Output, Tag> is true
template <typename Output, typename Tag>
struct tupled_output_find_index
: geometry::tuples::find_index_if
<
Output,
tupled_output_find_index_pred<Tag>::template pred
>
{};
template
<
typename Output,
typename Tag,
bool IsTupledOutput = is_tupled_output<Output>::value
>
struct tupled_output_has
: boost::integral_constant<bool, false>
{};
template <typename Output, typename Tag>
struct tupled_output_has<Output, Tag, true>
: boost::integral_constant
<
bool,
((tupled_output_find_index<Output, Tag>::value)
< (geometry::tuples::size<Output>::value))
>
{};
// Valid only if tupled_output_has<Output, Tag> is true
template <typename Tag, typename Output>
inline typename geometry::tuples::element
<
tupled_output_find_index<Output, Tag>::value,
Output
>::type &
tupled_output_get(Output & output)
{
return geometry::tuples::get<tupled_output_find_index<Output, Tag>::value>(output);
}
// defines a tuple-type holding value-types of ranges being elements of
// Output pair/tuple
template
<
typename Tuple,
size_t I = 0,
size_t N = geometry::tuples::size<Tuple>::value
>
struct tupled_range_values_bt
{
typedef boost::tuples::cons
<
typename boost::range_value
<
typename geometry::tuples::element<I, Tuple>::type
>::type,
typename tupled_range_values_bt<Tuple, I+1, N>::type
> type;
};
template <typename Tuple, size_t N>
struct tupled_range_values_bt<Tuple, N, N>
{
typedef boost::tuples::null_type type;
};
template <typename Output>
struct tupled_range_values
: tupled_range_values_bt<Output>
{};
template <typename F, typename S>
struct tupled_range_values<std::pair<F, S> >
{
typedef std::pair
<
typename boost::range_value<F>::type,
typename boost::range_value<S>::type
> type;
};
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
template <typename ...Ts>
struct tupled_range_values<std::tuple<Ts...> >
{
typedef std::tuple<typename boost::range_value<Ts>::type...> type;
};
#endif // BOOST_GEOMETRY_CXX11_TUPLE
// util defining a type and creating a tuple holding back-insert-iterators to
// ranges being elements of Output pair/tuple
template <typename Tuple,
size_t I = 0,
size_t N = geometry::tuples::size<Tuple>::value>
struct tupled_back_inserters_bt
{
typedef boost::tuples::cons
<
geometry::range::back_insert_iterator
<
typename geometry::tuples::element<I, Tuple>::type
>,
typename tupled_back_inserters_bt<Tuple, I+1, N>::type
> type;
static type apply(Tuple & tup)
{
return type(geometry::range::back_inserter(geometry::tuples::get<I>(tup)),
tupled_back_inserters_bt<Tuple, I+1, N>::apply(tup));
}
};
template <typename Tuple, size_t N>
struct tupled_back_inserters_bt<Tuple, N, N>
{
typedef boost::tuples::null_type type;
static type apply(Tuple const&)
{
return type();
}
};
template <typename Tuple>
struct tupled_back_inserters
: tupled_back_inserters_bt<Tuple>
{};
template <typename F, typename S>
struct tupled_back_inserters<std::pair<F, S> >
{
typedef std::pair
<
geometry::range::back_insert_iterator<F>,
geometry::range::back_insert_iterator<S>
> type;
static type apply(std::pair<F, S> & p)
{
return type(geometry::range::back_inserter(p.first),
geometry::range::back_inserter(p.second));
}
};
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
// NOTE: In C++14 std::integer_sequence and std::make_integer_sequence could be used
template <typename Is, typename Tuple>
struct tupled_back_inserters_st;
template <int ...Is, typename ...Ts>
struct tupled_back_inserters_st<geometry::tuples::int_sequence<Is...>, std::tuple<Ts...> >
{
typedef std::tuple<geometry::range::back_insert_iterator<Ts>...> type;
static type apply(std::tuple<Ts...> & tup)
{
return type(geometry::range::back_inserter(std::get<Is>(tup))...);
}
};
template <typename ...Ts>
struct tupled_back_inserters<std::tuple<Ts...> >
: tupled_back_inserters_st
<
typename geometry::tuples::make_int_sequence<sizeof...(Ts)>::type,
std::tuple<Ts...>
>
{};
#endif // BOOST_GEOMETRY_CXX11_TUPLE
template
<
typename GeometryOut,
bool IsTupled = is_tupled_output<GeometryOut>::value
>
struct output_geometry_value
: boost::range_value<GeometryOut>
{};
template <typename GeometryOut>
struct output_geometry_value<GeometryOut, true>
: tupled_range_values<GeometryOut>
{};
template
<
typename GeometryOut,
bool IsTupled = is_tupled_output<GeometryOut>::value
>
struct output_geometry_back_inserter_
{
typedef geometry::range::back_insert_iterator<GeometryOut> type;
static type apply(GeometryOut & out)
{
return geometry::range::back_inserter(out);
}
};
template <typename GeometryOut>
struct output_geometry_back_inserter_<GeometryOut, true>
: tupled_back_inserters<GeometryOut>
{};
template <typename GeometryOut>
inline typename output_geometry_back_inserter_<GeometryOut>::type
output_geometry_back_inserter(GeometryOut & out)
{
return output_geometry_back_inserter_<GeometryOut>::apply(out);
}
// is_tag_same_as_pred
// Defines a predicate true if type's tag is the same as Tag
template <typename Tag>
struct is_tag_same_as_pred
{
template <typename T>
struct pred
: boost::is_same<typename geometry::tag<T>::type, Tag>
{};
};
// Allows to access a type/object in a pair/tuple corresponding to an index in
// GeometryOut pair/tuple of a geometry defined by Tag.
// If GeometryOut is a geometry then it's expected to be defined by DefaultTag.
template
<
typename GeometryOut,
typename Tag,
typename DefaultTag,
typename GeometryTag = typename geometry::tag<GeometryOut>::type
>
struct output_geometry_access
{};
// assume GeometryTag is void because not adapted tuple holding geometries was passed
template <typename TupledOut, typename Tag, typename DefaultTag>
struct output_geometry_access<TupledOut, Tag, DefaultTag, void>
{
static const int index = geometry::tuples::find_index_if
<
TupledOut, is_tag_same_as_pred<Tag>::template pred
>::value;
typedef typename geometry::tuples::element<index, TupledOut>::type type;
template <typename Tuple>
static typename geometry::tuples::element<index, Tuple>::type&
get(Tuple & tup)
{
return geometry::tuples::get<index>(tup);
}
};
template <typename GeometryOut, typename Tag, typename DefaultTag>
struct output_geometry_access<GeometryOut, Tag, DefaultTag, DefaultTag>
{
typedef GeometryOut type;
template <typename T>
static T& get(T & v)
{
return v;
}
};
} // namespace detail
#endif // DOXYGEN_NO_DETAIL
}} // namespace boost::geometry
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_TUPLED_OUTPUT_HPP

View File

@ -1,7 +1,8 @@
// Boost.Geometry
// Copyright (c) 2019 Barend Gehrels, Amsterdam, the Netherlands.
// Copyright (c) 2018 Oracle and/or its affiliates.
// Copyright (c) 2018-2020 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,
@ -18,6 +19,10 @@
#define BOOST_GEOMETRY_CXX11_ARRAY_UNIFIED_INITIALIZATION
#endif
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
#define BOOST_GEOMETRY_CXX11_TUPLE
#endif
// Defining this selects Kramer rule for segment-intersection
// That is default behaviour.
#define BOOST_GEOMETRY_USE_KRAMER_RULE

View File

@ -1,204 +0,0 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 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
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_INDEX_DETAIL_TUPLES_HPP
#define BOOST_GEOMETRY_INDEX_DETAIL_TUPLES_HPP
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/is_same.hpp>
// TODO move this to index/tuples and separate algorithms
namespace boost { namespace geometry { namespace index { namespace detail {
namespace tuples {
// find_index
namespace detail {
template <typename Tuple, typename El, size_t N>
struct find_index;
template <typename Tuple, typename El, size_t N, typename CurrentEl>
struct find_index_impl
{
static const size_t value = find_index<Tuple, El, N - 1>::value;
};
template <typename Tuple, typename El, size_t N>
struct find_index_impl<Tuple, El, N, El>
{
static const size_t value = N - 1;
};
template <typename Tuple, typename El, typename CurrentEl>
struct find_index_impl<Tuple, El, 1, CurrentEl>
{
BOOST_MPL_ASSERT_MSG(
(false),
ELEMENT_NOT_FOUND,
(find_index_impl));
};
template <typename Tuple, typename El>
struct find_index_impl<Tuple, El, 1, El>
{
static const size_t value = 0;
};
template <typename Tuple, typename El, size_t N>
struct find_index
{
static const size_t value =
find_index_impl<
Tuple,
El,
N,
typename boost::tuples::element<N - 1, Tuple>::type
>::value;
};
} // namespace detail
template <typename Tuple, typename El>
struct find_index
{
static const size_t value =
detail::find_index<
Tuple,
El,
boost::tuples::length<Tuple>::value
>::value;
};
// has
namespace detail {
template <typename Tuple, typename El, size_t N>
struct has
{
static const bool value
= boost::is_same<
typename boost::tuples::element<N - 1, Tuple>::type,
El
>::value
|| has<Tuple, El, N - 1>::value;
};
template <typename Tuple, typename El>
struct has<Tuple, El, 1>
{
static const bool value
= boost::is_same<
typename boost::tuples::element<0, Tuple>::type,
El
>::value;
};
} // namespace detail
template <typename Tuple, typename El>
struct has
{
static const bool value
= detail::has<
Tuple,
El,
boost::tuples::length<Tuple>::value
>::value;
};
// add
template <typename Tuple, typename El>
struct add
{
BOOST_MPL_ASSERT_MSG(
(false),
NOT_IMPLEMENTED_FOR_THIS_TUPLE_TYPE,
(add));
};
template <typename T1, typename T>
struct add<boost::tuple<T1>, T>
{
typedef boost::tuple<T1, T> type;
};
template <typename T1, typename T2, typename T>
struct add<boost::tuple<T1, T2>, T>
{
typedef boost::tuple<T1, T2, T> type;
};
// add_if
template <typename Tuple, typename El, bool Cond>
struct add_if
{
typedef Tuple type;
};
template <typename Tuple, typename El>
struct add_if<Tuple, El, true>
{
typedef typename add<Tuple, El>::type type;
};
// add_unique
template <typename Tuple, typename El>
struct add_unique
{
typedef typename add_if<
Tuple,
El,
!has<Tuple, El>::value
>::type type;
};
template <typename Tuple,
typename T,
size_t I = 0,
size_t N = boost::tuples::length<Tuple>::value>
struct push_back
{
typedef
boost::tuples::cons<
typename boost::tuples::element<I, Tuple>::type,
typename push_back<Tuple, T, I+1, N>::type
> type;
static type apply(Tuple const& tup, T const& t)
{
return
type(
boost::get<I>(tup),
push_back<Tuple, T, I+1, N>::apply(tup, t)
);
}
};
template <typename Tuple, typename T, size_t N>
struct push_back<Tuple, T, N, N>
{
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
static type apply(Tuple const&, T const& t)
{
return type(t, boost::tuples::null_type());
}
};
} // namespace tuples
}}}} // namespace boost::geometry::index::detail
#endif // BOOST_GEOMETRY_INDEX_DETAIL_RTREE_TAGS_HPP

View File

@ -4,6 +4,10 @@
//
// Copyright (c) 2011-2018 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019.
// Modifications copyright (c) 2019 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,7 @@
#define BOOST_GEOMETRY_INDEX_PREDICATES_HPP
#include <boost/geometry/index/detail/predicates.hpp>
#include <boost/geometry/index/detail/tuples.hpp>
#include <boost/geometry/util/tuples.hpp>
/*!
\defgroup predicates Predicates (boost::geometry::index::)
@ -408,7 +412,7 @@ operator&&(Pred1 const& p1, Pred2 const& p2)
}
template <typename Head, typename Tail, typename Pred> inline
typename tuples::push_back<
typename geometry::tuples::push_back<
boost::tuples::cons<Head, Tail>, Pred
>::type
operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
@ -417,7 +421,7 @@ operator&&(boost::tuples::cons<Head, Tail> const& t, Pred const& p)
namespace bt = boost::tuples;
return
tuples::push_back<
geometry::tuples::push_back<
bt::cons<Head, Tail>, Pred
>::apply(t, p);
}

View File

@ -125,12 +125,12 @@ inline const pj_datums_type<T>* pj_datum_find_datum(srs::dpar::parameters<T> con
template
<
typename Params,
typename Param = typename srs::spar::detail::tuples_find_if
typename Param = typename geometry::tuples::find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::datum_traits>::pred
>::type,
bool IsFound = srs::spar::detail::tuples_is_found<Param>::value
bool IsFound = geometry::tuples::is_found<Param>::value
>
struct pj_datum_find_datum_static
{
@ -214,7 +214,7 @@ inline bool pj_datum_find_nadgrids(srs::dpar::parameters<T> const& params,
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
int I = geometry::tuples::find_index_if
<
Params,
srs::spar::detail::is_param<srs::spar::nadgrids>::pred
@ -309,7 +309,7 @@ inline bool pj_datum_find_towgs84(srs::dpar::parameters<T> const& params,
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
int I = geometry::tuples::find_index_if
<
Params,
srs::spar::detail::is_param_t<srs::spar::towgs84>::pred

View File

@ -3,8 +3,8 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018, 2019.
// Modifications copyright (c) 2017-2019, 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,
@ -161,7 +161,7 @@ inline bool pj_ell_init_ellps(srs::dpar::parameters<T> const& params, T &a, T &b
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
int I = geometry::tuples::find_index_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::ellps_traits>::pred
@ -363,35 +363,35 @@ struct static_srs_tag_check_nonexpanded
{
typedef typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_au>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_v>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_a>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_g>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::r_h>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r_lat_a>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::r_lat_g>::pred
>::value,
@ -400,23 +400,23 @@ struct static_srs_tag_check_nonexpanded
// b, es, e, f, rf parameters then he wants to define spheroid, not sphere
typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::b>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::es>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::e>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::rf>::pred
>::value
|| srs::spar::detail::tuples_exists_if
|| geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param_t<srs::spar::f>::pred
>::value,
@ -433,7 +433,7 @@ struct static_srs_tag_check_ellps
<
typename srs::spar::detail::ellps_traits
<
typename srs::spar::detail::tuples_find_if
typename geometry::tuples::find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::ellps_traits>::pred
@ -451,7 +451,7 @@ struct static_srs_tag_check_datum
<
typename srs::spar::detail::datum_traits
<
typename srs::spar::detail::tuples_find_if
typename geometry::tuples::find_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::datum_traits>::pred
@ -506,7 +506,7 @@ struct static_srs_tag<Params, void, void, void>
// so use default or generate error
typedef typename boost::mpl::if_c
<
srs::spar::detail::tuples_exists_if
geometry::tuples::exists_if
<
Params, srs::spar::detail::is_param<srs::spar::no_defs>::pred
>::value,

View File

@ -3,8 +3,8 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018, 2019.
// Modifications copyright (c) 2017-2019, 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,
@ -98,13 +98,13 @@ inline void pj_init_proj(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL
parameters<T> & par)
{
typedef srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> params_type;
typedef typename srs::spar::detail::tuples_find_if
typedef typename geometry::tuples::find_if
<
params_type,
srs::spar::detail::is_param_tr<srs::spar::detail::proj_traits>::pred
>::type proj_type;
static const bool is_found = srs::spar::detail::tuples_is_found<proj_type>::value;
static const bool is_found = geometry::tuples::is_found<proj_type>::value;
BOOST_MPL_ASSERT_MSG((is_found), PROJECTION_NOT_NAMED, (params_type));
@ -227,7 +227,7 @@ template
<
typename Params,
bool Vertical,
int UnitsI = srs::spar::detail::tuples_find_index_if
int UnitsI = geometry::tuples::find_index_if
<
Params,
boost::mpl::if_c
@ -237,7 +237,7 @@ template
srs::spar::detail::is_param_tr<srs::spar::detail::units_traits>
>::type::template pred
>::value,
int ToMeterI = srs::spar::detail::tuples_find_index_if
int ToMeterI = geometry::tuples::find_index_if
<
Params,
boost::mpl::if_c
@ -391,7 +391,7 @@ inline void pj_init_pm(srs::dpar::parameters<T> const& params, T& val)
template
<
typename Params,
int I = srs::spar::detail::tuples_find_index_if
int I = geometry::tuples::find_index_if
<
Params,
srs::spar::detail::is_param_tr<srs::spar::detail::pm_traits>::pred

View File

@ -3,8 +3,8 @@
// Copyright (c) 2008-2012 Barend Gehrels, Amsterdam, the Netherlands.
// This file was modified by Oracle on 2017, 2018.
// Modifications copyright (c) 2017-2018, Oracle and/or its affiliates.
// This file was modified by Oracle on 2017, 2018, 2019.
// Modifications copyright (c) 2017-2019, Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
// Use, modification and distribution is subject to the Boost Software License,
@ -134,9 +134,9 @@ inline bool pj_param_exists(Params const& params, Name const& name)
template <typename Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
{
return srs::spar::detail::tuples_is_found
return geometry::tuples::is_found
<
typename srs::spar::detail::tuples_find_if
typename geometry::tuples::find_if
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param<Param>::template pred
@ -147,9 +147,9 @@ inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DET
template <template <typename> class Param, BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX>
inline bool pj_param_exists(srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> const& )
{
return srs::spar::detail::tuples_is_found
return geometry::tuples::is_found
<
typename srs::spar::detail::tuples_find_if
typename geometry::tuples::find_if
<
srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>,
srs::spar::detail::is_param_t<Param>::template pred
@ -281,7 +281,7 @@ template
<
typename Params,
template <typename> class IsSamePred,
int I = srs::spar::detail::tuples_find_index_if<Params, IsSamePred>::value,
int I = geometry::tuples::find_index_if<Params, IsSamePred>::value,
int N = boost::tuples::length<Params>::value
>
struct _pj_param_x_static

View File

@ -506,7 +506,7 @@ namespace projections
<
boost::is_same
<
typename srs::spar::detail::tuples_find_if
typename geometry::tuples::find_if
<
BGP,
//srs::par4::detail::is_guam

View File

@ -136,13 +136,13 @@ namespace projections
/* get name of projection to be translated */
typedef srs::spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX> params_type;
typedef typename srs::spar::detail::tuples_find_if
typedef typename geometry::tuples::find_if
<
params_type,
srs::spar::detail::is_param_t<srs::spar::o_proj>::pred
>::type o_proj_type;
static const bool is_found = srs::spar::detail::tuples_is_found<o_proj_type>::value;
static const bool is_found = geometry::tuples::is_found<o_proj_type>::value;
BOOST_MPL_ASSERT_MSG((is_found), NO_ROTATION_PROJ, (params_type));
typedef typename o_proj_type::type proj_type;

View File

@ -1,6 +1,6 @@
// Boost.Geometry
// Copyright (c) 2017-2018, Oracle and/or its affiliates.
// Copyright (c) 2017-2019, 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,
@ -22,8 +22,7 @@
#include <boost/geometry/srs/sphere.hpp>
#include <boost/geometry/srs/spheroid.hpp>
// TODO: move this functionality
#include <boost/geometry/index/detail/tuples.hpp>
#include <boost/geometry/util/tuples.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/if.hpp>
@ -31,9 +30,7 @@
#include <boost/mpl/not.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/variant/variant.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/is_void.hpp>
#include <string>
#include <vector>
@ -214,7 +211,7 @@ struct add_parameter
// NOTE: parameters has to be convertible to tuples::cons
template <BOOST_GEOMETRY_PROJECTIONS_DETAIL_TYPENAME_PX, typename Parameter>
struct add_parameter<spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>, Parameter>
: index::detail::tuples::push_back
: geometry::tuples::push_back
<
typename detail::map_params_to_cons<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>::type,
Parameter
@ -223,7 +220,7 @@ struct add_parameter<spar::parameters<BOOST_GEOMETRY_PROJECTIONS_DETAIL_PX>, Par
template <typename Head, typename Tail, typename Parameter>
struct add_parameter<boost::tuples::cons<Head, Tail>, Parameter>
: index::detail::tuples::push_back
: geometry::tuples::push_back
<
boost::tuples::cons<Head, Tail>,
Parameter
@ -1013,73 +1010,6 @@ BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ind_ft)
BOOST_GEOMETRY_PROJECTIONS_DETAIL_REGISTER_UNITS(units_ind_ch)
template
<
typename Tuple,
template <typename> class IsSamePred,
int I = 0,
int N = boost::tuples::length<Tuple>::value
>
struct tuples_find_index_if
: boost::mpl::if_c
<
IsSamePred<typename boost::tuples::element<I, Tuple>::type>::value,
boost::integral_constant<int, I>,
typename tuples_find_index_if<Tuple, IsSamePred, I+1, N>::type
>::type
{};
template
<
typename Tuple,
template <typename> class IsSamePred,
int N
>
struct tuples_find_index_if<Tuple, IsSamePred, N, N>
: boost::integral_constant<int, N>
{};
template
<
typename Tuple,
template <typename> class IsSamePred,
int I = tuples_find_index_if<Tuple, IsSamePred>::value,
int N = boost::tuples::length<Tuple>::value
>
struct tuples_find_if
: boost::tuples::element<I, Tuple>
{};
template
<
typename Tuple,
template <typename> class IsSamePred,
int N
>
struct tuples_find_if<Tuple, IsSamePred, N, N>
{
typedef boost::tuples::null_type type;
};
template <typename T>
struct tuples_is_found
: boost::mpl::not_<boost::is_same<T, boost::tuples::null_type> >
{};
template <typename T>
struct tuples_is_not_found
: boost::is_same<T, boost::tuples::null_type>
{};
template <typename Tuple, template <typename> class IsSamePred>
struct tuples_exists_if
: tuples_is_found
<
typename tuples_find_if<Tuple, IsSamePred>::type
>
{};
template <typename T, template <typename> class Param>
struct is_same_t : boost::false_type {};
template <typename T, template <typename> class Param>
@ -1140,13 +1070,13 @@ struct is_param_tr
template <typename Tuple>
struct pick_proj_tag
{
typedef typename tuples_find_if
typedef typename geometry::tuples::find_if
<
Tuple,
is_param_tr<proj_traits>::pred
>::type proj_type;
static const bool is_found = tuples_is_found<proj_type>::value;
static const bool is_found = geometry::tuples::is_found<proj_type>::value;
BOOST_MPL_ASSERT_MSG((is_found), PROJECTION_NOT_NAMED, (Tuple));
@ -1157,13 +1087,13 @@ struct pick_proj_tag
template <typename Tuple>
struct pick_o_proj_tag
{
typedef typename tuples_find_if
typedef typename geometry::tuples::find_if
<
Tuple,
is_param_t<o_proj>::pred
>::type o_proj_type;
static const bool is_found = tuples_is_found<o_proj_type>::value;
static const bool is_found = geometry::tuples::is_found<o_proj_type>::value;
BOOST_MPL_ASSERT_MSG((is_found), NO_O_PROJ_PARAMETER, (Tuple));

View File

@ -0,0 +1,394 @@
// Boost.Geometry Index
//
// Copyright (c) 2011-2013 Adam Wulkiewicz, Lodz, Poland.
//
// This file was modified by Oracle on 2019, 2020.
// Modifications copyright (c) 2019-2020 Oracle and/or its affiliates.
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
//
// Use, modification and distribution is subject to the Boost Software License,
// Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_GEOMETRY_UTIL_TUPLES_HPP
#define BOOST_GEOMETRY_UTIL_TUPLES_HPP
#include <boost/geometry/core/config.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/not.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/integral_constant.hpp>
#include <boost/type_traits/is_same.hpp>
#include <utility>
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
#include <tuple>
#endif // BOOST_GEOMETRY_CXX11_TUPLE
namespace boost { namespace geometry { namespace tuples {
using boost::tuples::null_type;
template <int I, typename Tuple>
struct element
: boost::tuples::element<I, Tuple>
{};
template <typename Tuple>
struct size
: boost::tuples::length<Tuple>
{};
template <int I, typename HT, typename TT>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
>::non_const_type
get(boost::tuples::cons<HT, TT> & tup)
{
return boost::tuples::get<I>(tup);
}
template <int I, typename HT, typename TT>
inline typename boost::tuples::access_traits
<
typename boost::tuples::element<I, boost::tuples::cons<HT, TT> >::type
>::const_type
get(boost::tuples::cons<HT, TT> const& tup)
{
return boost::tuples::get<I>(tup);
}
template <int I, typename F, typename S>
struct element<I, std::pair<F, S> >
{};
template <typename F, typename S>
struct element<0, std::pair<F, S> >
{
typedef F type;
};
template <typename F, typename S>
struct element<1, std::pair<F, S> >
{
typedef S type;
};
template <typename F, typename S>
struct size<std::pair<F, S> >
: boost::integral_constant<int, 2>
{};
template <int I, typename Pair>
struct get_pair;
template <typename F, typename S>
struct get_pair<0, std::pair<F, S> >
{
typedef F type;
static inline F& apply(std::pair<F, S> & p)
{
return p.first;
}
static inline F const& apply(std::pair<F, S> const& p)
{
return p.first;
}
};
template <typename F, typename S>
struct get_pair<1, std::pair<F, S> >
{
typedef S type;
static inline S& apply(std::pair<F, S> & p)
{
return p.second;
}
static inline S const& apply(std::pair<F, S> const& p)
{
return p.second;
}
};
template <int I, typename F, typename S>
inline typename get_pair<I, std::pair<F, S> >::type&
get(std::pair<F, S> & p)
{
return get_pair<I, std::pair<F, S> >::apply(p);
}
template <int I, typename F, typename S>
inline typename get_pair<I, std::pair<F, S> >::type const&
get(std::pair<F, S> const& p)
{
return get_pair<I, std::pair<F, S> >::apply(p);
}
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
template <int I, typename ...Ts>
struct element<I, std::tuple<Ts...> >
: std::tuple_element<I, std::tuple<Ts...> >
{};
template <typename ...Ts>
struct size<std::tuple<Ts...> >
: std::tuple_size<std::tuple<Ts...> >
{};
template <int I, typename ...Ts>
inline typename std::tuple_element<I, std::tuple<Ts...> >::type&
get(std::tuple<Ts...> & tup)
{
return std::get<I>(tup);
}
template <int I, typename ...Ts>
inline typename std::tuple_element<I, std::tuple<Ts...> >::type const&
get(std::tuple<Ts...> const& tup)
{
return std::get<I>(tup);
}
#endif // BOOST_GEOMETRY_CXX11_TUPLE
// find_index_if
// Searches for the index of an element for which UnaryPredicate returns true
// If such element is not found the result is N
template
<
typename Tuple,
template <typename> class UnaryPred,
int I = 0,
int N = size<Tuple>::value
>
struct find_index_if
: boost::mpl::if_c
<
UnaryPred<typename element<I, Tuple>::type>::value,
boost::integral_constant<int, I>,
typename find_index_if<Tuple, UnaryPred, I+1, N>::type
>::type
{};
template
<
typename Tuple,
template <typename> class UnaryPred,
int N
>
struct find_index_if<Tuple, UnaryPred, N, N>
: boost::integral_constant<int, N>
{};
// find_if
// Searches for an element for which UnaryPredicate returns true
// If such element is not found the result is boost::tuples::null_type
template
<
typename Tuple,
template <typename> class UnaryPred,
int I = 0,
int N = size<Tuple>::value
>
struct find_if
: boost::mpl::if_c
<
UnaryPred<typename element<I, Tuple>::type>::value,
element<I, Tuple>,
find_if<Tuple, UnaryPred, I+1, N>
>::type
{};
template
<
typename Tuple,
template <typename> class UnaryPred,
int N
>
struct find_if<Tuple, UnaryPred, N, N>
{
typedef boost::tuples::null_type type;
};
// is_found
// Returns true if a type T (the result of find_if) was found.
template <typename T>
struct is_found
: boost::mpl::not_<boost::is_same<T, boost::tuples::null_type> >
{};
// is_not_found
// Returns true if a type T (the result of find_if) was not found.
template <typename T>
struct is_not_found
: boost::is_same<T, boost::tuples::null_type>
{};
// exists_if
// Returns true if search for element meeting UnaryPred can be found.
template <typename Tuple, template <typename> class UnaryPred>
struct exists_if
: is_found<typename find_if<Tuple, UnaryPred>::type>
{};
// push_back
// A utility used to create a type/object of a Tuple containing
// all types/objects stored in another Tuple plus additional one.
template <typename Tuple,
typename T,
size_t I = 0,
size_t N = size<Tuple>::value>
struct push_back_bt
{
typedef
boost::tuples::cons<
typename element<I, Tuple>::type,
typename push_back_bt<Tuple, T, I+1, N>::type
> type;
static type apply(Tuple const& tup, T const& t)
{
return
type(
geometry::tuples::get<I>(tup),
push_back_bt<Tuple, T, I+1, N>::apply(tup, t)
);
}
};
template <typename Tuple, typename T, size_t N>
struct push_back_bt<Tuple, T, N, N>
{
typedef boost::tuples::cons<T, boost::tuples::null_type> type;
static type apply(Tuple const&, T const& t)
{
return type(t, boost::tuples::null_type());
}
};
template <typename Tuple, typename T>
struct push_back
: push_back_bt<Tuple, T>
{};
template <typename F, typename S, typename T>
struct push_back<std::pair<F, S>, T>
{
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
typedef std::tuple<F, S, T> type;
#else
typedef boost::tuple<F, S, T> type;
#endif // BOOST_GEOMETRY_CXX11_TUPLE
static type apply(std::pair<F, S> const& p, T const& t)
{
return type(p.first, p.second, t);
}
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
static type apply(std::pair<F, S> && p, T const& t)
{
return type(std::move(p.first), std::move(p.second), t);
}
static type apply(std::pair<F, S> && p, T && t)
{
return type(std::move(p.first), std::move(p.second), std::move(t));
}
#endif
#endif // BOOST_GEOMETRY_CXX11_TUPLE
};
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
// NOTE: In C++14 std::integer_sequence and std::make_integer_sequence could be used
template <int... Is>
struct int_sequence {};
template <int N, int ...Is>
struct make_int_sequence
{
typedef typename make_int_sequence<N - 1, N - 1, Is...>::type type;
};
template <int ...Is>
struct make_int_sequence<0, Is...>
{
typedef int_sequence<Is...> type;
};
template <typename Is, typename Tuple, typename T>
struct push_back_st;
template <int ...Is, typename ...Ts, typename T>
struct push_back_st<int_sequence<Is...>, std::tuple<Ts...>, T>
{
typedef std::tuple<Ts..., T> type;
static type apply(std::tuple<Ts...> const& tup, T const& t)
{
return type(std::get<Is>(tup)..., t);
}
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
static type apply(std::tuple<Ts...> && tup, T const& t)
{
return type(std::move(std::get<Is>(tup))..., t);
}
static type apply(std::tuple<Ts...> && tup, T && t)
{
return type(std::move(std::get<Is>(tup))..., std::move(t));
}
#endif
};
template <typename ...Ts, typename T>
struct push_back<std::tuple<Ts...>, T>
: push_back_st
<
typename make_int_sequence<sizeof...(Ts)>::type,
std::tuple<Ts...>,
T
>
{};
#endif // BOOST_GEOMETRY_CXX11_TUPLE
}}} // namespace boost::geometry::tuples
#endif // BOOST_GEOMETRY_UTIL_TUPLES_HPP

View File

@ -18,6 +18,7 @@ test-suite boost-geometry-algorithms-detail
[ run as_range.cpp : : : : algorithms_as_range ]
[ run calculate_point_order.cpp : : : : algorithms_calculate_point_order ]
[ run partition.cpp : : : : algorithms_partition ]
[ run tupled_output.cpp : : : : algorithms_tupled_output ]
;
build-project sections ;

View File

@ -0,0 +1,116 @@
// Boost.Geometry
// Unit Test
// Copyright (c) 2019 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)
#include <geometry_test_common.hpp>
#include <boost/geometry/algorithms/detail/tupled_output.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/util/range.hpp>
namespace bgd = boost::geometry::detail;
namespace bgt = boost::geometry::tuples;
namespace bgr = boost::geometry::range;
template <typename MultiPoint>
void add_points(MultiPoint & mp)
{
typedef typename bg::point_type<MultiPoint>::type point_type;
bg::range::push_back(mp, point_type(1, 2));
bg::range::push_back(mp, point_type(2, 3));
bg::range::push_back(mp, point_type(3, 4));
}
template <typename TupleM, typename TupleS>
void test_range_values()
{
typedef typename bgd::tupled_range_values<TupleM>::type tuple_s;
BOOST_CHECK_EQUAL((boost::is_same<tuple_s, TupleS>::value), true);
}
template <typename TupleM, typename TupleBI>
void test_back_inserters()
{
typedef typename bgd::tupled_back_inserters<TupleM>::type tuple_bi;
BOOST_CHECK_EQUAL((boost::is_same<tuple_bi, TupleBI>::value), true);
TupleM tup;
bgd::tupled_back_inserters<TupleM>::apply(tup);
}
template <typename TuplePoLs, typename TupleLsMPt>
void test_all()
{
BOOST_CHECK_EQUAL((bgd::is_tupled_output<TuplePoLs>::value), false);
BOOST_CHECK_EQUAL((bgd::is_tupled_output<TupleLsMPt>::value), true);
BOOST_CHECK_EQUAL((bgd::tupled_output_has<TuplePoLs, bg::multi_point_tag>::value), false);
BOOST_CHECK_EQUAL((bgd::tupled_output_has<TupleLsMPt, bg::multi_point_tag>::value), true);
BOOST_CHECK_EQUAL((bgd::tupled_output_has<TuplePoLs, bg::multi_polygon_tag>::value), false);
BOOST_CHECK_EQUAL((bgd::tupled_output_has<TupleLsMPt, bg::multi_polygon_tag>::value), false);
TupleLsMPt tup;
add_points(bgd::tupled_output_get<bg::multi_point_tag>(tup));
BOOST_CHECK_EQUAL((boost::size(bgt::get<1>(tup))), 3u);
}
int test_main(int, char* [])
{
typedef bg::model::point<double, 2, bg::cs::cartesian> point;
typedef bg::model::linestring<point> linestring;
typedef bg::model::polygon<point> polygon;
typedef bg::model::multi_point<point> multi_point;
typedef bg::model::multi_linestring<linestring> multi_linestring;
//typedef bg::model::multi_polygon<polygon> multi_polygon;
BOOST_CHECK_EQUAL((bgd::is_range<int>::value), false);
BOOST_CHECK_EQUAL((bgd::is_range<linestring>::value), true);
BOOST_CHECK_EQUAL((bgd::is_range<multi_point>::value), true);
BOOST_CHECK_EQUAL((bgd::is_tupled_output_element<int>::value), false);
BOOST_CHECK_EQUAL((bgd::is_tupled_output_element<linestring>::value), false);
BOOST_CHECK_EQUAL((bgd::is_tupled_output_element<multi_point>::value), true);
test_all<boost::tuple<polygon, linestring>, boost::tuple<linestring, multi_point> >();
test_all<std::pair<polygon, linestring>, std::pair<linestring, multi_point> >();
test_range_values<boost::tuple<multi_linestring, multi_point>,
boost::tuples::cons<linestring,
boost::tuples::cons<point,
boost::tuples::null_type> > >();
test_range_values<std::pair<multi_linestring, multi_point>,
std::pair<linestring, point> >();
test_back_inserters<boost::tuple<multi_linestring, multi_point>,
boost::tuples::cons<bgr::back_insert_iterator<multi_linestring>,
boost::tuples::cons<bgr::back_insert_iterator<multi_point>,
boost::tuples::null_type> > >();
test_back_inserters<std::pair<multi_linestring, multi_point>,
std::pair<bgr::back_insert_iterator<multi_linestring>,
bgr::back_insert_iterator<multi_point> > >();
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
test_all<std::tuple<polygon, linestring>, std::tuple<linestring, multi_point> >();
test_range_values<std::tuple<multi_linestring, multi_point>,
std::tuple<linestring, point> >();
test_back_inserters<std::tuple<multi_linestring, multi_point>,
std::tuple<bgr::back_insert_iterator<multi_linestring>,
bgr::back_insert_iterator<multi_point> > >();
#endif
return 0;
}

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 2014, 2015, 2019.
# Modifications copyright (c) 2014-2019, Oracle and/or its affiliates.
# This file was modified by Oracle on 2014, 2015, 2019, 2020.
# Modifications copyright (c) 2014-2020, 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
@ -21,6 +21,7 @@ test-suite boost-geometry-algorithms-difference
[ run difference_l_a_sph.cpp : : : : algorithms_difference_l_a_sph ]
[ run difference_linear_linear.cpp : : : : algorithms_difference_linear_linear ]
[ run difference_areal_linear.cpp : : : : algorithms_difference_areal_linear ]
[ run difference_pl_a.cpp : : : : algorithms_difference_pl_a ]
[ run difference_pl_l.cpp : : : : algorithms_difference_pl_l ]
[ run difference_pl_pl.cpp : : : : algorithms_difference_pl_pl ]
[ run difference_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE

View File

@ -0,0 +1,212 @@
// Boost.Geometry
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_TEST_MODULE
#define BOOST_TEST_MODULE test_difference_pointlike_areal
#endif
#include <iostream>
#include <algorithm>
#include <boost/test/included/unit_test.hpp>
#include "../test_set_ops_pointlike.hpp"
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/ring.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/multi_point.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
typedef bg::model::point<double, 2, bg::cs::cartesian> Pt;
typedef bg::model::ring<Pt> R;
typedef bg::model::polygon<Pt> Po;
typedef bg::model::multi_point<Pt> MPt;
typedef bg::model::multi_polygon<Po> MPo;
BOOST_AUTO_TEST_CASE( test_difference_point_ring )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, R, MPt, bg::overlay_difference
> tester;
tester::apply(
"pt-r-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-r-02",
from_wkt<Pt>("POINT(3 5)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-r-03",
from_wkt<Pt>("POINT(6 3)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(6 3)")
);
}
BOOST_AUTO_TEST_CASE( test_difference_point_polygon )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, Po, MPt, bg::overlay_difference
> tester;
tester::apply(
"pt-po-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-po-02",
from_wkt<Pt>("POINT(4 4)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-po-03",
from_wkt<Pt>("POINT(3 3)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT(3 3)")
);
tester::apply(
"pt-po-04",
from_wkt<Pt>("POINT(6 0)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT(6 0)")
);
}
BOOST_AUTO_TEST_CASE( test_difference_point_multipolygon )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, MPo, MPt, bg::overlay_difference
> tester;
tester::apply(
"pt-mpo-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-mpo-02",
from_wkt<Pt>("POINT(3 3)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT(3 3)")
);
tester::apply(
"pt-mpo-03",
from_wkt<Pt>("POINT(4 4)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-mpo-04",
from_wkt<Pt>("POINT(5 5)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-mpo-05",
from_wkt<Pt>("POINT(6 6)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT()")
);
}
BOOST_AUTO_TEST_CASE( test_difference_multipoint_ring )
{
typedef test_set_op_of_pointlike_geometries
<
MPt, R, MPt, bg::overlay_difference
> tester;
tester::apply(
"mpt-r-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 5 5, 6 6)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(6 6)")
);
tester::apply(
"mpt-r-02",
from_wkt<MPt>("MULTIPOINT(3 5, 5 3, 3 0, 0 3, 3 6, 6 3, 3 -1, -1 3)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(3 6, 6 3, 3 -1, -1 3)")
);
}
BOOST_AUTO_TEST_CASE( test_difference_multipoint_polygon )
{
typedef test_set_op_of_pointlike_geometries
<
MPt, Po, MPt, bg::overlay_difference
> tester;
tester::apply(
"mpt-po-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 4 4, 5 5, 6 6)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT(1 1, 6 6)")
);
tester::apply(
"mpt-po-02",
from_wkt<MPt>("MULTIPOINT(3 5, 5 3, 3 0, 0 3, 3 6, 6 3, 3 -1, -1 3, 2 0.5, 0.5 2, 2 4, 4 2)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))"),
from_wkt<MPt>("MULTIPOINT(3 6, 6 3, 3 -1, -1 3)")
);
}
BOOST_AUTO_TEST_CASE(test_difference_multipoint_multipolygon)
{
typedef test_set_op_of_pointlike_geometries
<
MPt, MPo, MPt, bg::overlay_difference
> tester;
tester::apply(
"mpt-mpo-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 4 4, 5 5, 6 6)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT(1 1)")
);
tester::apply(
"mpt-mpo-02",
from_wkt<MPt>("MULTIPOINT(3 5, 5 3, 3 0, 0 3, 3 6, 6 3, 3 -1, -1 3, 2 0.5, 0.5 2, 2 4, 4 2, 6 5, 6 7, 5 6, 7 6)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((5 5, 5 7, 7 7, 7 5, 5 5)))"),
from_wkt<MPt>("MULTIPOINT(3 6, 6 3, 3 -1, -1 3)")
);
}

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 2014, 2015.
# Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
# This file was modified by Oracle on 2014, 2015, 2020.
# Modifications copyright (c) 2014-2020, 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
@ -22,6 +22,8 @@ test-suite boost-geometry-algorithms-intersection
[ run intersection_linear_linear.cpp : : : : algorithms_intersection_linear_linear ]
[ run intersection_multi.cpp : : : <define>BOOST_GEOMETRY_TEST_ONLY_ONE_TYPE
: algorithms_intersection_multi ]
[ run intersection_pl_a.cpp : : : : algorithms_intersection_pl_a ]
[ run intersection_pl_l.cpp : : : : algorithms_intersection_pl_l ]
[ run intersection_pl_pl.cpp : : : : algorithms_intersection_pl_pl ]
[ run intersection_tupled.cpp : : : : algorithms_intersection_tupled ]
;

View File

@ -0,0 +1,190 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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_TEST_MODULE
#define BOOST_TEST_MODULE test_intersection_pointlike_areal
#endif
#include <iostream>
#include <algorithm>
#include <boost/test/included/unit_test.hpp>
#include "../test_set_ops_pointlike.hpp"
#include <boost/geometry/geometries/multi_point.hpp>
#include <boost/geometry/geometries/multi_polygon.hpp>
#include <boost/geometry/geometries/point.hpp>
#include <boost/geometry/geometries/polygon.hpp>
#include <boost/geometry/geometries/ring.hpp>
typedef bg::model::point<double, 2, bg::cs::cartesian> Pt;
typedef bg::model::polygon<Pt> Po;
typedef bg::model::ring<Pt> R;
typedef bg::model::multi_point<Pt> MPt;
typedef bg::model::multi_polygon<Po> MPo;
BOOST_AUTO_TEST_CASE( test_intersection_point_ring )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, R, MPt, bg::overlay_intersection
> tester;
tester::apply(
"pt-r-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(0 0)")
);
tester::apply(
"pt-r-02",
from_wkt<Pt>("POINT(1 1)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(1 1)")
);
tester::apply(
"pt-r-03",
from_wkt<Pt>("POINT(6 6)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
}
BOOST_AUTO_TEST_CASE( test_intersection_point_polygon )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, Po, MPt, bg::overlay_intersection
> tester;
tester::apply(
"pt-po-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT(0 0)")
);
tester::apply(
"pt-po-02",
from_wkt<Pt>("POINT(1 1)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
tester::apply(
"pt-po-03",
from_wkt<Pt>("POINT(3 3)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT(3 3)")
);
tester::apply(
"pt-po-04",
from_wkt<Pt>("POINT(4 4)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT(4 4)")
);
tester::apply(
"pt-po-05",
from_wkt<Pt>("POINT(6 6)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT()")
);
}
BOOST_AUTO_TEST_CASE( test_intersection_point_multipolygon )
{
typedef test_set_op_of_pointlike_geometries
<
Pt, MPo, MPt, bg::overlay_intersection
> tester;
tester::apply(
"pt-mpo-01",
from_wkt<Pt>("POINT(0 0)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"),
from_wkt<MPt>("MULTIPOINT(0 0)")
);
tester::apply(
"pt-mpo-02",
from_wkt<Pt>("POINT(1 1)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"),
from_wkt<MPt>("MULTIPOINT(1 1)")
);
tester::apply(
"pt-mpo-03",
from_wkt<Pt>("POINT(2 2)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"),
from_wkt<MPt>("MULTIPOINT(2 2)")
);
tester::apply(
"pt-mpo-04",
from_wkt<Pt>("POINT(3 3)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"),
from_wkt<MPt>("MULTIPOINT()")
);
}
BOOST_AUTO_TEST_CASE( test_intersection_multipoint_ring )
{
typedef test_set_op_of_pointlike_geometries
<
MPt, R, MPt, bg::overlay_intersection
> tester;
tester::apply(
"mpt-r-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 6 6)"),
from_wkt<R>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))"),
from_wkt<MPt>("MULTIPOINT(0 0, 1 1)")
);
}
BOOST_AUTO_TEST_CASE( test_intersection_multipoint_polygon )
{
typedef test_set_op_of_pointlike_geometries
<
MPt, Po, MPt, bg::overlay_intersection
> tester;
tester::apply(
"mpt-po-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 3 3, 4 4, 6 6)"),
from_wkt<Po>("POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 3 1, 3 3, 1 3, 0 0))"),
from_wkt<MPt>("MULTIPOINT(0 0, 3 3, 4 4)")
);
}
BOOST_AUTO_TEST_CASE( test_intersection_multipoint_multipolygon )
{
typedef test_set_op_of_pointlike_geometries
<
MPt, MPo, MPt, bg::overlay_intersection
> tester;
tester::apply(
"mpt-mpo-01",
from_wkt<MPt>("MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)"),
from_wkt<MPo>("MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))"),
// NOTE: This is caused by the fact that intersection(MPt, MPt)
// used internally does not filter duplicates out.
from_wkt<MPt>("MULTIPOINT(0 0, 0 0, 1 1, 2 2, 4 4, 5 5)")
);
}

View File

@ -0,0 +1,365 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2020, Oracle and/or its affiliates.
// 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
#include <geometry_test_common.hpp>
#include <boost/geometry/algorithms/correct.hpp>
#include <boost/geometry/algorithms/equals.hpp>
#include <boost/geometry/algorithms/intersection.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry/io/wkt/wkt.hpp>
#include <boost/geometry/strategies/cartesian/area.hpp>
#include <boost/geometry/strategies/cartesian/intersection.hpp>
#include <boost/geometry/strategies/cartesian/point_in_poly_winding.hpp>
#include <boost/geometry/strategies/cartesian/point_in_point.hpp>
#include <boost/tuple/tuple.hpp>
typedef bg::model::point<double, 2, bg::cs::cartesian> Pt;
typedef bg::model::linestring<Pt> Ls;
typedef bg::model::polygon<Pt> Po;
typedef bg::model::ring<Pt> R;
typedef bg::model::multi_point<Pt> MPt;
typedef bg::model::multi_linestring<Ls> MLs;
typedef bg::model::multi_polygon<Po> MPo;
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
#include <tuple>
#endif
template <typename G>
inline void check(std::string const& wkt1,
std::string const& wkt2,
G const& g,
std::string const& expected)
{
G expect;
bg::read_wkt(expected, expect);
bg::correct(expect);
if (! boost::empty(g) || ! boost::empty(expect))
{
BOOST_CHECK_MESSAGE(
// Commented out becasue the output in reversed case may be slightly different
// e.g. different number of duplicated points in MultiPoint
//boost::size(g) == boost::size(expect) &&
bg::equals(g, expect),
wkt1 << " x " << wkt2 << " -> " << bg::wkt(g)
<< " different than expected: " << expected
);
}
}
inline void check(std::string const& wkt1,
std::string const& wkt2,
boost::tuple<MPt, MLs, MPo> const& tup,
std::string const& out_p_str,
std::string const& out_l_str,
std::string const& out_a_str)
{
check(wkt1, wkt2, boost::get<0>(tup), out_p_str);
check(wkt1, wkt2, boost::get<1>(tup), out_l_str);
check(wkt1, wkt2, boost::get<2>(tup), out_a_str);
}
inline void check(std::string const& wkt1,
std::string const& wkt2,
std::pair<MPt, MLs> const& pair,
std::string const& out_p_str,
std::string const& out_l_str,
std::string const& )
{
check(wkt1, wkt2, pair.first, out_p_str);
check(wkt1, wkt2, pair.second, out_l_str);
}
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
inline void check(std::string const& wkt1,
std::string const& wkt2,
std::tuple<MPt, MLs, MPo> const& tup,
std::string const& out_p_str,
std::string const& out_l_str,
std::string const& out_a_str)
{
check(wkt1, wkt2, std::get<0>(tup), out_p_str);
check(wkt1, wkt2, std::get<1>(tup), out_l_str);
check(wkt1, wkt2, std::get<2>(tup), out_a_str);
}
#endif
template <typename In1, typename In2, typename Tup>
inline void test_one(std::string const& in1_str,
std::string const& in2_str,
std::string const& out_p_str = "MULTIPOINT()",
std::string const& out_l_str = "MULTILINESTRING()",
std::string const& out_a_str = "MULTIPOLYGON()")
{
In1 in1;
bg::read_wkt(in1_str, in1);
bg::correct(in1);
In2 in2;
bg::read_wkt(in2_str, in2);
bg::correct(in2);
{
Tup result;
bg::intersection(in1, in2, result);
check(in1_str, in2_str, result, out_p_str, out_l_str, out_a_str);
}
{
Tup result;
bg::intersection(in2, in1, result);
check(in1_str, in2_str, result, out_p_str, out_l_str, out_a_str);
}
}
template <typename Tup>
inline void test_pp()
{
test_one<Pt, Pt, Tup>(
"POINT(0 0)",
"POINT(0 0)",
"MULTIPOINT(0 0)");
test_one<Pt, MPt, Tup>(
"POINT(0 0)",
"MULTIPOINT(0 0, 1 1)",
"MULTIPOINT(0 0)");
test_one<MPt, MPt, Tup>(
"MULTIPOINT(0 0, 1 1, 2 2)",
"MULTIPOINT(1 1, 2 2, 3 3)",
"MULTIPOINT(1 1, 2 2)");
}
template <typename Tup>
inline void test_pl()
{
test_one<Pt, Ls, Tup>(
"POINT(0 0)",
"LINESTRING(0 0, 1 1)",
"MULTIPOINT(0 0)");
test_one<Pt, MLs, Tup>(
"POINT(1 1)",
"MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))",
"MULTIPOINT(1 1)");
test_one<MPt, Ls, Tup>(
"MULTIPOINT(0 0, 1 1, 2 2, 3 3)",
"LINESTRING(0 0, 1 1)",
"MULTIPOINT(0 0, 1 1)");
test_one<MPt, MLs, Tup>(
"MULTIPOINT(0 0, 1 1, 2 2, 3 3)",
"MULTILINESTRING((0 0, 1 1),(1 1, 2 2),(4 4, 5 5))",
"MULTIPOINT(0 0, 1 1, 2 2)");
}
template <typename Tup>
inline void test_pa()
{
test_one<Pt, R, Tup>(
"POINT(0 0)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"MULTIPOINT(0 0)");
test_one<Pt, Po, Tup>(
"POINT(0 0)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTIPOINT(0 0)");
test_one<Pt, MPo, Tup>(
"POINT(0 0)",
"MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))",
"MULTIPOINT(0 0)");
test_one<MPt, R, Tup>(
"MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5)");
test_one<MPt, Po, Tup>(
"MULTIPOINT(0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTIPOINT(0 0, 4 4, 5 5)");
test_one<MPt, MPo, Tup>(
"MULTIPOINT(0 0, 0 0, 1 1, 2 2, 3 3, 4 4, 5 5, 6 6)",
"MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))",
"MULTIPOINT(0 0, 0 0, 1 1, 2 2, 4 4, 5 5)"); // one (0 0) could be filtered out
}
template <typename Tup>
inline void test_ll()
{
test_one<Ls, Ls, Tup>(
"LINESTRING(0 0, 1 0, 2 1, 3 0)",
"LINESTRING(0 0, 1 0, 3 0, 4 0)",
"MULTIPOINT(3 0)",
"MULTILINESTRING((0 0, 1 0))");
test_one<Ls, MLs, Tup>(
"LINESTRING(0 0, 1 0, 2 1, 3 0)",
"MULTILINESTRING((0 0, 1 0, 3 0),(2 1, 2 2))",
"MULTIPOINT(3 0, 2 1)",
"MULTILINESTRING((0 0, 1 0))");
test_one<MLs, MLs, Tup>(
"MULTILINESTRING((0 0, 1 0, 2 1),(2 1, 3 0))",
"MULTILINESTRING((0 0, 1 0, 3 0),(2 1, 2 2))",
"MULTIPOINT(3 0, 2 1, 2 1)", // (2 1) could be filtered out
"MULTILINESTRING((0 0, 1 0))");
test_one<Ls, Ls, Tup>(
"LINESTRING(0 0, 0 5, 5 5, 5 0, 0 0)",
"LINESTRING(0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0)",
"MULTIPOINT(4 5, 5 1, 0 0)", // (0 0) could be filtered out
"MULTILINESTRING((0 0, 0 1), (5 5, 5 2), (5 0, 0 0))");
test_one<MLs, MLs, Tup>(
"MULTILINESTRING((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTILINESTRING((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))",
// all (0 0) could be filtered out
"MULTIPOINT(0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0)",
"MULTILINESTRING((5 4,5 1),(0 0,4 1),(4 4,1 4,0 0))");
}
template <typename Tup>
inline void test_la()
{
test_one<Ls, R, Tup>(
"LINESTRING(0 2, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5, 3 3, 2 5, 2 9, 0 5)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"MULTIPOINT(0 2, 5 2, 5 5, 0 5)",
"MULTILINESTRING((0 0, 5 0),(4 5, 3 3, 2 5))");
test_one<Ls, Po, Tup>(
"LINESTRING(1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9, 4 5, 3 3, 2 5, 2 9, 0 5)",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTIPOINT(5 2, 5 5, 0 5)",
"MULTILINESTRING((1 4, 0 3.4)(0 0, 5 0),(4 5, 3.5 4),(2.5 4, 2 5))");
test_one<MLs, R, Tup>(
"MULTILINESTRING((0 2, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 3 3, 2 5, 2 9, 0 5))",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"MULTIPOINT(0 2, 5 2, 5 5, 0 5)",
"MULTILINESTRING((0 0, 5 0),(4 5, 3 3, 2 5))");
test_one<MLs, Po, Tup>(
"MULTILINESTRING((1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 3 3, 2 5, 2 9, 0 5))",
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTIPOINT(5 2, 5 5, 0 5)",
"MULTILINESTRING((1 4, 0 3.4)(0 0, 5 0),(4 5, 3.5 4),(2.5 4, 2 5))");
test_one<MLs, MPo, Tup>(
"MULTILINESTRING((1 4, -4 1, 0 0, 5 0, 9 1, 5 2, 9 3, 5 5, 4 9), (4 9, 4 5, 4 4, 2 2, 2 5, 1 9, 0 5))",
"MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),((0 0, 1 2, 2 2, 2 1, 0 0)))",
"MULTIPOINT(5 2, 5 5, 2 2, 0 5)",
"MULTILINESTRING((1 4, 0 3.4)(0 0, 5 0),(4 5, 4 4),(2 4, 2 5))");
test_one<Ls, R, Tup>(
"LINESTRING(0 0, 0 5, 5 5, 5 0, 0 0)",
"POLYGON((0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0))",
"MULTIPOINT(4 5)",
"MULTILINESTRING((0 0, 0 1), (5 5, 5 2), (5 1, 5 0, 0 0))");
test_one<MLs, Po, Tup>(
"MULTILINESTRING((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"POLYGON((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))",
"MULTIPOINT(0 0)", // (0 0) could be filtered out
"MULTILINESTRING((5 4, 5 1),(0 0, 4 1, 4 4, 1 4, 0 0))");
}
template <typename Tup>
inline void test_aa()
{
test_one<R, R, Tup>(
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"POLYGON((0 0, 0 1, 6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 0, 0 0))",
"MULTIPOINT(4 5)",
"MULTILINESTRING((5 2, 5 5))",
"MULTIPOLYGON(((0 0, 0 1, 5 1, 5 0, 0 0)))");
test_one<R, MPo, Tup>(
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))",
"MULTIPOLYGON(((0 0, 0 1, 6 1, 6 0, 0 0)),"
"((6 1, 5 2, 5 5, 5 6, 4 5, 4 7, 7 7, 7 1, 6 1)))",
"MULTIPOINT(4 5)",
"MULTILINESTRING((5 2, 5 5))",
"MULTIPOLYGON(((0 0, 0 1, 5 1, 5 0, 0 0)))");
test_one<Po, Po, Tup>(
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"POLYGON((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0))",
// all (0 0) could be filtered out
"MULTIPOINT(0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0)",
"MULTILINESTRING((0 0, 1 4, 4 4),(0 0, 4 1))",
"MULTIPOLYGON(((4 1, 4 4, 5 4, 5 1, 4 1)))");
test_one<Po, MPo, Tup>(
"POLYGON((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0))",
"MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0)),"
"((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))",
// all (0 0) and (5 0) could be filtered out
"MULTIPOINT(2 5, 5 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0)",
"MULTILINESTRING((0 0, 1 4, 4 4),(0 0, 4 1),(5 1, 5 0))",
"MULTIPOLYGON(((4 1, 4 4, 5 4, 5 1, 4 1)),((5 4, 4 5, 5 5, 5 4)))");
test_one<MPo, MPo, Tup>(
"MULTIPOLYGON(((0 0, 0 5, 5 5, 5 0, 0 0),(0 0, 4 1, 4 4, 1 4, 0 0)),"
"((2 6, 2 8, 8 8, 8 5, 7 5, 7 6, 2 6)))",
"MULTIPOLYGON(((0 0, 1 4, 5 4, 5 1, 4 1, 0 0),(0 0, 2 1, 2 2, 1 2, 0 0)),"
"((5 0, 5 1, 6 1, 6 4, 5 4, 3 6, 2 5, 2 7, 7 7, 7 0 5 0)))",
// all (0 0) and (5 0) could be filtered out
"MULTIPOINT(2 5, 5 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0, 0 0)",
"MULTILINESTRING((0 0, 1 4, 4 4),(0 0, 4 1),(5 1, 5 0),(7 5, 7 6))",
"MULTIPOLYGON(((4 1, 4 4, 5 4, 5 1, 4 1)),"
"((5 4, 4 5, 5 5, 5 4)),"
"((2 6, 2 7, 7 7, 7 6, 2 6)))");
}
template <typename Tup>
inline void test_pair()
{
test_pp<Tup>();
test_pl<Tup>();
test_pa<Tup>();
test_ll<Tup>();
test_la<Tup>();
}
template <typename Tup>
inline void test_tuple()
{
test_pp<Tup>();
test_pl<Tup>();
test_pa<Tup>();
test_ll<Tup>();
test_la<Tup>();
test_aa<Tup>();
}
int test_main(int, char* [])
{
test_pair<std::pair<MPt, MLs> >();
test_tuple<boost::tuple<MPt, MLs, MPo> >();
#ifdef BOOST_GEOMETRY_CXX11_TUPLE
test_tuple<std::tuple<MPt, MLs, MPo> >();
#endif
return 0;
}

View File

@ -1,12 +1,13 @@
// Boost.Geometry (aka GGL, Generic Geometry Library)
// Copyright (c) 2014-2015, Oracle and/or its affiliates.
// Copyright (c) 2014-2020, 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
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
#ifndef BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
#define BOOST_GEOMETRY_TEST_SET_OPS_POINTLIKE_HPP
@ -183,7 +184,7 @@ struct geometry_info<Point, bg::point_tag>
{
static std::size_t const topological_dimension = 0;
static inline char const* name() { return "P"; }
static inline char const* name() { return "Pt"; }
};
template <typename MultiPoint>
@ -191,7 +192,7 @@ struct geometry_info<MultiPoint, bg::multi_point_tag>
{
static std::size_t const topological_dimension = 0;
static inline char const* name() { return "MP"; }
static inline char const* name() { return "MPt"; }
};
template <typename Linestring>
@ -218,7 +219,29 @@ struct geometry_info<Segment, bg::segment_tag>
static inline char const* name() { return "S"; }
};
template <typename Ring>
struct geometry_info<Ring, bg::ring_tag>
{
static std::size_t const topological_dimension = 2;
static inline char const* name() { return "R"; }
};
template <typename Polygon>
struct geometry_info<Polygon, bg::polygon_tag>
{
static std::size_t const topological_dimension = 2;
static inline char const* name() { return "Po"; }
};
template <typename MultiPolygon>
struct geometry_info<MultiPolygon, bg::multi_polygon_tag>
{
static std::size_t const topological_dimension = 2;
static inline char const* name() { return "MPo"; }
};
//==================================================================
//==================================================================

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 2014, 2015.
# Modifications copyright (c) 2014-2015, Oracle and/or its affiliates.
# This file was modified by Oracle on 2014, 2015, 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
@ -25,5 +25,6 @@ test-suite boost-geometry-util
[ run range.cpp : : : : util_range ]
[ run rational.cpp : : : : util_rational ]
[ run select_most_precise.cpp : : : : util_select_most_precise ]
[ run tuples.cpp : : : : util_tuples ]
[ run write_dsv.cpp : : : : util_write_dsv ]
;

141
test/util/tuples.cpp Normal file
View File

@ -0,0 +1,141 @@
// Boost.Geometry
// Unit Test
// Copyright (c) 2019 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)
#include <geometry_test_common.hpp>
#include <boost/geometry/util/tuples.hpp>
namespace bt = boost::tuples;
namespace bgt = boost::geometry::tuples;
namespace bm = boost::mpl;
template <typename T>
struct is_double
: boost::is_same<T, double>
{};
template <typename T>
struct is_float
: boost::is_same<T, float>
{};
template <typename Tuple>
struct is_boost_tuple
: boost::integral_constant<bool, false>
{};
template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
struct is_boost_tuple<boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
: boost::integral_constant<bool, true>
{};
template <typename Tuple>
struct is_boost_tuples_cons
: boost::integral_constant<bool, false>
{};
template <typename HT, typename TT>
struct is_boost_tuples_cons<boost::tuples::cons<HT, TT> >
: boost::integral_constant<bool, true>
{};
template <typename Tuple>
struct is_std_pair
: boost::integral_constant<bool, false>
{};
template <typename F, typename S>
struct is_std_pair<std::pair<F, S> >
: boost::integral_constant<bool, true>
{};
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
template <typename Tuple>
struct is_std_tuple
: boost::integral_constant<bool, false>
{};
template <typename ...Ts>
struct is_std_tuple<std::tuple<Ts...> >
: boost::integral_constant<bool, true>
{};
#endif
template <typename Tuple>
void test_all()
{
typedef Tuple tuple_id;
tuple_id tup_id(1, 2.0);
BOOST_CHECK_EQUAL((bgt::get<0>(tup_id)), 1);
BOOST_CHECK_EQUAL((bgt::get<1>(tup_id)), 2.0);
BOOST_CHECK_EQUAL(int(bgt::size<tuple_id>::value), 2);
BOOST_CHECK_EQUAL((bgt::find_index_if<tuple_id, is_double>::value), 1);
BOOST_CHECK((boost::is_same<typename bgt::find_if<tuple_id, is_double>::type, double>::value));
BOOST_CHECK_EQUAL((bgt::find_index_if<tuple_id, is_float>::value), 2);
BOOST_CHECK((boost::is_same<typename bgt::find_if<tuple_id, is_float>::type, boost::tuples::null_type>::value));
typedef typename bgt::push_back<tuple_id, float>::type tuple_idf;
tuple_idf tup_idf = bgt::push_back<tuple_id, float>::apply(tup_id, 3.0f);
BOOST_CHECK_EQUAL((bgt::get<0>(tup_idf)), 1);
BOOST_CHECK_EQUAL((bgt::get<1>(tup_idf)), 2.0);
BOOST_CHECK_EQUAL((bgt::get<2>(tup_idf)), 3.0f);
BOOST_CHECK_EQUAL(int(bgt::size<tuple_idf>::value), 3);
BOOST_CHECK_EQUAL((bgt::find_index_if<tuple_idf, is_float>::value), 2);
BOOST_CHECK((boost::is_same<typename bgt::find_if<tuple_idf, is_float>::type, float>::value));
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
BOOST_CHECK((
(is_boost_tuple<tuple_id>::value && is_boost_tuples_cons<tuple_idf>::value)
|| (!is_boost_tuple<tuple_id>::value && is_std_tuple<tuple_idf>::value)
));
#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
tup_idf = bgt::push_back<tuple_id, float>::apply(std::move(tup_id), 3.0f);
BOOST_CHECK_EQUAL((bgt::get<0>(tup_idf)), 1);
BOOST_CHECK_EQUAL((bgt::get<1>(tup_idf)), 2.0);
BOOST_CHECK_EQUAL((bgt::get<2>(tup_idf)), 3.0f);
#endif
#else
BOOST_CHECK((is_boost_tuples_cons<tuple_idf>::type, float>::value));
#endif
}
int test_main(int, char* [])
{
test_all<boost::tuple<int, double> >();
test_all<std::pair<int, double> >();
#if !defined(BOOST_NO_CXX11_HDR_TUPLE) && !defined(BOOST_NO_VARIADIC_TEMPLATES)
test_all<std::tuple<int, double> >();
#endif
return 0;
}