From 73fd9c49de0682a950c2890d2b17439f9e2deeaa Mon Sep 17 00:00:00 2001 From: Barend Gehrels Date: Sun, 10 Oct 2010 19:47:31 +0000 Subject: [PATCH] Added multi_linestring of intersections Changed intersection dispatching using is_areal [SVN r65892] --- .../geometry/algorithms/intersection.hpp | 50 +++---- include/boost/geometry/core/is_areal.hpp | 54 ++++++++ .../multi/algorithms/intersection.hpp | 129 +++++++++++++++--- .../boost/geometry/multi/core/is_areal.hpp | 37 +++++ test/multi/algorithms/multi_intersection.cpp | 33 +++++ 5 files changed, 262 insertions(+), 41 deletions(-) create mode 100644 include/boost/geometry/core/is_areal.hpp create mode 100644 include/boost/geometry/multi/core/is_areal.hpp diff --git a/include/boost/geometry/algorithms/intersection.hpp b/include/boost/geometry/algorithms/intersection.hpp index b2af587f9..a5c69be35 100644 --- a/include/boost/geometry/algorithms/intersection.hpp +++ b/include/boost/geometry/algorithms/intersection.hpp @@ -18,6 +18,7 @@ #include +#include #include #include #include @@ -101,7 +102,7 @@ struct intersection_linestring_linestring_point -}} // namespace detail::disjoint +}} // namespace detail::intersection #endif // DOXYGEN_NO_DETAIL @@ -112,7 +113,11 @@ namespace dispatch template < + // tag dispatching: typename TagIn1, typename TagIn2, typename TagOut, + // metafunction finetuning helpers: + bool Areal1, bool Areal2, bool ArealOut, + // real types typename Geometry1, typename Geometry2, typename OutputIterator, typename GeometryOut, @@ -130,39 +135,24 @@ struct intersection_inserter template < - typename Polygon1, typename Polygon2, + typename TagIn1, typename TagIn2, typename TagOut, + typename Geometry1, typename Geometry2, typename OutputIterator, - typename PolygonOut, + typename GeometryOut, typename Strategy > struct intersection_inserter < - polygon_tag, polygon_tag, polygon_tag, - Polygon1, Polygon2, - OutputIterator, PolygonOut, + TagIn1, TagIn2, TagOut, + true, true, true, + Geometry1, Geometry2, + OutputIterator, GeometryOut, Strategy > : detail::overlay::overlay - + {}; -template -< - typename Polygon, typename Box, - typename OutputIterator, - typename PolygonOut, - typename Strategy -> -struct intersection_inserter - < - polygon_tag, box_tag, polygon_tag, - Polygon, Box, - OutputIterator, PolygonOut, - Strategy - > : detail::overlay::overlay - -{}; - template < @@ -173,6 +163,7 @@ template struct intersection_inserter < segment_tag, segment_tag, point_tag, + false, false, false, Segment1, Segment2, OutputIterator, GeometryOut, Strategy @@ -194,6 +185,7 @@ template struct intersection_inserter < linestring_tag, linestring_tag, point_tag, + false, false, false, Linestring1, Linestring2, OutputIterator, GeometryOut, Strategy @@ -215,6 +207,7 @@ template struct intersection_inserter < linestring_tag, box_tag, linestring_tag, + false, true, false, Linestring, Box, OutputIterator, GeometryOut, Strategy @@ -239,6 +232,7 @@ template struct intersection_inserter < segment_tag, box_tag, linestring_tag, + false, true, false, Segment, Box, OutputIterator, GeometryOut, Strategy @@ -261,6 +255,7 @@ struct intersection_inserter template < typename GeometryTag1, typename GeometryTag2, typename GeometryTag3, + bool Areal1, bool Areal2, bool ArealOut, typename Geometry1, typename Geometry2, typename OutputIterator, typename GeometryOut, typename Strategy @@ -274,6 +269,7 @@ struct intersection_inserter_reversed return intersection_inserter < GeometryTag2, GeometryTag1, GeometryTag3, + Areal2, Areal1, ArealOut, Geometry2, Geometry1, OutputIterator, GeometryOut, Strategy @@ -331,6 +327,9 @@ inline OutputIterator intersection_inserter(Geometry1 const& geometry1, typename tag::type, typename tag::type, typename tag::type, + is_areal::value, + is_areal::value, + is_areal::value, Geometry1, Geometry2, OutputIterator, GeometryOut, @@ -341,6 +340,9 @@ inline OutputIterator intersection_inserter(Geometry1 const& geometry1, typename tag::type, typename tag::type, typename tag::type, + is_areal::value, + is_areal::value, + is_areal::value, Geometry1, Geometry2, OutputIterator, GeometryOut, diff --git a/include/boost/geometry/core/is_areal.hpp b/include/boost/geometry/core/is_areal.hpp new file mode 100644 index 000000000..0d2933941 --- /dev/null +++ b/include/boost/geometry/core/is_areal.hpp @@ -0,0 +1,54 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands. +// 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_CORE_IS_AREAL_HPP +#define BOOST_GEOMETRY_CORE_IS_AREAL_HPP + + +#include + + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template struct is_areal : boost::false_type {}; + +template <> struct is_areal : boost::true_type {}; +template <> struct is_areal : boost::true_type {}; +template <> struct is_areal : boost::true_type {}; + + +} // namespace core_dispatch +#endif + + + +/*! + \brief Meta-function defining "true" for areal types (box, (multi)polygon, ring), + \note Used for tag dispatching and meta-function finetuning + \note Even though linear_ring is called linear, it has areal properties. + \ingroup core +*/ +template +struct is_areal : core_dispatch::is_areal::type> +{}; + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_CORE_IS_AREAL_HPP diff --git a/include/boost/geometry/multi/algorithms/intersection.hpp b/include/boost/geometry/multi/algorithms/intersection.hpp index e214d245d..203dcf345 100644 --- a/include/boost/geometry/multi/algorithms/intersection.hpp +++ b/include/boost/geometry/multi/algorithms/intersection.hpp @@ -10,51 +10,146 @@ #include +#include #include namespace boost { namespace geometry { +#ifndef DOXYGEN_NO_DETAIL +namespace detail { namespace intersection +{ + + +template +< + typename MultiLinestring1, typename MultiLinestring2, + typename OutputIterator, typename PointOut, + typename Strategy +> +struct intersection_multi_linestring_multi_linestring_point +{ + static inline OutputIterator apply(MultiLinestring1 const& ml1, + MultiLinestring2 const& ml2, OutputIterator out, + Strategy const& strategy) + { + // Note, this loop is quadratic w.r.t. number of linestrings per input. + // Future Enhancement: first do the sections of each, then intersect. + for (typename boost::range_iterator + < + MultiLinestring1 const + >::type it1 = boost::begin(ml1); + it1 != boost::end(ml1); + ++it1) + { + for (typename boost::range_iterator + < + MultiLinestring2 const + >::type it2 = boost::begin(ml2); + it2 != boost::end(ml2); + ++it2) + { + out = intersection_linestring_linestring_point + < + typename boost::range_value::type, + typename boost::range_value::type, + OutputIterator, PointOut, Strategy + >::apply(*it1, *it2, out, strategy); + } + } + + return out; + } +}; + + +template +< + typename Linestring, typename MultiLinestring, + typename OutputIterator, typename PointOut, + typename Strategy +> +struct intersection_linestring_multi_linestring_point +{ + static inline OutputIterator apply(Linestring const& linestring, + MultiLinestring const& ml, OutputIterator out, + Strategy const& strategy) + { + for (typename boost::range_iterator + < + MultiLinestring const + >::type it = boost::begin(ml); + it != boost::end(ml); + ++it) + { + out = intersection_linestring_linestring_point + < + Linestring, + typename boost::range_value::type, + OutputIterator, PointOut, Strategy + >::apply(linestring, *it, out, strategy); + } + + return out; + } +}; + + + + + +}} // namespace detail::intersection +#endif // DOXYGEN_NO_DETAIL + + #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { +// Linear template < - typename Polygon, typename MultiPolygon, - typename OutputIterator, - typename PolygonOut, + typename MultiLinestring1, typename MultiLinestring2, + typename OutputIterator, typename GeometryOut, typename Strategy > struct intersection_inserter < - polygon_tag, multi_polygon_tag, polygon_tag, - Polygon, MultiPolygon, - OutputIterator, PolygonOut, + multi_linestring_tag, multi_linestring_tag, point_tag, + false, false, false, + MultiLinestring1, MultiLinestring2, + OutputIterator, GeometryOut, Strategy - > : detail::overlay::overlay - + > : detail::intersection::intersection_multi_linestring_multi_linestring_point + < + MultiLinestring1, MultiLinestring2, + OutputIterator, GeometryOut, + Strategy + > {}; - template < - typename MultiPolygon1, typename MultiPolygon2, - typename OutputIterator, - typename PolygonOut, + typename Linestring, typename MultiLinestring, + typename OutputIterator, typename GeometryOut, typename Strategy > struct intersection_inserter < - multi_polygon_tag, multi_polygon_tag, polygon_tag, - MultiPolygon1, MultiPolygon2, - OutputIterator, PolygonOut, + linestring_tag, multi_linestring_tag, point_tag, + false, false, false, + Linestring, MultiLinestring, + OutputIterator, GeometryOut, Strategy - > : detail::overlay::overlay - + > : detail::intersection::intersection_linestring_multi_linestring_point + < + Linestring, MultiLinestring, + OutputIterator, GeometryOut, + Strategy + > {}; diff --git a/include/boost/geometry/multi/core/is_areal.hpp b/include/boost/geometry/multi/core/is_areal.hpp new file mode 100644 index 000000000..3cec4da94 --- /dev/null +++ b/include/boost/geometry/multi/core/is_areal.hpp @@ -0,0 +1,37 @@ +// Boost.Geometry (aka GGL, Generic Geometry Library) +// +// Copyright Barend Gehrels 2010, Geodan, Amsterdam, the Netherlands. +// 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_MULTI_CORE_IS_AREAL_HPP +#define BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP + + +#include + + +#include +#include + + +namespace boost { namespace geometry +{ + + +#ifndef DOXYGEN_NO_DISPATCH +namespace core_dispatch +{ + +template <> struct is_areal : boost::true_type {}; + +} // namespace core_dispatch +#endif + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_MULTI_CORE_IS_AREAL_HPP diff --git a/test/multi/algorithms/multi_intersection.cpp b/test/multi/algorithms/multi_intersection.cpp index 4c30b924f..c7d6817ec 100644 --- a/test/multi/algorithms/multi_intersection.cpp +++ b/test/multi/algorithms/multi_intersection.cpp @@ -15,6 +15,7 @@ #include +#include #include #include @@ -27,9 +28,13 @@ void test_all() // polygon/multi polygon and ring/multi polygon are tested in union namespace bg = boost::geometry; + typedef bg::linear_ring

ring; typedef bg::polygon

polygon; typedef bg::multi_polygon multi_polygon; + typedef bg::linestring

linestring; + typedef bg::multi_linestring multi_linestring; + test_one("simplex_multi", case_multi_simplex[0], case_multi_simplex[1], 2, 12, 6.42); @@ -40,6 +45,34 @@ void test_all() test_one("case_multi_2", case_multi_2[0], case_multi_2[1], 3, 12, 5.9); + + test_one("simplex_multi_mp_p", + case_multi_simplex[0], case_single_simplex, + 1, 20, 14.58); + + test_one("simplex_multi_r_mp", + case_single_simplex, case_multi_simplex[0], + 1, 20, 14.58); + /*test_one("simplex_multi_mp_r", + case_multi_simplex[0], case_single_simplex, + 1, 20, 14.58);*/ + + + // linear + test_one("case_multi_linear_1", + "MULTILINESTRING((0 0,1 1))", "MULTILINESTRING((0 1,1 0))", + 1, 1, 0); + test_one("case_multi_linear_2", + "MULTILINESTRING((0 0,1 1),(0.5 0,1.5 1))", "MULTILINESTRING((0 1,1 0),(0.5 1,1.5 0))", + 4, 4, 0); + + test_one("case_multi_linear_3", + "LINESTRING(0 0,1 1)", "MULTILINESTRING((0 1,1 0),(0.5 1,1.5 0))", + 2, 2, 0); + test_one("case_multi_linear_4", + "MULTILINESTRING((0 1,1 0),(0.5 1,1.5 0))", "LINESTRING(0 0,1 1)", + 2, 2, 0); + }