annotate DEPENDENCIES/generic/include/boost/geometry/algorithms/detail/overlay/overlay.hpp @ 46:d572322e2efe

Fix to .cat file check (was susceptible to DOS line-endings) and subrepo update
author Chris Cannam
date Thu, 07 Aug 2014 14:39:38 +0100
parents 2665513ce2d3
children c530137014c0
rev   line source
Chris@16 1 // Boost.Geometry (aka GGL, Generic Geometry Library)
Chris@16 2
Chris@16 3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands.
Chris@16 4
Chris@16 5 // Use, modification and distribution is subject to the Boost Software License,
Chris@16 6 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8
Chris@16 9 #ifndef BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
Chris@16 10 #define BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP
Chris@16 11
Chris@16 12
Chris@16 13 #include <deque>
Chris@16 14 #include <map>
Chris@16 15
Chris@16 16 #include <boost/range.hpp>
Chris@16 17 #include <boost/mpl/assert.hpp>
Chris@16 18
Chris@16 19
Chris@16 20 #include <boost/geometry/algorithms/detail/overlay/calculate_distance_policy.hpp>
Chris@16 21 #include <boost/geometry/algorithms/detail/overlay/enrich_intersection_points.hpp>
Chris@16 22 #include <boost/geometry/algorithms/detail/overlay/enrichment_info.hpp>
Chris@16 23 #include <boost/geometry/algorithms/detail/overlay/get_turns.hpp>
Chris@16 24 #include <boost/geometry/algorithms/detail/overlay/overlay_type.hpp>
Chris@16 25 #include <boost/geometry/algorithms/detail/overlay/traverse.hpp>
Chris@16 26 #include <boost/geometry/algorithms/detail/overlay/traversal_info.hpp>
Chris@16 27 #include <boost/geometry/algorithms/detail/overlay/turn_info.hpp>
Chris@16 28
Chris@16 29
Chris@16 30 #include <boost/geometry/algorithms/num_points.hpp>
Chris@16 31 #include <boost/geometry/algorithms/reverse.hpp>
Chris@16 32
Chris@16 33 #include <boost/geometry/algorithms/detail/overlay/add_rings.hpp>
Chris@16 34 #include <boost/geometry/algorithms/detail/overlay/assign_parents.hpp>
Chris@16 35 #include <boost/geometry/algorithms/detail/overlay/ring_properties.hpp>
Chris@16 36 #include <boost/geometry/algorithms/detail/overlay/select_rings.hpp>
Chris@16 37
Chris@16 38
Chris@16 39 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
Chris@16 40 # include <boost/geometry/io/dsv/write.hpp>
Chris@16 41 #endif
Chris@16 42
Chris@16 43 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 44 # include <boost/timer.hpp>
Chris@16 45 #endif
Chris@16 46
Chris@16 47
Chris@16 48 namespace boost { namespace geometry
Chris@16 49 {
Chris@16 50
Chris@16 51
Chris@16 52 #ifndef DOXYGEN_NO_DETAIL
Chris@16 53 namespace detail { namespace overlay
Chris@16 54 {
Chris@16 55
Chris@16 56 // Skip for assemble process
Chris@16 57 template <typename TurnInfo>
Chris@16 58 inline bool skip(TurnInfo const& turn_info)
Chris@16 59 {
Chris@16 60 return (turn_info.discarded || turn_info.both(operation_union))
Chris@16 61 && ! turn_info.any_blocked()
Chris@16 62 && ! turn_info.both(operation_intersection)
Chris@16 63 ;
Chris@16 64 }
Chris@16 65
Chris@16 66
Chris@16 67 template <typename TurnPoints, typename Map>
Chris@16 68 inline void map_turns(Map& map, TurnPoints const& turn_points)
Chris@16 69 {
Chris@16 70 typedef typename boost::range_value<TurnPoints>::type turn_point_type;
Chris@16 71 typedef typename turn_point_type::container_type container_type;
Chris@16 72
Chris@16 73 int index = 0;
Chris@16 74 for (typename boost::range_iterator<TurnPoints const>::type
Chris@16 75 it = boost::begin(turn_points);
Chris@16 76 it != boost::end(turn_points);
Chris@16 77 ++it, ++index)
Chris@16 78 {
Chris@16 79 if (! skip(*it))
Chris@16 80 {
Chris@16 81 int op_index = 0;
Chris@16 82 for (typename boost::range_iterator<container_type const>::type
Chris@16 83 op_it = boost::begin(it->operations);
Chris@16 84 op_it != boost::end(it->operations);
Chris@16 85 ++op_it, ++op_index)
Chris@16 86 {
Chris@16 87 ring_identifier ring_id
Chris@16 88 (
Chris@16 89 op_it->seg_id.source_index,
Chris@16 90 op_it->seg_id.multi_index,
Chris@16 91 op_it->seg_id.ring_index
Chris@16 92 );
Chris@16 93 map[ring_id]++;
Chris@16 94 }
Chris@16 95 }
Chris@16 96 }
Chris@16 97 }
Chris@16 98
Chris@16 99
Chris@16 100 template
Chris@16 101 <
Chris@16 102 typename GeometryOut, overlay_type Direction, bool ReverseOut,
Chris@16 103 typename Geometry1, typename Geometry2,
Chris@16 104 typename OutputIterator
Chris@16 105 >
Chris@16 106 inline OutputIterator return_if_one_input_is_empty(Geometry1 const& geometry1,
Chris@16 107 Geometry2 const& geometry2,
Chris@16 108 OutputIterator out)
Chris@16 109 {
Chris@16 110 typedef std::deque
Chris@16 111 <
Chris@16 112 typename geometry::ring_type<GeometryOut>::type
Chris@16 113 > ring_container_type;
Chris@16 114
Chris@16 115 typedef ring_properties<typename geometry::point_type<Geometry1>::type> properties;
Chris@16 116
Chris@16 117 // Silence warning C4127: conditional expression is constant
Chris@16 118 #if defined(_MSC_VER)
Chris@16 119 #pragma warning(push)
Chris@16 120 #pragma warning(disable : 4127)
Chris@16 121 #endif
Chris@16 122
Chris@16 123 // Union: return either of them
Chris@16 124 // Intersection: return nothing
Chris@16 125 // Difference: return first of them
Chris@16 126 if (Direction == overlay_intersection
Chris@16 127 || (Direction == overlay_difference
Chris@16 128 && geometry::num_points(geometry1) == 0))
Chris@16 129 {
Chris@16 130 return out;
Chris@16 131 }
Chris@16 132
Chris@16 133 #if defined(_MSC_VER)
Chris@16 134 #pragma warning(pop)
Chris@16 135 #endif
Chris@16 136
Chris@16 137
Chris@16 138 std::map<ring_identifier, int> empty;
Chris@16 139 std::map<ring_identifier, properties> all_of_one_of_them;
Chris@16 140
Chris@16 141 select_rings<Direction>(geometry1, geometry2, empty, all_of_one_of_them, false);
Chris@16 142 ring_container_type rings;
Chris@16 143 assign_parents(geometry1, geometry2, rings, all_of_one_of_them);
Chris@16 144 return add_rings<GeometryOut>(all_of_one_of_them, geometry1, geometry2, rings, out);
Chris@16 145 }
Chris@16 146
Chris@16 147
Chris@16 148 template
Chris@16 149 <
Chris@16 150 typename Geometry1, typename Geometry2,
Chris@16 151 bool Reverse1, bool Reverse2, bool ReverseOut,
Chris@16 152 typename GeometryOut,
Chris@16 153 overlay_type Direction
Chris@16 154 >
Chris@16 155 struct overlay
Chris@16 156 {
Chris@16 157 template <typename OutputIterator, typename Strategy>
Chris@16 158 static inline OutputIterator apply(
Chris@16 159 Geometry1 const& geometry1, Geometry2 const& geometry2,
Chris@16 160 OutputIterator out,
Chris@16 161 Strategy const& )
Chris@16 162 {
Chris@16 163 if (geometry::num_points(geometry1) == 0
Chris@16 164 && geometry::num_points(geometry2) == 0)
Chris@16 165 {
Chris@16 166 return out;
Chris@16 167 }
Chris@16 168
Chris@16 169 if (geometry::num_points(geometry1) == 0
Chris@16 170 || geometry::num_points(geometry2) == 0)
Chris@16 171 {
Chris@16 172 return return_if_one_input_is_empty
Chris@16 173 <
Chris@16 174 GeometryOut, Direction, ReverseOut
Chris@16 175 >(geometry1, geometry2, out);
Chris@16 176 }
Chris@16 177
Chris@16 178 typedef typename geometry::point_type<GeometryOut>::type point_type;
Chris@16 179 typedef detail::overlay::traversal_turn_info<point_type> turn_info;
Chris@16 180 typedef std::deque<turn_info> container_type;
Chris@16 181
Chris@16 182 typedef std::deque
Chris@16 183 <
Chris@16 184 typename geometry::ring_type<GeometryOut>::type
Chris@16 185 > ring_container_type;
Chris@16 186
Chris@16 187 container_type turn_points;
Chris@16 188
Chris@16 189 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 190 boost::timer timer;
Chris@16 191 #endif
Chris@16 192
Chris@16 193 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
Chris@16 194 std::cout << "get turns" << std::endl;
Chris@16 195 #endif
Chris@16 196 detail::get_turns::no_interrupt_policy policy;
Chris@16 197 geometry::get_turns
Chris@16 198 <
Chris@16 199 Reverse1, Reverse2,
Chris@16 200 detail::overlay::calculate_distance_policy
Chris@16 201 >(geometry1, geometry2, turn_points, policy);
Chris@16 202
Chris@16 203 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 204 std::cout << "get_turns: " << timer.elapsed() << std::endl;
Chris@16 205 #endif
Chris@16 206
Chris@16 207 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
Chris@16 208 std::cout << "enrich" << std::endl;
Chris@16 209 #endif
Chris@16 210 typename Strategy::side_strategy_type side_strategy;
Chris@16 211 geometry::enrich_intersection_points<Reverse1, Reverse2>(turn_points,
Chris@16 212 Direction == overlay_union
Chris@16 213 ? geometry::detail::overlay::operation_union
Chris@16 214 : geometry::detail::overlay::operation_intersection,
Chris@16 215 geometry1, geometry2,
Chris@16 216 side_strategy);
Chris@16 217
Chris@16 218 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 219 std::cout << "enrich_intersection_points: " << timer.elapsed() << std::endl;
Chris@16 220 #endif
Chris@16 221
Chris@16 222
Chris@16 223 #ifdef BOOST_GEOMETRY_DEBUG_ASSEMBLE
Chris@16 224 std::cout << "traverse" << std::endl;
Chris@16 225 #endif
Chris@16 226 // Traverse through intersection/turn points and create rings of them.
Chris@16 227 // Note that these rings are always in clockwise order, even in CCW polygons,
Chris@16 228 // and are marked as "to be reversed" below
Chris@16 229 ring_container_type rings;
Chris@16 230 traverse<Reverse1, Reverse2, Geometry1, Geometry2>::apply
Chris@16 231 (
Chris@16 232 geometry1, geometry2,
Chris@16 233 Direction == overlay_union
Chris@16 234 ? geometry::detail::overlay::operation_union
Chris@16 235 : geometry::detail::overlay::operation_intersection,
Chris@16 236 turn_points, rings
Chris@16 237 );
Chris@16 238
Chris@16 239 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 240 std::cout << "traverse: " << timer.elapsed() << std::endl;
Chris@16 241 #endif
Chris@16 242
Chris@16 243
Chris@16 244 std::map<ring_identifier, int> map;
Chris@16 245 map_turns(map, turn_points);
Chris@16 246
Chris@16 247 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 248 std::cout << "map_turns: " << timer.elapsed() << std::endl;
Chris@16 249 #endif
Chris@16 250
Chris@16 251 typedef ring_properties<typename geometry::point_type<GeometryOut>::type> properties;
Chris@16 252
Chris@16 253 std::map<ring_identifier, properties> selected;
Chris@16 254 select_rings<Direction>(geometry1, geometry2, map, selected, ! turn_points.empty());
Chris@16 255
Chris@16 256 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 257 std::cout << "select_rings: " << timer.elapsed() << std::endl;
Chris@16 258 #endif
Chris@16 259
Chris@16 260
Chris@16 261 // Add rings created during traversal
Chris@16 262 {
Chris@16 263 ring_identifier id(2, 0, -1);
Chris@16 264 for (typename boost::range_iterator<ring_container_type>::type
Chris@16 265 it = boost::begin(rings);
Chris@16 266 it != boost::end(rings);
Chris@16 267 ++it)
Chris@16 268 {
Chris@16 269 selected[id] = properties(*it, true);
Chris@16 270 selected[id].reversed = ReverseOut;
Chris@16 271 id.multi_index++;
Chris@16 272 }
Chris@16 273 }
Chris@16 274
Chris@16 275 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 276 std::cout << "add traversal rings: " << timer.elapsed() << std::endl;
Chris@16 277 #endif
Chris@16 278
Chris@16 279
Chris@16 280 assign_parents(geometry1, geometry2, rings, selected);
Chris@16 281
Chris@16 282 #ifdef BOOST_GEOMETRY_TIME_OVERLAY
Chris@16 283 std::cout << "assign_parents: " << timer.elapsed() << std::endl;
Chris@16 284 #endif
Chris@16 285
Chris@16 286 return add_rings<GeometryOut>(selected, geometry1, geometry2, rings, out);
Chris@16 287 }
Chris@16 288 };
Chris@16 289
Chris@16 290
Chris@16 291 // Metafunction helper for intersection and union
Chris@16 292 template <order_selector Selector, bool Reverse = false>
Chris@16 293 struct do_reverse {};
Chris@16 294
Chris@16 295 template <>
Chris@16 296 struct do_reverse<clockwise, false> : boost::false_type {};
Chris@16 297
Chris@16 298 template <>
Chris@16 299 struct do_reverse<clockwise, true> : boost::true_type {};
Chris@16 300
Chris@16 301 template <>
Chris@16 302 struct do_reverse<counterclockwise, false> : boost::true_type {};
Chris@16 303
Chris@16 304 template <>
Chris@16 305 struct do_reverse<counterclockwise, true> : boost::false_type {};
Chris@16 306
Chris@16 307
Chris@16 308
Chris@16 309 }} // namespace detail::overlay
Chris@16 310 #endif // DOXYGEN_NO_DETAIL
Chris@16 311
Chris@16 312
Chris@16 313 }} // namespace boost::geometry
Chris@16 314
Chris@16 315
Chris@16 316 #endif // BOOST_GEOMETRY_ALGORITHMS_DETAIL_OVERLAY_OVERLAY_HPP