1556 lines
46 KiB
C++
1556 lines
46 KiB
C++
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
|
|
|
// Copyright (c) 2007-2015 Barend Gehrels, Amsterdam, the Netherlands.
|
|
|
|
// This file was modified by Oracle on 2014-2021.
|
|
// Modifications copyright (c) 2014-2021 Oracle and/or its affiliates.
|
|
|
|
// Contributed and/or modified by Vissarion Fysikopoulos, on behalf of Oracle
|
|
// Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle
|
|
// Contributed and/or modified by Adam Wulkiewicz, on behalf of Oracle
|
|
|
|
// 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_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|
|
#define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|
|
|
|
|
|
#include <cstddef>
|
|
#include <deque>
|
|
#include <type_traits>
|
|
|
|
#include <boost/range/begin.hpp>
|
|
#include <boost/range/end.hpp>
|
|
#include <boost/range/size.hpp>
|
|
|
|
#include <boost/geometry/algorithms/convert.hpp>
|
|
#include <boost/geometry/algorithms/detail/point_on_border.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/follow.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/linear_linear.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/pointlike_areal.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/pointlike_linear.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/pointlike_pointlike.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/range_in_geometry.hpp>
|
|
#include <boost/geometry/algorithms/detail/overlay/segment_as_subrange.hpp>
|
|
|
|
#include <boost/geometry/core/point_order.hpp>
|
|
#include <boost/geometry/core/reverse_dispatch.hpp>
|
|
#include <boost/geometry/core/static_assert.hpp>
|
|
|
|
#include <boost/geometry/geometries/concepts/check.hpp>
|
|
|
|
#include <boost/geometry/policies/robustness/rescale_policy_tags.hpp>
|
|
#include <boost/geometry/policies/robustness/segment_ratio_type.hpp>
|
|
#include <boost/geometry/policies/robustness/get_rescale_policy.hpp>
|
|
|
|
#include <boost/geometry/strategies/default_strategy.hpp>
|
|
#include <boost/geometry/strategies/detail.hpp>
|
|
#include <boost/geometry/strategies/relate/services.hpp>
|
|
|
|
#include <boost/geometry/views/segment_view.hpp>
|
|
#include <boost/geometry/views/detail/boundary_view.hpp>
|
|
|
|
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
|
#include <boost/geometry/algorithms/detail/overlay/debug_turn_info.hpp>
|
|
#include <boost/geometry/io/wkt/wkt.hpp>
|
|
#include <boost/geometry/util/for_each_with_index.hpp>
|
|
#endif
|
|
|
|
namespace boost { namespace geometry
|
|
{
|
|
|
|
#ifndef DOXYGEN_NO_DETAIL
|
|
namespace detail { namespace intersection
|
|
{
|
|
|
|
template <typename PointOut>
|
|
struct intersection_segment_segment_point
|
|
{
|
|
template
|
|
<
|
|
typename Segment1, typename Segment2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator, typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Segment1 const& segment1,
|
|
Segment2 const& segment2,
|
|
RobustPolicy const& ,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
// Make sure this is only called with no rescaling
|
|
BOOST_STATIC_ASSERT((std::is_same
|
|
<
|
|
no_rescale_policy_tag,
|
|
typename rescale_policy_type<RobustPolicy>::type
|
|
>::value));
|
|
|
|
typedef typename point_type<PointOut>::type point_type;
|
|
|
|
// Get the intersection point (or two points)
|
|
typedef segment_intersection_points<point_type> intersection_return_type;
|
|
|
|
typedef policies::relate::segments_intersection_points
|
|
<
|
|
intersection_return_type
|
|
> policy_type;
|
|
|
|
detail::segment_as_subrange<Segment1> sub_range1(segment1);
|
|
detail::segment_as_subrange<Segment2> sub_range2(segment2);
|
|
|
|
intersection_return_type
|
|
is = strategy.relate().apply(sub_range1, sub_range2, policy_type());
|
|
|
|
for (std::size_t i = 0; i < is.count; i++)
|
|
{
|
|
PointOut p;
|
|
geometry::convert(is.intersections[i], p);
|
|
*out++ = p;
|
|
}
|
|
return out;
|
|
}
|
|
};
|
|
|
|
template <typename PointOut>
|
|
struct intersection_linestring_linestring_point
|
|
{
|
|
template
|
|
<
|
|
typename Linestring1, typename Linestring2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Linestring1 const& linestring1,
|
|
Linestring2 const& linestring2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
// Make sure this is only called with no rescaling
|
|
BOOST_STATIC_ASSERT((std::is_same
|
|
<
|
|
no_rescale_policy_tag,
|
|
typename rescale_policy_type<RobustPolicy>::type
|
|
>::value));
|
|
|
|
typedef detail::overlay::turn_info<PointOut> turn_info;
|
|
std::deque<turn_info> turns;
|
|
|
|
geometry::get_intersection_points(linestring1, linestring2,
|
|
robust_policy, turns, strategy);
|
|
|
|
for (auto const& turn : turns)
|
|
{
|
|
PointOut p;
|
|
geometry::convert(turn.point, p);
|
|
*out++ = p;
|
|
}
|
|
return out;
|
|
}
|
|
};
|
|
|
|
/*!
|
|
\brief Version of linestring with an areal feature (polygon or multipolygon)
|
|
*/
|
|
template
|
|
<
|
|
bool ReverseAreal,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool FollowIsolatedPoints
|
|
>
|
|
struct intersection_of_linestring_with_areal
|
|
{
|
|
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
|
template <typename Turn, typename Operation>
|
|
static inline void debug_follow(Turn const& turn, Operation op,
|
|
int index)
|
|
{
|
|
std::cout << index
|
|
<< " at " << op.seg_id
|
|
<< " meth: " << method_char(turn.method)
|
|
<< " op: " << operation_char(op.operation)
|
|
<< " vis: " << visited_char(op.visited)
|
|
<< " of: " << operation_char(turn.operations[0].operation)
|
|
<< operation_char(turn.operations[1].operation)
|
|
<< " " << geometry::wkt(turn.point)
|
|
<< std::endl;
|
|
}
|
|
|
|
template <typename Turn>
|
|
static inline void debug_turn(Turn const& t, bool non_crossing)
|
|
{
|
|
std::cout << "checking turn @"
|
|
<< geometry::wkt(t.point)
|
|
<< "; " << method_char(t.method)
|
|
<< ":" << operation_char(t.operations[0].operation)
|
|
<< "/" << operation_char(t.operations[1].operation)
|
|
<< "; non-crossing? "
|
|
<< std::boolalpha << non_crossing << std::noboolalpha
|
|
<< std::endl;
|
|
}
|
|
#endif
|
|
|
|
template <typename Linestring, typename Areal, typename Strategy, typename Turns>
|
|
static inline bool simple_turns_analysis(Linestring const& linestring,
|
|
Areal const& areal,
|
|
Strategy const& strategy,
|
|
Turns const& turns,
|
|
int & inside_value)
|
|
{
|
|
using namespace overlay;
|
|
|
|
bool found_continue = false;
|
|
bool found_intersection = false;
|
|
bool found_union = false;
|
|
bool found_front = false;
|
|
|
|
for (auto const& turn : turns)
|
|
{
|
|
method_type const method = turn.method;
|
|
operation_type const op = turn.operations[0].operation;
|
|
|
|
if (method == method_crosses)
|
|
{
|
|
return false;
|
|
}
|
|
else if (op == operation_intersection)
|
|
{
|
|
found_intersection = true;
|
|
}
|
|
else if (op == operation_union)
|
|
{
|
|
found_union = true;
|
|
}
|
|
else if (op == operation_continue)
|
|
{
|
|
found_continue = true;
|
|
}
|
|
|
|
if ((found_intersection || found_continue) && found_union)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (turn.operations[0].position == position_front)
|
|
{
|
|
found_front = true;
|
|
}
|
|
}
|
|
|
|
if (found_front)
|
|
{
|
|
if (found_intersection)
|
|
{
|
|
inside_value = 1; // inside
|
|
}
|
|
else if (found_union)
|
|
{
|
|
inside_value = -1; // outside
|
|
}
|
|
else // continue and blocked
|
|
{
|
|
inside_value = 0;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// if needed analyse points of a linestring
|
|
// NOTE: range_in_geometry checks points of a linestring
|
|
// until a point inside/outside areal is found
|
|
// TODO: Could be replaced with point_in_geometry() because found_front is false
|
|
inside_value = range_in_geometry(linestring, areal, strategy);
|
|
|
|
if ( (found_intersection && inside_value == -1) // going in from outside
|
|
|| (found_continue && inside_value == -1) // going on boundary from outside
|
|
|| (found_union && inside_value == 1) ) // going out from inside
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
template
|
|
<
|
|
typename LineString, typename Areal,
|
|
typename RobustPolicy,
|
|
typename OutputIterator, typename Strategy
|
|
>
|
|
static inline OutputIterator apply(LineString const& linestring, Areal const& areal,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
// Make sure this is only called with no rescaling
|
|
BOOST_STATIC_ASSERT((std::is_same
|
|
<
|
|
no_rescale_policy_tag,
|
|
typename rescale_policy_type<RobustPolicy>::type
|
|
>::value));
|
|
|
|
if (boost::size(linestring) == 0)
|
|
{
|
|
return out;
|
|
}
|
|
|
|
typedef detail::overlay::follow
|
|
<
|
|
GeometryOut,
|
|
LineString,
|
|
Areal,
|
|
OverlayType,
|
|
false, // do not remove spikes for linear geometries
|
|
FollowIsolatedPoints
|
|
> follower;
|
|
|
|
typedef typename geometry::detail::output_geometry_access
|
|
<
|
|
GeometryOut, linestring_tag, linestring_tag
|
|
> linear;
|
|
|
|
typedef typename point_type
|
|
<
|
|
typename linear::type
|
|
>::type point_type;
|
|
|
|
typedef geometry::segment_ratio
|
|
<
|
|
typename coordinate_type<point_type>::type
|
|
> ratio_type;
|
|
|
|
typedef detail::overlay::turn_info
|
|
<
|
|
point_type,
|
|
ratio_type,
|
|
detail::overlay::turn_operation_linear
|
|
<
|
|
point_type,
|
|
ratio_type
|
|
>
|
|
> turn_info;
|
|
|
|
std::deque<turn_info> turns;
|
|
|
|
detail::get_turns::no_interrupt_policy policy;
|
|
|
|
typedef detail::overlay::get_turn_info_linear_areal
|
|
<
|
|
detail::overlay::assign_null_policy
|
|
> turn_policy;
|
|
|
|
dispatch::get_turns
|
|
<
|
|
typename geometry::tag<LineString>::type,
|
|
typename geometry::tag<Areal>::type,
|
|
LineString,
|
|
Areal,
|
|
false,
|
|
(OverlayType == overlay_intersection ? ReverseAreal : !ReverseAreal),
|
|
turn_policy
|
|
>::apply(0, linestring, 1, areal,
|
|
strategy, robust_policy,
|
|
turns, policy);
|
|
|
|
int inside_value = 0;
|
|
if (simple_turns_analysis(linestring, areal, strategy, turns, inside_value))
|
|
{
|
|
// No crossing the boundary, it is either
|
|
// inside (interior + borders)
|
|
// or outside (exterior + borders)
|
|
// or on boundary
|
|
|
|
// add linestring to the output if conditions are met
|
|
if (follower::included(inside_value))
|
|
{
|
|
typename linear::type copy;
|
|
geometry::convert(linestring, copy);
|
|
*linear::get(out)++ = copy;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
#if defined(BOOST_GEOMETRY_DEBUG_FOLLOW)
|
|
for_each_with_index(turns, [](auto index, auto const& turn)
|
|
{
|
|
debug_follow(turn, turn.operations[0], index);
|
|
});
|
|
#endif
|
|
|
|
return follower::apply
|
|
(
|
|
linestring, areal,
|
|
geometry::detail::overlay::operation_intersection,
|
|
turns, robust_policy, out, strategy
|
|
);
|
|
}
|
|
};
|
|
|
|
|
|
template <typename Turns, typename OutputIterator>
|
|
inline OutputIterator intersection_output_turn_points(Turns const& turns,
|
|
OutputIterator out)
|
|
{
|
|
for (auto const& turn : turns)
|
|
{
|
|
*out++ = turn.point;
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
template <typename PointOut>
|
|
struct intersection_areal_areal_point
|
|
{
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
typedef detail::overlay::turn_info
|
|
<
|
|
PointOut,
|
|
typename segment_ratio_type<PointOut, RobustPolicy>::type
|
|
> turn_info;
|
|
std::vector<turn_info> turns;
|
|
|
|
detail::get_turns::no_interrupt_policy policy;
|
|
|
|
geometry::get_turns
|
|
<
|
|
false, false, detail::overlay::assign_null_policy
|
|
>(geometry1, geometry2, strategy, robust_policy, turns, policy);
|
|
|
|
return intersection_output_turn_points(turns, out);
|
|
}
|
|
};
|
|
|
|
template <typename PointOut>
|
|
struct intersection_linear_areal_point
|
|
{
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
// Make sure this is only called with no rescaling
|
|
BOOST_STATIC_ASSERT((std::is_same
|
|
<
|
|
no_rescale_policy_tag,
|
|
typename rescale_policy_type<RobustPolicy>::type
|
|
>::value));
|
|
|
|
typedef geometry::segment_ratio<typename geometry::coordinate_type<PointOut>::type> ratio_type;
|
|
|
|
typedef detail::overlay::turn_info
|
|
<
|
|
PointOut,
|
|
ratio_type,
|
|
detail::overlay::turn_operation_linear
|
|
<
|
|
PointOut,
|
|
ratio_type
|
|
>
|
|
> turn_info;
|
|
|
|
typedef detail::overlay::get_turn_info_linear_areal
|
|
<
|
|
detail::overlay::assign_null_policy
|
|
> turn_policy;
|
|
|
|
std::vector<turn_info> turns;
|
|
|
|
detail::get_turns::no_interrupt_policy interrupt_policy;
|
|
|
|
dispatch::get_turns
|
|
<
|
|
typename geometry::tag<Geometry1>::type,
|
|
typename geometry::tag<Geometry2>::type,
|
|
Geometry1,
|
|
Geometry2,
|
|
false,
|
|
false,
|
|
turn_policy
|
|
>::apply(0, geometry1, 1, geometry2,
|
|
strategy, robust_policy,
|
|
turns, interrupt_policy);
|
|
|
|
return intersection_output_turn_points(turns, out);
|
|
}
|
|
};
|
|
|
|
template <typename PointOut>
|
|
struct intersection_areal_linear_point
|
|
{
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
return intersection_linear_areal_point
|
|
<
|
|
PointOut
|
|
>::apply(geometry2, geometry1, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
}} // namespace detail::intersection
|
|
#endif // DOXYGEN_NO_DETAIL
|
|
|
|
|
|
|
|
#ifndef DOXYGEN_NO_DISPATCH
|
|
namespace dispatch
|
|
{
|
|
|
|
template
|
|
<
|
|
// real types
|
|
typename Geometry1,
|
|
typename Geometry2,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
// orientation
|
|
bool Reverse1 = detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
|
bool Reverse2 = detail::overlay::do_reverse<geometry::point_order<Geometry2>::value>::value,
|
|
// tag dispatching:
|
|
typename TagIn1 = typename geometry::tag<Geometry1>::type,
|
|
typename TagIn2 = typename geometry::tag<Geometry2>::type,
|
|
typename TagOut = typename detail::setop_insert_output_tag<GeometryOut>::type,
|
|
// metafunction finetuning helpers:
|
|
typename CastedTagIn1 = typename geometry::tag_cast<TagIn1, areal_tag, linear_tag, pointlike_tag>::type,
|
|
typename CastedTagIn2 = typename geometry::tag_cast<TagIn2, areal_tag, linear_tag, pointlike_tag>::type,
|
|
typename CastedTagOut = typename geometry::tag_cast<TagOut, areal_tag, linear_tag, pointlike_tag>::type
|
|
>
|
|
struct intersection_insert
|
|
{
|
|
BOOST_GEOMETRY_STATIC_ASSERT_FALSE(
|
|
"Not or not yet implemented for these Geometry types or their order.",
|
|
Geometry1, Geometry2, GeometryOut,
|
|
std::integral_constant<overlay_type, OverlayType>);
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2, typename TagOut
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
GeometryOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, TagOut,
|
|
areal_tag, areal_tag, areal_tag
|
|
> : detail::overlay::overlay
|
|
<
|
|
Geometry1, Geometry2, Reverse1, Reverse2,
|
|
detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
|
GeometryOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
// Any areal type with box:
|
|
template
|
|
<
|
|
typename Geometry, typename Box,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn, typename TagOut
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry, Box,
|
|
GeometryOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn, box_tag, TagOut,
|
|
areal_tag, areal_tag, areal_tag
|
|
> : detail::overlay::overlay
|
|
<
|
|
Geometry, Box, Reverse1, Reverse2,
|
|
detail::overlay::do_reverse<geometry::point_order<GeometryOut>::value>::value,
|
|
GeometryOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Segment1, typename Segment2,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Segment1, Segment2,
|
|
GeometryOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
segment_tag, segment_tag, point_tag,
|
|
linear_tag, linear_tag, pointlike_tag
|
|
> : detail::intersection::intersection_segment_segment_point<GeometryOut>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linestring1, typename Linestring2,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring1, Linestring2,
|
|
GeometryOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
linestring_tag, linestring_tag, point_tag,
|
|
linear_tag, linear_tag, pointlike_tag
|
|
> : detail::intersection::intersection_linestring_linestring_point<GeometryOut>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linestring, typename Box,
|
|
typename GeometryOut,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, Box,
|
|
GeometryOut,
|
|
overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
linestring_tag, box_tag, linestring_tag,
|
|
linear_tag, areal_tag, linear_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
|
static inline OutputIterator apply(Linestring const& linestring,
|
|
Box const& box,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out, Strategy const& )
|
|
{
|
|
typedef typename point_type<GeometryOut>::type point_type;
|
|
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
|
return detail::intersection::clip_range_with_box
|
|
<GeometryOut>(box, linestring, robust_policy, out, lb_strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linestring, typename Polygon,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool ReverseLinestring, bool ReversePolygon
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, Polygon,
|
|
GeometryOut,
|
|
OverlayType,
|
|
ReverseLinestring, ReversePolygon,
|
|
linestring_tag, polygon_tag, linestring_tag,
|
|
linear_tag, areal_tag, linear_tag
|
|
> : detail::intersection::intersection_of_linestring_with_areal
|
|
<
|
|
ReversePolygon,
|
|
GeometryOut,
|
|
OverlayType,
|
|
false
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linestring, typename Ring,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool ReverseLinestring, bool ReverseRing
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, Ring,
|
|
GeometryOut,
|
|
OverlayType,
|
|
ReverseLinestring, ReverseRing,
|
|
linestring_tag, ring_tag, linestring_tag,
|
|
linear_tag, areal_tag, linear_tag
|
|
> : detail::intersection::intersection_of_linestring_with_areal
|
|
<
|
|
ReverseRing,
|
|
GeometryOut,
|
|
OverlayType,
|
|
false
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Segment, typename Box,
|
|
typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Segment, Box,
|
|
GeometryOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
segment_tag, box_tag, linestring_tag,
|
|
linear_tag, areal_tag, linear_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
|
static inline OutputIterator apply(Segment const& segment,
|
|
Box const& box,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out, Strategy const& )
|
|
{
|
|
geometry::segment_view<Segment> range(segment);
|
|
|
|
typedef typename point_type<GeometryOut>::type point_type;
|
|
strategy::intersection::liang_barsky<Box, point_type> lb_strategy;
|
|
return detail::intersection::clip_range_with_box
|
|
<GeometryOut>(box, range, robust_policy, out, lb_strategy);
|
|
}
|
|
};
|
|
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag1, typename Tag2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
PointOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
Tag1, Tag2, point_tag,
|
|
areal_tag, areal_tag, pointlike_tag
|
|
>
|
|
: public detail::intersection::intersection_areal_areal_point
|
|
<
|
|
PointOut
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag1, typename Tag2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
PointOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
Tag1, Tag2, point_tag,
|
|
linear_tag, areal_tag, pointlike_tag
|
|
>
|
|
: public detail::intersection::intersection_linear_areal_point
|
|
<
|
|
PointOut
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag1, typename Tag2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
PointOut,
|
|
OverlayType,
|
|
Reverse1, Reverse2,
|
|
Tag1, Tag2, point_tag,
|
|
areal_tag, linear_tag, pointlike_tag
|
|
>
|
|
: public detail::intersection::intersection_areal_linear_point
|
|
<
|
|
PointOut
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2, typename GeometryOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert_reversed
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
|
static inline OutputIterator apply(Geometry1 const& g1,
|
|
Geometry2 const& g2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
return intersection_insert
|
|
<
|
|
Geometry2, Geometry1, GeometryOut,
|
|
OverlayType,
|
|
Reverse2, Reverse1
|
|
>::apply(g2, g1, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
// dispatch for intersection(areal, areal, linear)
|
|
template
|
|
<
|
|
typename Geometry1, typename Geometry2,
|
|
typename LinestringOut,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag1, typename Tag2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
LinestringOut,
|
|
overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
Tag1, Tag2, linestring_tag,
|
|
areal_tag, areal_tag, linear_tag
|
|
>
|
|
{
|
|
template
|
|
<
|
|
typename RobustPolicy, typename OutputIterator, typename Strategy
|
|
>
|
|
static inline OutputIterator apply(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator oit,
|
|
Strategy const& strategy)
|
|
{
|
|
detail::boundary_view<Geometry1 const> view1(geometry1);
|
|
detail::boundary_view<Geometry2 const> view2(geometry2);
|
|
|
|
return detail::overlay::linear_linear_linestring
|
|
<
|
|
detail::boundary_view<Geometry1 const>,
|
|
detail::boundary_view<Geometry2 const>,
|
|
LinestringOut,
|
|
overlay_intersection
|
|
>::apply(view1, view2, robust_policy, oit, strategy);
|
|
}
|
|
};
|
|
|
|
// dispatch for difference/intersection of linear geometries
|
|
template
|
|
<
|
|
typename Linear1, typename Linear2, typename LineStringOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linear1, Linear2, LineStringOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, linestring_tag,
|
|
linear_tag, linear_tag, linear_tag
|
|
> : detail::overlay::linear_linear_linestring
|
|
<
|
|
Linear1, Linear2, LineStringOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Linear1, typename Linear2, typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linear1, Linear2, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
linear_tag, linear_tag, detail::tupled_output_tag
|
|
>
|
|
: detail::expect_output
|
|
<
|
|
Linear1, Linear2, TupledOut,
|
|
// NOTE: points can be the result only in case of intersection.
|
|
std::conditional_t
|
|
<
|
|
(OverlayType == overlay_intersection),
|
|
point_tag,
|
|
void
|
|
>,
|
|
linestring_tag
|
|
>
|
|
{
|
|
// NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
|
|
// iterators in OutputIterators tuple/pair.
|
|
template
|
|
<
|
|
typename RobustPolicy, typename OutputIterators, typename Strategy
|
|
>
|
|
static inline OutputIterators apply(Linear1 const& linear1,
|
|
Linear2 const& linear2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterators oit,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail::overlay::linear_linear_linestring
|
|
<
|
|
Linear1, Linear2, TupledOut, OverlayType
|
|
>::apply(linear1, linear2, robust_policy, oit, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
// dispatch for difference/intersection of point-like geometries
|
|
|
|
template
|
|
<
|
|
typename Point1, typename Point2, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Point1, Point2, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
point_tag, point_tag, point_tag,
|
|
pointlike_tag, pointlike_tag, pointlike_tag
|
|
> : detail::overlay::point_point_point
|
|
<
|
|
Point1, Point2, PointOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename MultiPoint, typename Point, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
MultiPoint, Point, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
multi_point_tag, point_tag, point_tag,
|
|
pointlike_tag, pointlike_tag, pointlike_tag
|
|
> : detail::overlay::multipoint_point_point
|
|
<
|
|
MultiPoint, Point, PointOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename Point, typename MultiPoint, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Point, MultiPoint, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
point_tag, multi_point_tag, point_tag,
|
|
pointlike_tag, pointlike_tag, pointlike_tag
|
|
> : detail::overlay::point_multipoint_point
|
|
<
|
|
Point, MultiPoint, PointOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename MultiPoint1, typename MultiPoint2, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
MultiPoint1, MultiPoint2, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
multi_point_tag, multi_point_tag, point_tag,
|
|
pointlike_tag, pointlike_tag, pointlike_tag
|
|
> : detail::overlay::multipoint_multipoint_point
|
|
<
|
|
MultiPoint1, MultiPoint2, PointOut, OverlayType
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename PointLike1, typename PointLike2, typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
PointLike1, PointLike2, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
pointlike_tag, pointlike_tag, detail::tupled_output_tag
|
|
>
|
|
: detail::expect_output<PointLike1, PointLike2, TupledOut, point_tag>
|
|
{
|
|
// NOTE: The order of geometries in TupledOut tuple/pair must correspond to the order
|
|
// of iterators in OutputIterators tuple/pair.
|
|
template
|
|
<
|
|
typename RobustPolicy, typename OutputIterators, typename Strategy
|
|
>
|
|
static inline OutputIterators apply(PointLike1 const& pointlike1,
|
|
PointLike2 const& pointlike2,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterators oits,
|
|
Strategy const& strategy)
|
|
{
|
|
namespace bgt = boost::geometry::tuples;
|
|
|
|
static const bool out_point_index = bgt::find_index_if
|
|
<
|
|
TupledOut, geometry::detail::is_tag_same_as_pred<point_tag>::template pred
|
|
>::value;
|
|
|
|
bgt::get<out_point_index>(oits) = intersection_insert
|
|
<
|
|
PointLike1, PointLike2,
|
|
typename bgt::element
|
|
<
|
|
out_point_index, TupledOut
|
|
>::type,
|
|
OverlayType
|
|
>::apply(pointlike1, pointlike2, robust_policy,
|
|
bgt::get<out_point_index>(oits),
|
|
strategy);
|
|
|
|
return oits;
|
|
}
|
|
};
|
|
|
|
|
|
// dispatch for difference/intersection of pointlike-linear geometries
|
|
template
|
|
<
|
|
typename Point, typename Linear, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Point, Linear, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
point_tag, Tag, point_tag,
|
|
pointlike_tag, linear_tag, pointlike_tag
|
|
> : detail_dispatch::overlay::pointlike_linear_point
|
|
<
|
|
Point, Linear, PointOut, OverlayType,
|
|
point_tag, typename tag_cast<Tag, segment_tag, linear_tag>::type
|
|
>
|
|
{};
|
|
|
|
|
|
template
|
|
<
|
|
typename MultiPoint, typename Linear, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename Tag
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
MultiPoint, Linear, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
multi_point_tag, Tag, point_tag,
|
|
pointlike_tag, linear_tag, pointlike_tag
|
|
> : detail_dispatch::overlay::pointlike_linear_point
|
|
<
|
|
MultiPoint, Linear, PointOut, OverlayType,
|
|
multi_point_tag,
|
|
typename tag_cast<Tag, segment_tag, linear_tag>::type
|
|
>
|
|
{};
|
|
|
|
|
|
// This specialization is needed because intersection() reverses the arguments
|
|
// for MultiPoint/Linestring combination.
|
|
template
|
|
<
|
|
typename Linestring, typename MultiPoint, typename PointOut,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, MultiPoint, PointOut, overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
linestring_tag, multi_point_tag, point_tag,
|
|
linear_tag, pointlike_tag, pointlike_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
|
static inline OutputIterator apply(Linestring const& linestring,
|
|
MultiPoint const& multipoint,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail_dispatch::overlay::pointlike_linear_point
|
|
<
|
|
MultiPoint, Linestring, PointOut, overlay_intersection,
|
|
multi_point_tag, linear_tag
|
|
>::apply(multipoint, linestring, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename PointLike, typename Linear, typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
PointLike, Linear, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
pointlike_tag, linear_tag, detail::tupled_output_tag
|
|
>
|
|
// Reuse the implementation for PointLike/PointLike.
|
|
: intersection_insert
|
|
<
|
|
PointLike, Linear, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
pointlike_tag, pointlike_tag, detail::tupled_output_tag
|
|
>
|
|
{};
|
|
|
|
|
|
// This specialization is needed because intersection() reverses the arguments
|
|
// for MultiPoint/Linestring combination.
|
|
template
|
|
<
|
|
typename Linestring, typename MultiPoint, typename TupledOut,
|
|
bool Reverse1, bool Reverse2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, MultiPoint, TupledOut, overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
linestring_tag, multi_point_tag, detail::tupled_output_tag,
|
|
linear_tag, pointlike_tag, detail::tupled_output_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterators, typename Strategy>
|
|
static inline OutputIterators apply(Linestring const& linestring,
|
|
MultiPoint const& multipoint,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterators out,
|
|
Strategy const& strategy)
|
|
{
|
|
return intersection_insert
|
|
<
|
|
MultiPoint, Linestring, TupledOut, overlay_intersection
|
|
>::apply(multipoint, linestring, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
// dispatch for difference/intersection of pointlike-areal geometries
|
|
template
|
|
<
|
|
typename Point, typename Areal, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename ArealTag
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Point, Areal, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
point_tag, ArealTag, point_tag,
|
|
pointlike_tag, areal_tag, pointlike_tag
|
|
> : detail_dispatch::overlay::pointlike_areal_point
|
|
<
|
|
Point, Areal, PointOut, OverlayType,
|
|
point_tag, ArealTag
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename MultiPoint, typename Areal, typename PointOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename ArealTag
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
MultiPoint, Areal, PointOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
multi_point_tag, ArealTag, point_tag,
|
|
pointlike_tag, areal_tag, pointlike_tag
|
|
> : detail_dispatch::overlay::pointlike_areal_point
|
|
<
|
|
MultiPoint, Areal, PointOut, OverlayType,
|
|
multi_point_tag, ArealTag
|
|
>
|
|
{};
|
|
|
|
// This specialization is needed because intersection() reverses the arguments
|
|
// for MultiPoint/Ring and MultiPoint/Polygon combinations.
|
|
template
|
|
<
|
|
typename Areal, typename MultiPoint, typename PointOut,
|
|
bool Reverse1, bool Reverse2,
|
|
typename ArealTag
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Areal, MultiPoint, PointOut, overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
ArealTag, multi_point_tag, point_tag,
|
|
areal_tag, pointlike_tag, pointlike_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterator, typename Strategy>
|
|
static inline OutputIterator apply(Areal const& areal,
|
|
MultiPoint const& multipoint,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
return detail_dispatch::overlay::pointlike_areal_point
|
|
<
|
|
MultiPoint, Areal, PointOut, overlay_intersection,
|
|
multi_point_tag, ArealTag
|
|
>::apply(multipoint, areal, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename PointLike, typename Areal, typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1, typename TagIn2
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
PointLike, Areal, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
pointlike_tag, areal_tag, detail::tupled_output_tag
|
|
>
|
|
// Reuse the implementation for PointLike/PointLike.
|
|
: intersection_insert
|
|
<
|
|
PointLike, Areal, TupledOut, OverlayType,
|
|
Reverse1, Reverse2,
|
|
TagIn1, TagIn2, detail::tupled_output_tag,
|
|
pointlike_tag, pointlike_tag, detail::tupled_output_tag
|
|
>
|
|
{};
|
|
|
|
|
|
// This specialization is needed because intersection() reverses the arguments
|
|
// for MultiPoint/Ring and MultiPoint/Polygon combinations.
|
|
template
|
|
<
|
|
typename Areal, typename MultiPoint, typename TupledOut,
|
|
bool Reverse1, bool Reverse2,
|
|
typename TagIn1
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Areal, MultiPoint, TupledOut, overlay_intersection,
|
|
Reverse1, Reverse2,
|
|
TagIn1, multi_point_tag, detail::tupled_output_tag,
|
|
areal_tag, pointlike_tag, detail::tupled_output_tag
|
|
>
|
|
{
|
|
template <typename RobustPolicy, typename OutputIterators, typename Strategy>
|
|
static inline OutputIterators apply(Areal const& areal,
|
|
MultiPoint const& multipoint,
|
|
RobustPolicy const& robust_policy,
|
|
OutputIterators out,
|
|
Strategy const& strategy)
|
|
{
|
|
return intersection_insert
|
|
<
|
|
MultiPoint, Areal, TupledOut, overlay_intersection
|
|
>::apply(multipoint, areal, robust_policy, out, strategy);
|
|
}
|
|
};
|
|
|
|
|
|
template
|
|
<
|
|
typename Linestring, typename Polygon,
|
|
typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool ReverseLinestring, bool ReversePolygon
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, Polygon,
|
|
TupledOut,
|
|
OverlayType,
|
|
ReverseLinestring, ReversePolygon,
|
|
linestring_tag, polygon_tag, detail::tupled_output_tag,
|
|
linear_tag, areal_tag, detail::tupled_output_tag
|
|
> : detail::intersection::intersection_of_linestring_with_areal
|
|
<
|
|
ReversePolygon,
|
|
TupledOut,
|
|
OverlayType,
|
|
true
|
|
>
|
|
{};
|
|
|
|
template
|
|
<
|
|
typename Linestring, typename Ring,
|
|
typename TupledOut,
|
|
overlay_type OverlayType,
|
|
bool ReverseLinestring, bool ReverseRing
|
|
>
|
|
struct intersection_insert
|
|
<
|
|
Linestring, Ring,
|
|
TupledOut,
|
|
OverlayType,
|
|
ReverseLinestring, ReverseRing,
|
|
linestring_tag, ring_tag, detail::tupled_output_tag,
|
|
linear_tag, areal_tag, detail::tupled_output_tag
|
|
> : detail::intersection::intersection_of_linestring_with_areal
|
|
<
|
|
ReverseRing,
|
|
TupledOut,
|
|
OverlayType,
|
|
true
|
|
>
|
|
{};
|
|
|
|
|
|
} // namespace dispatch
|
|
#endif // DOXYGEN_NO_DISPATCH
|
|
|
|
|
|
#ifndef DOXYGEN_NO_DETAIL
|
|
namespace detail { namespace intersection
|
|
{
|
|
|
|
|
|
template
|
|
<
|
|
typename GeometryOut,
|
|
bool ReverseSecond,
|
|
overlay_type OverlayType,
|
|
typename Geometry1, typename Geometry2,
|
|
typename RobustPolicy,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
inline OutputIterator insert(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
RobustPolicy robust_policy,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
return std::conditional_t
|
|
<
|
|
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
|
geometry::dispatch::intersection_insert_reversed
|
|
<
|
|
Geometry1, Geometry2,
|
|
GeometryOut,
|
|
OverlayType,
|
|
overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
|
overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
|
|
>,
|
|
geometry::dispatch::intersection_insert
|
|
<
|
|
Geometry1, Geometry2,
|
|
GeometryOut,
|
|
OverlayType,
|
|
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry1>::value>::value,
|
|
geometry::detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, ReverseSecond>::value
|
|
>
|
|
>::apply(geometry1, geometry2, robust_policy, out, strategy);
|
|
}
|
|
|
|
|
|
/*!
|
|
\brief \brief_calc2{intersection} \brief_strategy
|
|
\ingroup intersection
|
|
\details \details_calc2{intersection_insert, spatial set theoretic intersection}
|
|
\brief_strategy. \details_insert{intersection}
|
|
\tparam GeometryOut \tparam_geometry{\p_l_or_c}
|
|
\tparam Geometry1 \tparam_geometry
|
|
\tparam Geometry2 \tparam_geometry
|
|
\tparam OutputIterator \tparam_out{\p_l_or_c}
|
|
\tparam Strategy \tparam_strategy_overlay
|
|
\param geometry1 \param_geometry
|
|
\param geometry2 \param_geometry
|
|
\param out \param_out{intersection}
|
|
\param strategy \param_strategy{intersection}
|
|
\return \return_out
|
|
|
|
\qbk{distinguish,with strategy}
|
|
\qbk{[include reference/algorithms/intersection.qbk]}
|
|
*/
|
|
template
|
|
<
|
|
typename GeometryOut,
|
|
typename Geometry1,
|
|
typename Geometry2,
|
|
typename OutputIterator,
|
|
typename Strategy
|
|
>
|
|
inline OutputIterator intersection_insert(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
OutputIterator out,
|
|
Strategy const& strategy)
|
|
{
|
|
concepts::check<Geometry1 const>();
|
|
concepts::check<Geometry2 const>();
|
|
|
|
typedef typename geometry::rescale_overlay_policy_type
|
|
<
|
|
Geometry1,
|
|
Geometry2,
|
|
typename Strategy::cs_tag
|
|
>::type rescale_policy_type;
|
|
|
|
rescale_policy_type robust_policy
|
|
= geometry::get_rescale_policy<rescale_policy_type>(
|
|
geometry1, geometry2, strategy);
|
|
|
|
return detail::intersection::insert
|
|
<
|
|
GeometryOut, false, overlay_intersection
|
|
>(geometry1, geometry2, robust_policy, out, strategy);
|
|
}
|
|
|
|
|
|
/*!
|
|
\brief \brief_calc2{intersection}
|
|
\ingroup intersection
|
|
\details \details_calc2{intersection_insert, spatial set theoretic intersection}.
|
|
\details_insert{intersection}
|
|
\tparam GeometryOut \tparam_geometry{\p_l_or_c}
|
|
\tparam Geometry1 \tparam_geometry
|
|
\tparam Geometry2 \tparam_geometry
|
|
\tparam OutputIterator \tparam_out{\p_l_or_c}
|
|
\param geometry1 \param_geometry
|
|
\param geometry2 \param_geometry
|
|
\param out \param_out{intersection}
|
|
\return \return_out
|
|
|
|
\qbk{[include reference/algorithms/intersection.qbk]}
|
|
*/
|
|
template
|
|
<
|
|
typename GeometryOut,
|
|
typename Geometry1,
|
|
typename Geometry2,
|
|
typename OutputIterator
|
|
>
|
|
inline OutputIterator intersection_insert(Geometry1 const& geometry1,
|
|
Geometry2 const& geometry2,
|
|
OutputIterator out)
|
|
{
|
|
concepts::check<Geometry1 const>();
|
|
concepts::check<Geometry2 const>();
|
|
|
|
typedef typename strategies::relate::services::default_strategy
|
|
<
|
|
Geometry1, Geometry2
|
|
>::type strategy_type;
|
|
|
|
return intersection_insert<GeometryOut>(geometry1, geometry2, out,
|
|
strategy_type());
|
|
}
|
|
|
|
}} // namespace detail::intersection
|
|
#endif // DOXYGEN_NO_DETAIL
|
|
|
|
|
|
|
|
}} // namespace boost::geometry
|
|
|
|
|
|
#endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_INTERSECTION_INSERT_HPP
|