diff --git a/include/boost/geometry/algorithms/detail/sub_geometry.hpp b/include/boost/geometry/algorithms/detail/sub_geometry.hpp index c3db75694..98c191a12 100644 --- a/include/boost/geometry/algorithms/detail/sub_geometry.hpp +++ b/include/boost/geometry/algorithms/detail/sub_geometry.hpp @@ -81,7 +81,13 @@ struct get template struct get { - typedef typename boost::range_value::type sub_type; + typedef typename boost::range_value::type value_type; + typedef typename boost::mpl::if_c + < + boost::is_const::value, + typename boost::add_const::type, + value_type + >::type sub_type; typedef detail_dispatch::sub_geometry::get get_type; typedef typename get_type::result_type result_type; diff --git a/include/boost/geometry/algorithms/touches.hpp b/include/boost/geometry/algorithms/touches.hpp index 2523a26d2..7cb551472 100644 --- a/include/boost/geometry/algorithms/touches.hpp +++ b/include/boost/geometry/algorithms/touches.hpp @@ -408,25 +408,29 @@ struct linestring_linestring #ifndef DOXYGEN_NO_DISPATCH namespace dispatch { +// TODO: Since CastedTags are used is Reverse needed? + template < typename Geometry1, typename Geometry2, typename Tag1 = typename tag::type, typename Tag2 = typename tag::type, + typename CastedTag1 = typename tag_cast::type, + typename CastedTag2 = typename tag_cast::type, bool Reverse = reverse_dispatch::type::value > -struct touches - : detail::touches::areal_areal +struct touches : not_implemented {}; // If reversal is needed, perform it template < typename Geometry1, typename Geometry2, - typename Tag1, typename Tag2 + typename Tag1, typename Tag2, + typename CastedTag1, typename CastedTag2 > -struct touches - : touches +struct touches + : touches { static inline bool apply(Geometry1 const& g1, Geometry2 const& g2) { @@ -434,19 +438,52 @@ struct touches } }; -template -struct touches +// touches(Pt, Pt), touches(Pt, MPt), touches(MPt, MPt) +template +struct touches + : detail::touches::point_geometry +{ + static inline bool apply(Geometry1 const& , Geometry2 const& ) + { + return false; + } +}; + +// touches(Point, Linear), touches(Point, Areal) +template +struct touches : detail::touches::point_geometry {}; +// TODO: support touches(MPt, Linear/Areal) + +// touches(Linestring, Linestring) template -struct touches +struct touches : detail::touches::linestring_linestring {}; -template -struct touches - : detail::touches::linear_areal +// TODO: support touches(MLs, MLs) and touches(Ls, MLs) + +// touches(Linear, Areal) +template +struct touches + : detail::touches::linear_areal +{}; +// e.g. for touches(Poly, MLs) +template +struct touches +{ + static inline bool apply(Areal const& areal, Linear const& linear) + { + return detail::touches::linear_areal::apply(linear, areal); + } +}; + +// touches(Areal, Areal) +template +struct touches + : detail::touches::areal_areal {}; } // namespace dispatch diff --git a/test/multi/algorithms/multi_touches.cpp b/test/multi/algorithms/multi_touches.cpp index 0186c62e3..0389cc8e9 100644 --- a/test/multi/algorithms/multi_touches.cpp +++ b/test/multi/algorithms/multi_touches.cpp @@ -32,6 +32,8 @@ void test_all() { typedef bg::model::polygon

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

linestring; + typedef bg::model::multi_linestring ml; test_self_touches("MULTIPOLYGON(((0 0,0 100,100 100,100 0,0 0)))", false); @@ -62,10 +64,22 @@ void test_all() true); // Touch plus inside - // TODO fix this test_touches("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((20 0,20 10,30 10,30 0,20 0)))", "MULTIPOLYGON(((10 10,10 20,20 20,20 10,10 10)),((22 2,28 2,28 8,22 8,22 2)))", false); + + + test_touches("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((20 0,20 10,30 10,30 0,20 0)))", + "MULTILINESTRING((10 10,10 20,20 20,20 10,10 10),(30 10,30 20,40 20,40 10,30 10))", + true); + + test_touches("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((20 0,20 10,30 10,30 0,20 0)))", + "MULTILINESTRING((10 10,10 20,20 20,20 10,10 10),(22 2,28 2,28 8,22 8,22 2))", + false); + + test_touches("MULTIPOLYGON(((0 0,0 10,10 10,10 0,0 0)),((20 0,20 10,30 10,30 0,20 0)))", + "MULTILINESTRING((10 10,10 20,20 20,20 10,10 10),(50 2,60 2,60 8,50 8,50 2))", + true); } int test_main( int , char* [] )