| // Boost.Geometry (aka GGL, Generic Geometry Library) |
| |
| // Copyright (c) 2007-2011 Barend Gehrels, 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_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP |
| #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP |
| |
| #include <boost/geometry/algorithms/detail/overlay/convert_ring.hpp> |
| #include <boost/geometry/algorithms/detail/overlay/get_ring.hpp> |
| |
| |
| namespace boost { namespace geometry |
| { |
| |
| |
| #ifndef DOXYGEN_NO_DETAIL |
| namespace detail { namespace overlay |
| { |
| |
| template |
| < |
| typename GeometryOut, |
| typename Geometry1, |
| typename Geometry2, |
| typename RingCollection |
| > |
| inline void convert_and_add(GeometryOut& result, |
| Geometry1 const& geometry1, Geometry2 const& geometry2, |
| RingCollection const& collection, |
| ring_identifier id, |
| bool reversed, bool append) |
| { |
| typedef typename geometry::tag<Geometry1>::type tag1; |
| typedef typename geometry::tag<Geometry2>::type tag2; |
| typedef typename geometry::tag<GeometryOut>::type tag_out; |
| |
| if (id.source_index == 0) |
| { |
| convert_ring<tag_out>::apply(result, |
| get_ring<tag1>::apply(id, geometry1), |
| append, reversed); |
| } |
| else if (id.source_index == 1) |
| { |
| convert_ring<tag_out>::apply(result, |
| get_ring<tag2>::apply(id, geometry2), |
| append, reversed); |
| } |
| else if (id.source_index == 2) |
| { |
| convert_ring<tag_out>::apply(result, |
| get_ring<void>::apply(id, collection), |
| append, reversed); |
| } |
| } |
| |
| template |
| < |
| typename GeometryOut, |
| typename SelectionMap, |
| typename Geometry1, |
| typename Geometry2, |
| typename RingCollection, |
| typename OutputIterator |
| > |
| inline OutputIterator add_rings(SelectionMap const& map, |
| Geometry1 const& geometry1, Geometry2 const& geometry2, |
| RingCollection const& collection, |
| OutputIterator out) |
| { |
| typedef typename SelectionMap::const_iterator iterator; |
| |
| for (iterator it = boost::begin(map); |
| it != boost::end(map); |
| ++it) |
| { |
| if (! it->second.discarded |
| && it->second.parent.source_index == -1) |
| { |
| GeometryOut result; |
| convert_and_add(result, geometry1, geometry2, collection, |
| it->first, it->second.reversed, false); |
| |
| // Add children |
| for (typename std::vector<ring_identifier>::const_iterator child_it |
| = it->second.children.begin(); |
| child_it != it->second.children.end(); |
| ++child_it) |
| { |
| iterator mit = map.find(*child_it); |
| if (mit != map.end() |
| && ! mit->second.discarded) |
| { |
| convert_and_add(result, geometry1, geometry2, collection, |
| *child_it, mit->second.reversed, true); |
| } |
| } |
| *out++ = result; |
| } |
| } |
| return out; |
| } |
| |
| |
| template |
| < |
| typename GeometryOut, |
| typename SelectionMap, |
| typename Geometry, |
| typename RingCollection, |
| typename OutputIterator |
| > |
| inline OutputIterator add_rings(SelectionMap const& map, |
| Geometry const& geometry, |
| RingCollection const& collection, |
| OutputIterator out) |
| { |
| Geometry empty; |
| return add_rings<GeometryOut>(map, geometry, empty, collection, out); |
| } |
| |
| |
| }} // namespace detail::overlay |
| #endif // DOXYGEN_NO_DETAIL |
| |
| |
| }} // namespace geometry |
| |
| |
| #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_ADD_RINGS_HPP |