mirror of
https://github.com/boostorg/geometry.git
synced 2026-02-11 11:52:11 +00:00
Splitted intersection and intersection_inserter
Doing back_inserter now in later phase of dispatch Added MPL assertions to coordinate system and type Modified read_wkt with output iterator option [SVN r67473]
This commit is contained in:
@@ -10,21 +10,9 @@
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/ranges/segment_range.hpp>
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/algorithms/intersection_inserter.hpp>
|
||||
#include <boost/geometry/algorithms/intersects.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
@@ -36,72 +24,56 @@ namespace detail { namespace intersection
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t Dimension, std::size_t DimensionCount
|
||||
>
|
||||
struct intersection_segment_segment_point
|
||||
struct intersection_box_box
|
||||
{
|
||||
static inline OutputIterator apply(Segment1 const& segment1,
|
||||
Segment2 const& segment2, OutputIterator out,
|
||||
static inline bool apply(Box1 const& box1,
|
||||
Box2 const& box2, BoxOut& box_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
typedef typename coordinate_type<BoxOut>::type ct;
|
||||
|
||||
// Get the intersection point (or two points)
|
||||
segment_intersection_points<point_type> is
|
||||
= strategy::intersection::relate_cartesian_segments
|
||||
<
|
||||
policies::relate::segments_intersection_points
|
||||
<
|
||||
Segment1,
|
||||
Segment2,
|
||||
segment_intersection_points<point_type>
|
||||
>
|
||||
>::apply(segment1, segment2);
|
||||
ct min1 = get<min_corner, Dimension>(box1);
|
||||
ct min2 = get<min_corner, Dimension>(box2);
|
||||
ct max1 = get<max_corner, Dimension>(box1);
|
||||
ct max2 = get<max_corner, Dimension>(box2);
|
||||
|
||||
for (std::size_t i = 0; i < is.count; i++)
|
||||
if (max1 < min2 || max2 < min1)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::copy_coordinates(is.intersections[i], p);
|
||||
*out++ = p;
|
||||
return false;
|
||||
}
|
||||
return out;
|
||||
// Set dimensions of output coordinate
|
||||
set<min_corner, Dimension>(box_out, min1 < min2 ? min2 : min1);
|
||||
set<max_corner, Dimension>(box_out, max1 > max2 ? max2 : max1);
|
||||
|
||||
return intersection_box_box
|
||||
<
|
||||
Box1, Box2, BoxOut, Strategy,
|
||||
Dimension + 1, DimensionCount
|
||||
>::apply(box1, box2, box_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy,
|
||||
std::size_t DimensionCount
|
||||
>
|
||||
struct intersection_linestring_linestring_point
|
||||
struct intersection_box_box<Box1, Box2, BoxOut, Strategy, DimensionCount, DimensionCount>
|
||||
{
|
||||
static inline OutputIterator apply(Linestring1 const& linestring1,
|
||||
Linestring2 const& linestring2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
static inline bool apply(Box1 const&, Box2 const&, BoxOut&, Strategy const&)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
geometry::get_intersection_points(linestring1, linestring2, turns);
|
||||
|
||||
for (typename boost::range_iterator<std::deque<turn_info> const>::type
|
||||
it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::copy_coordinates(it->point, p);
|
||||
*out++ = p;
|
||||
}
|
||||
return out;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
@@ -111,362 +83,95 @@ struct intersection_linestring_linestring_point
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
// By default, all is forwarded to the intersection_inserter-dispatcher
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// orientation
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
struct intersection
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
|
||||
, (types<Geometry1, Geometry2, GeometryOut>)
|
||||
);
|
||||
typedef std::back_insert_iterator<GeometryOut> output_iterator;
|
||||
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename boost::range_value<GeometryOut>::type OneOut;
|
||||
|
||||
intersection_inserter
|
||||
<
|
||||
Tag1, Tag2, typename geometry::tag<OneOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<OneOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry1>::value, false>::value,
|
||||
detail::overlay::do_reverse<geometry::point_order<Geometry2>::value, false>::value,
|
||||
false,
|
||||
output_iterator, OneOut,
|
||||
Strategy
|
||||
>::apply(geometry1, geometry2, std::back_inserter(geometry_out), strategy);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Box1, typename Box2,
|
||||
typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
struct intersection
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
box_tag, box_tag, box_tag,
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
// Any areal type with box:
|
||||
template
|
||||
<
|
||||
typename TagIn, typename TagOut,
|
||||
typename Geometry, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
TagIn, box_tag, TagOut,
|
||||
true, true, true,
|
||||
Geometry, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
segment_tag, segment_tag, point_tag,
|
||||
false, false, false,
|
||||
Segment1, Segment2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_segment_segment_point
|
||||
> : public detail::intersection::intersection_box_box
|
||||
<
|
||||
Segment1, Segment2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
Box1, Box2, BoxOut,
|
||||
Strategy,
|
||||
0, geometry::dimension<Box1>::value
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
linestring_tag, linestring_tag, point_tag,
|
||||
false, false, false,
|
||||
Linestring1, Linestring2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_linestring_linestring_point
|
||||
<
|
||||
Linestring1, Linestring2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
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, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
segment_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Segment, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Segment const& segment,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
typedef boost::geometry::segment_range<Segment> range_type;
|
||||
range_type 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, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Tag1, typename Tag2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter_reversed
|
||||
struct intersection_reversed
|
||||
{
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
static inline bool apply(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
GeometryOut& geometry_out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_inserter
|
||||
return intersection
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Tag2, Tag1, TagOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>::apply(g2, g1, out, strategy);
|
||||
GeometryOut, Strategy
|
||||
>::apply(geometry2, geometry1, geometry_out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
geometry::dispatch::intersection_inserter_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
////point_order<Geometry1>::value,
|
||||
////point_order<Geometry2>::value,
|
||||
////point_order<GeometryOut>::value,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>,
|
||||
geometry::dispatch::intersection_inserter
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
////point_order<Geometry1>::value,
|
||||
///point_order<Geometry2>::value,
|
||||
///point_order<GeometryOut>::value,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection} \brief_strategy
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_inserter, spatial set theoretic intersection}
|
||||
\brief_strategy. \details_inserter{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 Compound strategy for intersection
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{intersection}
|
||||
\param strategy The strategy
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{behavior,[qbk_out __point__]:Calculates intersection points of input geometries}
|
||||
\qbk{behavior,[qbk_out __linestring__]:Calculates intersection linestrings of input geometries (NYI)}
|
||||
\qbk{behavior,[qbk_out __polygon__]:Calculates intersection polygons input (multi)polygons and/or boxes}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return detail::intersection::inserter<GeometryOut, false, false, true>(
|
||||
geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_inserter, spatial set theoretic intersection}. \details_inserter{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{example,intersection_segment_inserter}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy;
|
||||
|
||||
return intersection_inserter<GeometryOut>(geometry1, geometry2, out,
|
||||
strategy());
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
@@ -486,30 +191,42 @@ template
|
||||
<
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename Collection
|
||||
typename GeometryOut
|
||||
>
|
||||
inline void intersection(Geometry1 const& geometry1,
|
||||
inline bool intersection(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
Collection& output_collection)
|
||||
GeometryOut& geometry_out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef typename boost::range_value<Collection>::type geometry_out;
|
||||
concept::check<geometry_out>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<geometry_out>::type,
|
||||
typename cs_tag<Geometry1>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<geometry_out>::type
|
||||
typename geometry::point_type<Geometry1>::type
|
||||
> strategy;
|
||||
|
||||
|
||||
intersection_inserter<geometry_out>(geometry1, geometry2,
|
||||
std::back_inserter(output_collection),
|
||||
strategy());
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
dispatch::intersection_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>,
|
||||
dispatch::intersection
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
Geometry1, Geometry2, GeometryOut, strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, geometry_out, strategy());
|
||||
}
|
||||
|
||||
|
||||
|
||||
486
include/boost/geometry/algorithms/intersection_inserter.hpp
Normal file
486
include/boost/geometry/algorithms/intersection_inserter.hpp
Normal file
@@ -0,0 +1,486 @@
|
||||
// Boost.Geometry (aka GGL, Generic Geometry Library)
|
||||
//
|
||||
// Copyright Barend Gehrels 2007-2009, Geodan, Amsterdam, the Netherlands.
|
||||
// Copyright Bruno Lalande 2008, 2009
|
||||
// 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_INTERSECTION_INSERTER_HPP
|
||||
#define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_INSERTER_HPP
|
||||
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/range/metafunctions.hpp>
|
||||
|
||||
|
||||
#include <boost/geometry/core/is_areal.hpp>
|
||||
#include <boost/geometry/core/point_order.hpp>
|
||||
#include <boost/geometry/core/reverse_dispatch.hpp>
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/clip_linestring.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/get_intersection_points.hpp>
|
||||
#include <boost/geometry/algorithms/detail/overlay/overlay.hpp>
|
||||
#include <boost/geometry/ranges/segment_range.hpp>
|
||||
|
||||
|
||||
namespace boost { namespace geometry
|
||||
{
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_segment_segment_point
|
||||
{
|
||||
static inline OutputIterator apply(Segment1 const& segment1,
|
||||
Segment2 const& segment2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
|
||||
// Get the intersection point (or two points)
|
||||
segment_intersection_points<point_type> is
|
||||
= strategy::intersection::relate_cartesian_segments
|
||||
<
|
||||
policies::relate::segments_intersection_points
|
||||
<
|
||||
Segment1,
|
||||
Segment2,
|
||||
segment_intersection_points<point_type>
|
||||
>
|
||||
>::apply(segment1, segment2);
|
||||
|
||||
for (std::size_t i = 0; i < is.count; i++)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::copy_coordinates(is.intersections[i], p);
|
||||
*out++ = p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
typename OutputIterator, typename PointOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_linestring_linestring_point
|
||||
{
|
||||
static inline OutputIterator apply(Linestring1 const& linestring1,
|
||||
Linestring2 const& linestring2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
typedef typename point_type<PointOut>::type point_type;
|
||||
|
||||
typedef detail::overlay::turn_info<point_type> turn_info;
|
||||
std::deque<turn_info> turns;
|
||||
|
||||
geometry::get_intersection_points(linestring1, linestring2, turns);
|
||||
|
||||
for (typename boost::range_iterator<std::deque<turn_info> const>::type
|
||||
it = boost::begin(turns); it != boost::end(turns); ++it)
|
||||
{
|
||||
PointOut p;
|
||||
geometry::copy_coordinates(it->point, p);
|
||||
*out++ = p;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
};
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DISPATCH
|
||||
namespace dispatch
|
||||
{
|
||||
|
||||
template
|
||||
<
|
||||
// tag dispatching:
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
// orientation
|
||||
// metafunction finetuning helpers:
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
// real types
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_OR_NOT_YET_IMPLEMENTED_FOR_THIS_GEOMETRY_TYPES_OR_ORIENTATIONS
|
||||
, (types<Geometry1, Geometry2, GeometryOut>)
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename TagIn1, typename TagIn2, typename TagOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
TagIn1, TagIn2, TagOut,
|
||||
true, true, true,
|
||||
Geometry1, Geometry2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry1, Geometry2, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
{};
|
||||
|
||||
|
||||
// Any areal type with box:
|
||||
template
|
||||
<
|
||||
typename TagIn, typename TagOut,
|
||||
typename Geometry, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
TagIn, box_tag, TagOut,
|
||||
true, true, true,
|
||||
Geometry, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::overlay::overlay
|
||||
<Geometry, Box, Reverse1, Reverse2, ReverseOut, OutputIterator, GeometryOut, -1, Strategy>
|
||||
{};
|
||||
|
||||
/*// box/box
|
||||
template
|
||||
<
|
||||
typename Box1, typename Box2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator,
|
||||
typename BoxOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
box_tag, box_tag, box_tag,
|
||||
true, true, true,
|
||||
Box1, Box2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, BoxOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_box_box
|
||||
<Box1, Box2, OutputIterator, BoxOut, Strategy>
|
||||
{};
|
||||
*/
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment1, typename Segment2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
segment_tag, segment_tag, point_tag,
|
||||
false, false, false,
|
||||
Segment1, Segment2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_segment_segment_point
|
||||
<
|
||||
Segment1, Segment2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring1, typename Linestring2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
linestring_tag, linestring_tag, point_tag,
|
||||
false, false, false,
|
||||
Linestring1, Linestring2,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
> : detail::intersection::intersection_linestring_linestring_point
|
||||
<
|
||||
Linestring1, Linestring2,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename Linestring, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
linestring_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Linestring, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Linestring const& linestring,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
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, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
template
|
||||
<
|
||||
typename Segment, typename Box,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter
|
||||
<
|
||||
segment_tag, box_tag, linestring_tag,
|
||||
false, true, false,
|
||||
Segment, Box,
|
||||
Reverse1, Reverse2, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
{
|
||||
static inline OutputIterator apply(Segment const& segment,
|
||||
Box const& box, OutputIterator out, Strategy const& strategy)
|
||||
{
|
||||
typedef boost::geometry::segment_range<Segment> range_type;
|
||||
range_type 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, out, lb_strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryTag1, typename GeometryTag2, typename GeometryTag3,
|
||||
bool Areal1, bool Areal2, bool ArealOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename OutputIterator, typename GeometryOut,
|
||||
typename Strategy
|
||||
>
|
||||
struct intersection_inserter_reversed
|
||||
{
|
||||
static inline OutputIterator apply(Geometry1 const& g1,
|
||||
Geometry2 const& g2, OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return intersection_inserter
|
||||
<
|
||||
GeometryTag2, GeometryTag1, GeometryTag3,
|
||||
Areal2, Areal1, ArealOut,
|
||||
Geometry2, Geometry1,
|
||||
Reverse2, Reverse1, ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>::apply(g2, g1, out, strategy);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
} // namespace dispatch
|
||||
#endif // DOXYGEN_NO_DISPATCH
|
||||
|
||||
|
||||
#ifndef DOXYGEN_NO_DETAIL
|
||||
namespace detail { namespace intersection
|
||||
{
|
||||
|
||||
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
bool Reverse1, bool Reverse2, bool ReverseOut,
|
||||
typename Geometry1, typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
return boost::mpl::if_c
|
||||
<
|
||||
geometry::reverse_dispatch<Geometry1, Geometry2>::type::value,
|
||||
geometry::dispatch::intersection_inserter_reversed
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>,
|
||||
geometry::dispatch::intersection_inserter
|
||||
<
|
||||
typename geometry::tag<Geometry1>::type,
|
||||
typename geometry::tag<Geometry2>::type,
|
||||
typename geometry::tag<GeometryOut>::type,
|
||||
geometry::is_areal<Geometry1>::value,
|
||||
geometry::is_areal<Geometry2>::value,
|
||||
geometry::is_areal<GeometryOut>::value,
|
||||
Geometry1, Geometry2,
|
||||
overlay::do_reverse<geometry::point_order<Geometry1>::value, Reverse1>::value,
|
||||
overlay::do_reverse<geometry::point_order<Geometry2>::value, Reverse2>::value,
|
||||
ReverseOut,
|
||||
OutputIterator, GeometryOut,
|
||||
Strategy
|
||||
>
|
||||
>::type::apply(geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
}} // namespace detail::intersection
|
||||
#endif // DOXYGEN_NO_DETAIL
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection} \brief_strategy
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_inserter, spatial set theoretic intersection}
|
||||
\brief_strategy. \details_inserter{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 Compound strategy for intersection
|
||||
\param geometry1 \param_geometry
|
||||
\param geometry2 \param_geometry
|
||||
\param out \param_out{intersection}
|
||||
\param strategy The strategy
|
||||
\return \return_out
|
||||
|
||||
\qbk{distinguish,with strategy}
|
||||
\qbk{behavior,[qbk_out __point__]:Calculates intersection points of input geometries}
|
||||
\qbk{behavior,[qbk_out __linestring__]:Calculates intersection linestrings of input geometries (NYI)}
|
||||
\qbk{behavior,[qbk_out __polygon__]:Calculates intersection polygons input (multi)polygons and/or boxes}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator,
|
||||
typename Strategy
|
||||
>
|
||||
inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out,
|
||||
Strategy const& strategy)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
return detail::intersection::inserter<GeometryOut, false, false, true>(
|
||||
geometry1, geometry2, out, strategy);
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief \brief_calc2{intersection}
|
||||
\ingroup intersection
|
||||
\details \details_calc2{intersection_inserter, spatial set theoretic intersection}. \details_inserter{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{example,intersection_segment_inserter}
|
||||
*/
|
||||
template
|
||||
<
|
||||
typename GeometryOut,
|
||||
typename Geometry1,
|
||||
typename Geometry2,
|
||||
typename OutputIterator
|
||||
>
|
||||
inline OutputIterator intersection_inserter(Geometry1 const& geometry1,
|
||||
Geometry2 const& geometry2,
|
||||
OutputIterator out)
|
||||
{
|
||||
concept::check<Geometry1 const>();
|
||||
concept::check<Geometry2 const>();
|
||||
|
||||
typedef strategy_intersection
|
||||
<
|
||||
typename cs_tag<GeometryOut>::type,
|
||||
Geometry1,
|
||||
Geometry2,
|
||||
typename geometry::point_type<GeometryOut>::type
|
||||
> strategy;
|
||||
|
||||
return intersection_inserter<GeometryOut>(geometry1, geometry2, out,
|
||||
strategy());
|
||||
}
|
||||
|
||||
|
||||
}} // namespace boost::geometry
|
||||
|
||||
|
||||
#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_INSERTER_HPP
|
||||
@@ -11,6 +11,7 @@
|
||||
#define BOOST_GEOMETRY_CORE_COORDINATE_SYSTEM_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
|
||||
@@ -22,16 +23,22 @@ namespace boost { namespace geometry
|
||||
namespace traits
|
||||
{
|
||||
|
||||
/*!
|
||||
\brief Traits class defining the coordinate system of a point, important for strategy selection
|
||||
\ingroup traits
|
||||
\par Geometries:
|
||||
- point
|
||||
\par Specializations should provide:
|
||||
- typedef CS type; (cs::cartesian, cs::spherical, etc)
|
||||
*/
|
||||
template <typename P>
|
||||
struct coordinate_system {};
|
||||
/*!
|
||||
\brief Traits class defining the coordinate system of a point, important for strategy selection
|
||||
\ingroup traits
|
||||
\par Geometries:
|
||||
- point
|
||||
\par Specializations should provide:
|
||||
- typedef CS type; (cs::cartesian, cs::spherical, etc)
|
||||
*/
|
||||
template <typename Point>
|
||||
struct coordinate_system
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Point>)
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#define BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP
|
||||
|
||||
|
||||
#include <boost/mpl/assert.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/geometry/core/point_type.hpp>
|
||||
@@ -30,8 +31,14 @@ namespace traits
|
||||
\par Specializations should provide:
|
||||
- typedef T type; (double,float,int,etc)
|
||||
*/
|
||||
template <typename P>
|
||||
struct coordinate_type {};
|
||||
template <typename Point>
|
||||
struct coordinate_type
|
||||
{
|
||||
BOOST_MPL_ASSERT_MSG
|
||||
(
|
||||
false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types<Point>)
|
||||
);
|
||||
};
|
||||
|
||||
} // namespace traits
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <boost/geometry/core/coordinate_dimension.hpp>
|
||||
#include <boost/geometry/core/exception.hpp>
|
||||
#include <boost/geometry/core/exterior_ring.hpp>
|
||||
#include <boost/geometry/core/geometry_id.hpp>
|
||||
#include <boost/geometry/core/interior_rings.hpp>
|
||||
|
||||
#include <boost/geometry/geometries/concepts/check.hpp>
|
||||
@@ -692,20 +693,21 @@ Small example showing how to use read_wkt with an output iterator
|
||||
\line {
|
||||
\until }
|
||||
*/
|
||||
template <typename Point, typename OutputIterator>
|
||||
template <typename Geometry, typename OutputIterator>
|
||||
inline void read_wkt(std::string const& wkt, OutputIterator out)
|
||||
{
|
||||
geometry::concept::check<Point>();
|
||||
geometry::concept::check<Geometry>();
|
||||
|
||||
// Todo: maybe take this from the string, or do not call initialize, such that
|
||||
// any coordinate string is parsed and outputted
|
||||
std::string const& tag = "linestring";
|
||||
typedef typename point_type<Geometry>::type point_type;
|
||||
|
||||
std::string const& tag =
|
||||
geometry_id<Geometry>::value == 2 ? "linestring" : "polygon";
|
||||
|
||||
detail::wkt::tokenizer tokens(wkt, boost::char_separator<char>(" ", ",()"));
|
||||
detail::wkt::tokenizer::iterator it;
|
||||
if (detail::wkt::initialize<Point>(tokens, tag, wkt, it))
|
||||
if (detail::wkt::initialize<point_type>(tokens, tag, wkt, it))
|
||||
{
|
||||
detail::wkt::container_inserter<Point>::apply(it, tokens.end(), wkt, out);
|
||||
detail::wkt::container_inserter<point_type>::apply(it, tokens.end(), wkt, out);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user