diff --git a/include/boost/geometry/algorithms/intersection.hpp b/include/boost/geometry/algorithms/intersection.hpp index 2a289ddd7..a5b9d6342 100644 --- a/include/boost/geometry/algorithms/intersection.hpp +++ b/include/boost/geometry/algorithms/intersection.hpp @@ -10,21 +10,9 @@ #define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP -#include - -#include -#include -#include - - -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include 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::type point_type; + typedef typename coordinate_type::type ct; - // Get the intersection point (or two points) - segment_intersection_points is - = strategy::intersection::relate_cartesian_segments - < - policies::relate::segments_intersection_points - < - Segment1, - Segment2, - segment_intersection_points - > - >::apply(segment1, segment2); + ct min1 = get(box1); + ct min2 = get(box2); + ct max1 = get(box1); + ct max2 = get(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(box_out, min1 < min2 ? min2 : min1); + set(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 { - 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::type point_type; - - typedef detail::overlay::turn_info turn_info; - std::deque turns; - - geometry::get_intersection_points(linestring1, linestring2, turns); - - for (typename boost::range_iterator 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) - ); + typedef std::back_insert_iterator output_iterator; + + static inline bool apply(Geometry1 const& geometry1, + Geometry2 const& geometry2, + GeometryOut& geometry_out, + Strategy const& strategy) + { + typedef typename boost::range_value::type OneOut; + + intersection_inserter + < + Tag1, Tag2, typename geometry::tag::type, + geometry::is_areal::value, + geometry::is_areal::value, + geometry::is_areal::value, + Geometry1, Geometry2, + detail::overlay::do_reverse::value, false>::value, + detail::overlay::do_reverse::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 - -{}; - - -// 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 - -{}; - - -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::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::type point_type; - strategy::intersection::liang_barsky lb_strategy; - return detail::intersection::clip_range_with_box - (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 range_type; - range_type range(segment); - - typedef typename point_type::type point_type; - strategy::intersection::liang_barsky lb_strategy; - return detail::intersection::clip_range_with_box - (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::type::value, - geometry::dispatch::intersection_inserter_reversed - < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - ////point_order::value, - ////point_order::value, - ////point_order::value, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, - Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::value, Reverse2>::value, - ReverseOut, - OutputIterator, GeometryOut, - Strategy - >, - geometry::dispatch::intersection_inserter - < - typename geometry::tag::type, - typename geometry::tag::type, - typename geometry::tag::type, - ////point_order::value, - ///point_order::value, - ///point_order::value, - geometry::is_areal::value, - geometry::is_areal::value, - geometry::is_areal::value, - Geometry1, Geometry2, - overlay::do_reverse::value, Reverse1>::value, - overlay::do_reverse::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(); - concept::check(); - - return detail::intersection::inserter( - 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(); - concept::check(); - - typedef strategy_intersection - < - typename cs_tag::type, - Geometry1, - Geometry2, - typename geometry::point_type::type - > strategy; - - return intersection_inserter(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(); concept::check(); - typedef typename boost::range_value::type geometry_out; - concept::check(); - typedef strategy_intersection < - typename cs_tag::type, + typename cs_tag::type, Geometry1, Geometry2, - typename geometry::point_type::type + typename geometry::point_type::type > strategy; - intersection_inserter(geometry1, geometry2, - std::back_inserter(output_collection), - strategy()); + return boost::mpl::if_c + < + geometry::reverse_dispatch::type::value, + dispatch::intersection_reversed + < + typename geometry::tag::type, + typename geometry::tag::type, + typename geometry::tag::type, + Geometry1, Geometry2, GeometryOut, strategy + >, + dispatch::intersection + < + typename geometry::tag::type, + typename geometry::tag::type, + typename geometry::tag::type, + Geometry1, Geometry2, GeometryOut, strategy + > + >::type::apply(geometry1, geometry2, geometry_out, strategy()); } diff --git a/include/boost/geometry/algorithms/intersection_inserter.hpp b/include/boost/geometry/algorithms/intersection_inserter.hpp new file mode 100644 index 000000000..870cb0510 --- /dev/null +++ b/include/boost/geometry/algorithms/intersection_inserter.hpp @@ -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 + +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + + +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::type point_type; + + // Get the intersection point (or two points) + segment_intersection_points is + = strategy::intersection::relate_cartesian_segments + < + policies::relate::segments_intersection_points + < + Segment1, + Segment2, + segment_intersection_points + > + >::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::type point_type; + + typedef detail::overlay::turn_info turn_info; + std::deque turns; + + geometry::get_intersection_points(linestring1, linestring2, turns); + + for (typename boost::range_iterator 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) + ); +}; + + +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 + +{}; + + +// 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 + +{}; + +/*// 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 + +{}; +*/ + +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::type point_type; + strategy::intersection::liang_barsky lb_strategy; + return detail::intersection::clip_range_with_box + (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 range_type; + range_type range(segment); + + typedef typename point_type::type point_type; + strategy::intersection::liang_barsky lb_strategy; + return detail::intersection::clip_range_with_box + (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::type::value, + geometry::dispatch::intersection_inserter_reversed + < + typename geometry::tag::type, + typename geometry::tag::type, + typename geometry::tag::type, + geometry::is_areal::value, + geometry::is_areal::value, + geometry::is_areal::value, + Geometry1, Geometry2, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::value, Reverse2>::value, + ReverseOut, + OutputIterator, GeometryOut, + Strategy + >, + geometry::dispatch::intersection_inserter + < + typename geometry::tag::type, + typename geometry::tag::type, + typename geometry::tag::type, + geometry::is_areal::value, + geometry::is_areal::value, + geometry::is_areal::value, + Geometry1, Geometry2, + overlay::do_reverse::value, Reverse1>::value, + overlay::do_reverse::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(); + concept::check(); + + return detail::intersection::inserter( + 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(); + concept::check(); + + typedef strategy_intersection + < + typename cs_tag::type, + Geometry1, + Geometry2, + typename geometry::point_type::type + > strategy; + + return intersection_inserter(geometry1, geometry2, out, + strategy()); +} + + +}} // namespace boost::geometry + + +#endif // BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_INSERTER_HPP diff --git a/include/boost/geometry/core/coordinate_system.hpp b/include/boost/geometry/core/coordinate_system.hpp index e1e0152a9..f0c7cef37 100644 --- a/include/boost/geometry/core/coordinate_system.hpp +++ b/include/boost/geometry/core/coordinate_system.hpp @@ -11,6 +11,7 @@ #define BOOST_GEOMETRY_CORE_COORDINATE_SYSTEM_HPP +#include #include #include @@ -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 - 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 +struct coordinate_system +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types) + ); +}; } // namespace traits diff --git a/include/boost/geometry/core/coordinate_type.hpp b/include/boost/geometry/core/coordinate_type.hpp index e6a9e3a11..c740511eb 100644 --- a/include/boost/geometry/core/coordinate_type.hpp +++ b/include/boost/geometry/core/coordinate_type.hpp @@ -10,6 +10,7 @@ #define BOOST_GEOMETRY_CORE_COORDINATE_TYPE_HPP +#include #include #include @@ -30,8 +31,14 @@ namespace traits \par Specializations should provide: - typedef T type; (double,float,int,etc) */ -template -struct coordinate_type {}; +template +struct coordinate_type +{ + BOOST_MPL_ASSERT_MSG + ( + false, NOT_IMPLEMENTED_FOR_THIS_POINT_TYPE, (types) + ); +}; } // namespace traits diff --git a/include/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp b/include/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp index 62e43b24a..741812c1b 100644 --- a/include/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp +++ b/include/boost/geometry/extensions/gis/io/wkt/read_wkt.hpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -692,20 +693,21 @@ Small example showing how to use read_wkt with an output iterator \line { \until } */ -template +template inline void read_wkt(std::string const& wkt, OutputIterator out) { - geometry::concept::check(); + geometry::concept::check(); - // 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::type point_type; + + std::string const& tag = + geometry_id::value == 2 ? "linestring" : "polygon"; detail::wkt::tokenizer tokens(wkt, boost::char_separator(" ", ",()")); detail::wkt::tokenizer::iterator it; - if (detail::wkt::initialize(tokens, tag, wkt, it)) + if (detail::wkt::initialize(tokens, tag, wkt, it)) { - detail::wkt::container_inserter::apply(it, tokens.end(), wkt, out); + detail::wkt::container_inserter::apply(it, tokens.end(), wkt, out); } }