|
|
00001 // Boost.Geometry (aka GGL, Generic Geometry Library) 00002 // 00003 // Copyright Barend Gehrels 2007-2009, Geodan, Amsterdam, the Netherlands. 00004 // Copyright Bruno Lalande 2008, 2009 00005 // Use, modification and distribution is subject to the Boost Software License, 00006 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at 00007 // http://www.boost.org/LICENSE_1_0.txt) 00008 00009 #ifndef BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP 00010 #define BOOST_GEOMETRY_ALGORITHMS_INTERSECTION_HPP 00011 00012 00013 #include <boost/mpl/if.hpp> 00014 00015 #include <boost/geometry/core/reverse_dispatch.hpp> 00016 #include <boost/geometry/geometries/concepts/check.hpp> 00017 #include <boost/geometry/algorithms/overlay/clip_linestring.hpp> 00018 #include <boost/geometry/algorithms/overlay/assemble.hpp> 00019 00020 00021 00075 namespace boost { namespace geometry 00076 { 00077 00078 00079 #ifndef DOXYGEN_NO_DETAIL 00080 namespace detail { namespace overlay { 00081 00082 00083 00084 // Specializations for "take_one" for intersection 00085 // "one" should be the inner one 00086 00087 // for ring and box 00088 template 00089 < 00090 typename Tag1, typename Geometry1, 00091 typename Tag2, typename Geometry2, 00092 typename GeometryOut 00093 > 00094 struct take_if_1_is_in_2<Tag1, Geometry1, Tag2, Geometry2, GeometryOut, -1> 00095 { 00096 static inline void apply(Geometry1 const& geometry1, 00097 Geometry2 const& geometry2, 00098 GeometryOut& out 00099 ) 00100 { 00101 geometry::convert(geometry1, out); 00102 } 00103 }; 00104 00105 00106 template 00107 < 00108 typename Geometry1, 00109 typename Tag2, typename Geometry2, 00110 typename GeometryOut 00111 > 00112 struct take_if_1_is_in_2<polygon_tag, Geometry1, Tag2, Geometry2, GeometryOut, -1> 00113 { 00114 static inline void apply(Geometry1 const& geometry1, 00115 Geometry2 const& geometry2, 00116 GeometryOut& out 00117 ) 00118 { 00119 geometry::convert(exterior_ring(geometry1), out); 00120 } 00121 }; 00122 00123 00124 template 00125 < 00126 typename Geometry, typename GeometryOut, typename Container 00127 > 00128 struct add_holes<polygon_tag, Geometry, GeometryOut, Container, -1> 00129 { 00130 00131 static inline void apply(Geometry const& geometry, 00132 GeometryOut& out, 00133 Container const& holes 00134 ) 00135 { 00136 std::vector<sortable> v; 00137 sort_interior_rings(holes, v, -1); 00138 00139 // For an intersection, if a ring is containing an inner ring, 00140 // take the outer 00141 00142 std::size_t const n = boost::size(v); 00143 00144 for (std::size_t i = 0; i < n; i++) 00145 { 00146 // So, only if no inners: 00147 if (v[i].index_of_parent == -1) 00148 { 00149 typename geometry::point_type<GeometryOut>::type point; 00150 geometry::point_on_border(holes[v[i].index], point); 00151 if (geometry::within(point, geometry)) 00152 { 00153 typename ring_type<GeometryOut>::type hole; 00154 geometry::convert(holes[v[i].index], hole); 00155 geometry::interior_rings(out).push_back(hole); 00156 } 00157 } 00158 } 00159 } 00160 }; 00161 00162 00163 }} // namespace detail::overlay 00164 #endif // DOXYGEN_NO_DETAIL 00165 00166 00167 #ifndef DOXYGEN_NO_DISPATCH 00168 namespace dispatch 00169 { 00170 00171 template 00172 < 00173 typename Tag1, typename Tag2, typename Tag3, 00174 typename G1, typename G2, 00175 typename OutputIterator, 00176 typename GeometryOut, 00177 typename Strategy 00178 > 00179 struct intersection_inserter 00180 : detail::overlay::overlay_and_assemble 00181 <G1, G2, OutputIterator, GeometryOut, -1, Strategy> 00182 {}; 00183 00184 00185 template 00186 < 00187 typename Segment1, typename Segment2, 00188 typename OutputIterator, typename GeometryOut, 00189 typename Strategy 00190 > 00191 struct intersection_inserter 00192 < 00193 segment_tag, segment_tag, point_tag, 00194 Segment1, Segment2, 00195 OutputIterator, GeometryOut, 00196 Strategy 00197 > 00198 { 00199 static inline OutputIterator apply(Segment1 const& segment1, 00200 Segment2 const& segment2, OutputIterator out, Strategy const& strategy) 00201 { 00202 typedef typename point_type<GeometryOut>::type point_type; 00203 00204 // Get the intersection point (or two points) 00205 segment_intersection_points<point_type> is 00206 = strategy::intersection::relate_cartesian_segments 00207 < 00208 policies::relate::segments_intersection_points 00209 < 00210 Segment1, 00211 Segment2, 00212 segment_intersection_points<point_type> 00213 > 00214 >::apply(segment1, segment2); 00215 00216 for (std::size_t i = 0; i < is.count; i++) 00217 { 00218 GeometryOut p; 00219 geometry::copy_coordinates(is.intersections[i], p); 00220 *out = p; 00221 out++; 00222 } 00223 return out; 00224 } 00225 }; 00226 00227 00228 template 00229 < 00230 typename Linestring, typename Box, 00231 typename OutputIterator, typename GeometryOut, 00232 typename Strategy 00233 > 00234 struct intersection_inserter 00235 < 00236 linestring_tag, box_tag, linestring_tag, 00237 Linestring, Box, 00238 OutputIterator, GeometryOut, 00239 Strategy 00240 > 00241 { 00242 static inline OutputIterator apply(Linestring const& linestring, 00243 Box const& box, OutputIterator out, Strategy const& strategy) 00244 { 00245 typedef typename point_type<GeometryOut>::type point_type; 00246 strategy::intersection::liang_barsky<Box, point_type> lb_strategy; 00247 return detail::intersection::clip_linestring_with_box<GeometryOut>(box, linestring, out, lb_strategy); 00248 } 00249 }; 00250 00251 00252 template 00253 < 00254 typename GeometryTag1, typename GeometryTag2, typename GeometryTag3, 00255 typename Geometry1, typename Geometry2, 00256 typename OutputIterator, typename GeometryOut, 00257 typename Strategy 00258 > 00259 struct intersection_inserter_reversed 00260 { 00261 static inline OutputIterator apply(Geometry1 const& g1, 00262 Geometry2 const& g2, OutputIterator out, 00263 Strategy const& strategy) 00264 { 00265 return intersection_inserter 00266 < 00267 GeometryTag2, GeometryTag1, GeometryTag3, 00268 Geometry2, Geometry1, 00269 OutputIterator, GeometryOut, 00270 Strategy 00271 >::apply(g2, g1, out, strategy); 00272 } 00273 }; 00274 00275 00276 00277 } // namespace dispatch 00278 #endif // DOXYGEN_NO_DISPATCH 00279 00296 template 00297 < 00298 typename GeometryOut, 00299 typename Geometry1, 00300 typename Geometry2, 00301 typename OutputIterator, 00302 typename Strategy 00303 > 00304 inline OutputIterator intersection_inserter(Geometry1 const& geometry1, 00305 Geometry2 const& geometry2, 00306 OutputIterator out, 00307 Strategy const& strategy) 00308 { 00309 concept::check<const Geometry1>(); 00310 concept::check<const Geometry2>(); 00311 00312 return boost::mpl::if_c 00313 < 00314 reverse_dispatch<Geometry1, Geometry2>::type::value, 00315 dispatch::intersection_inserter_reversed 00316 < 00317 typename tag<Geometry1>::type, 00318 typename tag<Geometry2>::type, 00319 typename tag<GeometryOut>::type, 00320 Geometry1, 00321 Geometry2, 00322 OutputIterator, GeometryOut, 00323 Strategy 00324 >, 00325 dispatch::intersection_inserter 00326 < 00327 typename tag<Geometry1>::type, 00328 typename tag<Geometry2>::type, 00329 typename tag<GeometryOut>::type, 00330 Geometry1, 00331 Geometry2, 00332 OutputIterator, GeometryOut, 00333 Strategy 00334 > 00335 >::type::apply(geometry1, geometry2, out, strategy); 00336 } 00337 00338 00353 template 00354 < 00355 typename GeometryOut, 00356 typename Geometry1, 00357 typename Geometry2, 00358 typename OutputIterator 00359 > 00360 inline OutputIterator intersection_inserter(Geometry1 const& geometry1, 00361 Geometry2 const& geometry2, 00362 OutputIterator out) 00363 { 00364 concept::check<const Geometry1>(); 00365 concept::check<const Geometry2>(); 00366 00367 typedef typename geometry::point_type<GeometryOut>::type point_type; 00368 typedef detail::intersection::intersection_point<point_type> ip_type; 00369 00370 typedef strategy_intersection 00371 < 00372 typename cs_tag<point_type>::type, 00373 Geometry1, 00374 Geometry2, 00375 ip_type 00376 > strategy; 00377 00378 return intersection_inserter<GeometryOut>(geometry1, geometry2, out, strategy()); 00379 } 00380 00381 00382 }} // namespace boost::geometry 00383 00384 00385 #endif //GGL_ALGORITHMS_INTERSECTION_HPP
|
December 1, 2009 |
Copyright © 1995-2009 Barend Gehrels, Geodan, Amsterdam Copyright © 2008-2009 Bruno Lalande, Paris Copyright © 2009 Mateusz Loskot, Cadcorp, London |