You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
9.3 KiB
C++
342 lines
9.3 KiB
C++
2 years ago
|
// Boost.Geometry
|
||
|
|
||
|
// Copyright (c) 2020-2021, 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 geometry::detail::setop_insert_output_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
|
||
|
<
|
||
|
geometry::detail::expect_output
|
||
|
<
|
||
|
Areal1, Areal2, single_out,
|
||
|
point_tag, linestring_tag, polygon_tag
|
||
|
>
|
||
|
>();
|
||
|
|
||
|
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;
|
||
|
|
||
|
// 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);
|
||
|
}
|
||
|
|
||
|
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
|