Chris@16: // Boost.Geometry (aka GGL, Generic Geometry Library) Chris@16: Chris@16: // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. Chris@16: // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. Chris@16: // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. Chris@16: Chris@16: // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library Chris@16: // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. Chris@16: Chris@16: // Use, modification and distribution is subject to the Boost Software License, Chris@16: // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP Chris@16: #define BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP Chris@16: Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@101: #include Chris@101: #include Chris@101: #include Chris@16: Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: Chris@101: #include Chris@16: Chris@16: namespace boost { namespace geometry Chris@16: { Chris@16: Chris@16: Chris@16: #ifndef DOXYGEN_NO_DETAIL Chris@16: namespace detail { namespace buffer Chris@16: { Chris@16: Chris@16: template Chris@16: struct box_loop Chris@16: { Chris@16: typedef typename coordinate_type::type coordinate_type; Chris@16: Chris@16: static inline void apply(BoxIn const& box_in, T const& distance, BoxOut& box_out) Chris@16: { Chris@16: coordinate_type d = distance; Chris@16: set(box_out, get(box_in) + d); Chris@16: box_loop::apply(box_in, distance, box_out); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct box_loop Chris@16: { Chris@16: static inline void apply(BoxIn const&, T const&, BoxOut&) {} Chris@16: }; Chris@16: Chris@16: // Extends a box with the same amount in all directions Chris@16: template Chris@16: inline void buffer_box(BoxIn const& box_in, T const& distance, BoxOut& box_out) Chris@16: { Chris@16: assert_dimension_equal(); Chris@16: Chris@16: static const std::size_t N = dimension::value; Chris@16: Chris@16: box_loop::apply(box_in, -distance, box_out); Chris@16: box_loop::apply(box_in, distance, box_out); Chris@16: } Chris@16: Chris@16: Chris@16: Chris@16: }} // namespace detail::buffer Chris@16: #endif // DOXYGEN_NO_DETAIL Chris@16: Chris@16: #ifndef DOXYGEN_NO_DISPATCH Chris@16: namespace dispatch Chris@16: { Chris@16: Chris@16: template Chris@16: < Chris@16: typename Input, Chris@16: typename Output, Chris@16: typename TagIn = typename tag::type, Chris@16: typename TagOut = typename tag::type Chris@16: > Chris@16: struct buffer: not_implemented Chris@16: {}; Chris@16: Chris@16: Chris@16: template Chris@16: struct buffer Chris@16: { Chris@16: template Chris@16: static inline void apply(BoxIn const& box_in, Distance const& distance, Chris@101: Distance const& , BoxOut& box_out) Chris@16: { Chris@16: detail::buffer::buffer_box(box_in, distance, box_out); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace dispatch Chris@16: #endif // DOXYGEN_NO_DISPATCH Chris@16: Chris@16: Chris@101: namespace resolve_variant { Chris@101: Chris@101: template Chris@101: struct buffer Chris@101: { Chris@101: template Chris@101: static inline void apply(Geometry const& geometry, Chris@101: Distance const& distance, Chris@101: Distance const& chord_length, Chris@101: GeometryOut& out) Chris@101: { Chris@101: dispatch::buffer::apply(geometry, distance, chord_length, out); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: struct buffer > Chris@101: { Chris@101: template Chris@101: struct visitor: boost::static_visitor Chris@101: { Chris@101: Distance const& m_distance; Chris@101: Distance const& m_chord_length; Chris@101: GeometryOut& m_out; Chris@101: Chris@101: visitor(Distance const& distance, Chris@101: Distance const& chord_length, Chris@101: GeometryOut& out) Chris@101: : m_distance(distance), Chris@101: m_chord_length(chord_length), Chris@101: m_out(out) Chris@101: {} Chris@101: Chris@101: template Chris@101: void operator()(Geometry const& geometry) const Chris@101: { Chris@101: buffer::apply(geometry, m_distance, m_chord_length, m_out); Chris@101: } Chris@101: }; Chris@101: Chris@101: template Chris@101: static inline void apply( Chris@101: boost::variant const& geometry, Chris@101: Distance const& distance, Chris@101: Distance const& chord_length, Chris@101: GeometryOut& out Chris@101: ) Chris@101: { Chris@101: boost::apply_visitor(visitor(distance, chord_length, out), geometry); Chris@101: } Chris@101: }; Chris@101: Chris@101: } // namespace resolve_variant Chris@101: Chris@101: Chris@16: /*! Chris@16: \brief \brief_calc{buffer} Chris@16: \ingroup buffer Chris@16: \details \details_calc{buffer, \det_buffer}. Chris@16: \tparam Input \tparam_geometry Chris@16: \tparam Output \tparam_geometry Chris@16: \tparam Distance \tparam_numeric Chris@16: \param geometry_in \param_geometry Chris@16: \param geometry_out \param_geometry Chris@16: \param distance The distance to be used for the buffer Chris@16: \param chord_length (optional) The length of the chord's in the generated arcs around points or bends Chris@16: Chris@16: \qbk{[include reference/algorithms/buffer.qbk]} Chris@16: */ Chris@16: template Chris@16: inline void buffer(Input const& geometry_in, Output& geometry_out, Chris@16: Distance const& distance, Distance const& chord_length = -1) Chris@16: { Chris@16: concept::check(); Chris@16: concept::check(); Chris@16: Chris@101: resolve_variant::buffer::apply(geometry_in, distance, chord_length, geometry_out); Chris@16: } Chris@16: Chris@16: /*! Chris@16: \brief \brief_calc{buffer} Chris@16: \ingroup buffer Chris@16: \details \details_calc{return_buffer, \det_buffer}. \details_return{buffer}. Chris@16: \tparam Input \tparam_geometry Chris@16: \tparam Output \tparam_geometry Chris@16: \tparam Distance \tparam_numeric Chris@16: \param geometry \param_geometry Chris@16: \param distance The distance to be used for the buffer Chris@16: \param chord_length (optional) The length of the chord's in the generated arcs Chris@101: around points or bends (RESERVED, NOT YET USED) Chris@16: \return \return_calc{buffer} Chris@16: */ Chris@16: template Chris@16: Output return_buffer(Input const& geometry, Distance const& distance, Distance const& chord_length = -1) Chris@16: { Chris@16: concept::check(); Chris@16: concept::check(); Chris@16: Chris@16: Output geometry_out; Chris@16: Chris@101: resolve_variant::buffer::apply(geometry, distance, chord_length, geometry_out); Chris@16: Chris@16: return geometry_out; Chris@16: } Chris@16: Chris@101: /*! Chris@101: \brief \brief_calc{buffer} Chris@101: \ingroup buffer Chris@101: \details \details_calc{buffer, \det_buffer}. Chris@101: \tparam GeometryIn \tparam_geometry Chris@101: \tparam MultiPolygon \tparam_geometry{MultiPolygon} Chris@101: \tparam DistanceStrategy A strategy defining distance (or radius) Chris@101: \tparam SideStrategy A strategy defining creation along sides Chris@101: \tparam JoinStrategy A strategy defining creation around convex corners Chris@101: \tparam EndStrategy A strategy defining creation at linestring ends Chris@101: \tparam PointStrategy A strategy defining creation around points Chris@101: \param geometry_in \param_geometry Chris@101: \param geometry_out output multi polygon (or std:: collection of polygons), Chris@101: will contain a buffered version of the input geometry Chris@101: \param distance_strategy The distance strategy to be used Chris@101: \param side_strategy The side strategy to be used Chris@101: \param join_strategy The join strategy to be used Chris@101: \param end_strategy The end strategy to be used Chris@101: \param point_strategy The point strategy to be used Chris@101: Chris@101: \qbk{distinguish,with strategies} Chris@101: \qbk{[include reference/algorithms/buffer_with_strategies.qbk]} Chris@101: */ Chris@101: template Chris@101: < Chris@101: typename GeometryIn, Chris@101: typename MultiPolygon, Chris@101: typename DistanceStrategy, Chris@101: typename SideStrategy, Chris@101: typename JoinStrategy, Chris@101: typename EndStrategy, Chris@101: typename PointStrategy Chris@101: > Chris@101: inline void buffer(GeometryIn const& geometry_in, Chris@101: MultiPolygon& geometry_out, Chris@101: DistanceStrategy const& distance_strategy, Chris@101: SideStrategy const& side_strategy, Chris@101: JoinStrategy const& join_strategy, Chris@101: EndStrategy const& end_strategy, Chris@101: PointStrategy const& point_strategy) Chris@101: { Chris@101: typedef typename boost::range_value::type polygon_type; Chris@101: concept::check(); Chris@101: concept::check(); Chris@101: Chris@101: typedef typename point_type::type point_type; Chris@101: typedef typename rescale_policy_type::type rescale_policy_type; Chris@101: Chris@101: geometry_out.clear(); Chris@101: Chris@101: model::box box; Chris@101: envelope(geometry_in, box); Chris@101: buffer(box, box, distance_strategy.max_distance(join_strategy, end_strategy)); Chris@101: Chris@101: rescale_policy_type rescale_policy Chris@101: = boost::geometry::get_rescale_policy(box); Chris@101: Chris@101: detail::buffer::buffer_inserter(geometry_in, std::back_inserter(geometry_out), Chris@101: distance_strategy, Chris@101: side_strategy, Chris@101: join_strategy, Chris@101: end_strategy, Chris@101: point_strategy, Chris@101: rescale_policy); Chris@101: } Chris@101: Chris@101: Chris@16: }} // namespace boost::geometry Chris@16: Chris@16: #endif // BOOST_GEOMETRY_ALGORITHMS_BUFFER_HPP