Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/geometry/algorithms/length.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 // Boost.Geometry (aka GGL, Generic Geometry Library) | |
2 | |
3 // Copyright (c) 2007-2012 Barend Gehrels, Amsterdam, the Netherlands. | |
4 // Copyright (c) 2008-2012 Bruno Lalande, Paris, France. | |
5 // Copyright (c) 2009-2012 Mateusz Loskot, London, UK. | |
6 | |
7 // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
8 // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
9 | |
10 // Use, modification and distribution is subject to the Boost Software License, | |
11 // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
12 // http://www.boost.org/LICENSE_1_0.txt) | |
13 | |
14 #ifndef BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP | |
15 #define BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP | |
16 | |
17 #include <iterator> | |
18 | |
19 #include <boost/concept_check.hpp> | |
20 #include <boost/range.hpp> | |
21 | |
22 #include <boost/mpl/fold.hpp> | |
23 #include <boost/mpl/greater.hpp> | |
24 #include <boost/mpl/if.hpp> | |
25 #include <boost/mpl/insert.hpp> | |
26 #include <boost/mpl/int.hpp> | |
27 #include <boost/mpl/set.hpp> | |
28 #include <boost/mpl/size.hpp> | |
29 #include <boost/mpl/transform.hpp> | |
30 #include <boost/type_traits.hpp> | |
31 | |
32 #include <boost/geometry/core/cs.hpp> | |
33 #include <boost/geometry/core/closure.hpp> | |
34 | |
35 #include <boost/geometry/geometries/concepts/check.hpp> | |
36 | |
37 #include <boost/geometry/algorithms/assign.hpp> | |
38 #include <boost/geometry/algorithms/detail/calculate_null.hpp> | |
39 // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp> | |
40 #include <boost/geometry/views/closeable_view.hpp> | |
41 #include <boost/geometry/strategies/distance.hpp> | |
42 #include <boost/geometry/strategies/default_length_result.hpp> | |
43 | |
44 #include <boost/variant/apply_visitor.hpp> | |
45 #include <boost/variant/static_visitor.hpp> | |
46 #include <boost/variant/variant_fwd.hpp> | |
47 | |
48 | |
49 namespace boost { namespace geometry | |
50 { | |
51 | |
52 | |
53 #ifndef DOXYGEN_NO_DETAIL | |
54 namespace detail { namespace length | |
55 { | |
56 | |
57 | |
58 template<typename Segment> | |
59 struct segment_length | |
60 { | |
61 template <typename Strategy> | |
62 static inline typename default_length_result<Segment>::type apply( | |
63 Segment const& segment, Strategy const& strategy) | |
64 { | |
65 typedef typename point_type<Segment>::type point_type; | |
66 point_type p1, p2; | |
67 geometry::detail::assign_point_from_index<0>(segment, p1); | |
68 geometry::detail::assign_point_from_index<1>(segment, p2); | |
69 return strategy.apply(p1, p2); | |
70 } | |
71 }; | |
72 | |
73 /*! | |
74 \brief Internal, calculates length of a linestring using iterator pairs and | |
75 specified strategy | |
76 \note for_each could be used here, now that point_type is changed by boost | |
77 range iterator | |
78 */ | |
79 template<typename Range, closure_selector Closure> | |
80 struct range_length | |
81 { | |
82 typedef typename default_length_result<Range>::type return_type; | |
83 | |
84 template <typename Strategy> | |
85 static inline return_type apply( | |
86 Range const& range, Strategy const& strategy) | |
87 { | |
88 boost::ignore_unused_variable_warning(strategy); | |
89 typedef typename closeable_view<Range const, Closure>::type view_type; | |
90 typedef typename boost::range_iterator | |
91 < | |
92 view_type const | |
93 >::type iterator_type; | |
94 | |
95 return_type sum = return_type(); | |
96 view_type view(range); | |
97 iterator_type it = boost::begin(view), end = boost::end(view); | |
98 if(it != end) | |
99 { | |
100 for(iterator_type previous = it++; | |
101 it != end; | |
102 ++previous, ++it) | |
103 { | |
104 // Add point-point distance using the return type belonging | |
105 // to strategy | |
106 sum += strategy.apply(*previous, *it); | |
107 } | |
108 } | |
109 | |
110 return sum; | |
111 } | |
112 }; | |
113 | |
114 | |
115 }} // namespace detail::length | |
116 #endif // DOXYGEN_NO_DETAIL | |
117 | |
118 | |
119 #ifndef DOXYGEN_NO_DISPATCH | |
120 namespace dispatch | |
121 { | |
122 | |
123 | |
124 template <typename Geometry, typename Tag = typename tag<Geometry>::type> | |
125 struct length : detail::calculate_null | |
126 { | |
127 typedef typename default_length_result<Geometry>::type return_type; | |
128 | |
129 template <typename Strategy> | |
130 static inline return_type apply(Geometry const& geometry, Strategy const& strategy) | |
131 { | |
132 return calculate_null::apply<return_type>(geometry, strategy); | |
133 } | |
134 }; | |
135 | |
136 | |
137 template <typename Geometry> | |
138 struct length<Geometry, linestring_tag> | |
139 : detail::length::range_length<Geometry, closed> | |
140 {}; | |
141 | |
142 | |
143 // RING: length is currently 0; it might be argued that it is the "perimeter" | |
144 | |
145 | |
146 template <typename Geometry> | |
147 struct length<Geometry, segment_tag> | |
148 : detail::length::segment_length<Geometry> | |
149 {}; | |
150 | |
151 | |
152 template <typename Geometry> | |
153 struct devarianted_length | |
154 { | |
155 typedef typename default_length_result<Geometry>::type result_type; | |
156 | |
157 template <typename Strategy> | |
158 static inline result_type apply(Geometry const& geometry, | |
159 Strategy const& strategy) | |
160 { | |
161 return length<Geometry>::apply(geometry, strategy); | |
162 } | |
163 }; | |
164 | |
165 template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
166 struct devarianted_length<variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
167 { | |
168 typedef typename mpl::fold< | |
169 typename mpl::transform< | |
170 typename variant<BOOST_VARIANT_ENUM_PARAMS(T)>::types, | |
171 default_length_result<mpl::_> | |
172 >::type, | |
173 mpl::set0<>, | |
174 mpl::insert<mpl::_1, mpl::_2> | |
175 >::type possible_result_types; | |
176 | |
177 typedef typename mpl::if_< | |
178 mpl::greater< | |
179 mpl::size<possible_result_types>, | |
180 mpl::int_<1> | |
181 >, | |
182 typename make_variant_over<possible_result_types>::type, | |
183 typename mpl::front<possible_result_types>::type | |
184 >::type result_type; | |
185 | |
186 template <typename Strategy> | |
187 struct visitor | |
188 : static_visitor<result_type> | |
189 { | |
190 Strategy const& m_strategy; | |
191 | |
192 visitor(Strategy const& strategy) | |
193 : m_strategy(strategy) | |
194 {} | |
195 | |
196 template <typename Geometry> | |
197 inline typename devarianted_length<Geometry>::result_type | |
198 operator()(Geometry const& geometry) const | |
199 { | |
200 return devarianted_length<Geometry>::apply(geometry, m_strategy); | |
201 } | |
202 }; | |
203 | |
204 template <typename Strategy> | |
205 static inline result_type apply( | |
206 variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, | |
207 Strategy const& strategy | |
208 ) | |
209 { | |
210 return apply_visitor(visitor<Strategy>(strategy), geometry); | |
211 } | |
212 }; | |
213 | |
214 | |
215 } // namespace dispatch | |
216 #endif // DOXYGEN_NO_DISPATCH | |
217 | |
218 | |
219 /*! | |
220 \brief \brief_calc{length} | |
221 \ingroup length | |
222 \details \details_calc{length, length (the sum of distances between consecutive points)}. \details_default_strategy | |
223 \tparam Geometry \tparam_geometry | |
224 \param geometry \param_geometry | |
225 \return \return_calc{length} | |
226 | |
227 \qbk{[include reference/algorithms/length.qbk]} | |
228 \qbk{[length] [length_output]} | |
229 */ | |
230 template<typename Geometry> | |
231 inline typename dispatch::devarianted_length<Geometry>::result_type | |
232 length(Geometry const& geometry) | |
233 { | |
234 concept::check<Geometry const>(); | |
235 | |
236 // detail::throw_on_empty_input(geometry); | |
237 | |
238 typedef typename strategy::distance::services::default_strategy | |
239 < | |
240 point_tag, typename point_type<Geometry>::type | |
241 >::type strategy_type; | |
242 | |
243 return dispatch::devarianted_length<Geometry>::apply(geometry, strategy_type()); | |
244 } | |
245 | |
246 | |
247 /*! | |
248 \brief \brief_calc{length} \brief_strategy | |
249 \ingroup length | |
250 \details \details_calc{length, length (the sum of distances between consecutive points)} \brief_strategy. \details_strategy_reasons | |
251 \tparam Geometry \tparam_geometry | |
252 \tparam Strategy \tparam_strategy{distance} | |
253 \param geometry \param_geometry | |
254 \param strategy \param_strategy{distance} | |
255 \return \return_calc{length} | |
256 | |
257 \qbk{distinguish,with strategy} | |
258 \qbk{[include reference/algorithms/length.qbk]} | |
259 \qbk{[length_with_strategy] [length_with_strategy_output]} | |
260 */ | |
261 template<typename Geometry, typename Strategy> | |
262 inline typename dispatch::devarianted_length<Geometry>::result_type | |
263 length(Geometry const& geometry, Strategy const& strategy) | |
264 { | |
265 concept::check<Geometry const>(); | |
266 | |
267 // detail::throw_on_empty_input(geometry); | |
268 | |
269 return dispatch::devarianted_length<Geometry>::apply(geometry, strategy); | |
270 } | |
271 | |
272 | |
273 }} // namespace boost::geometry | |
274 | |
275 #endif // BOOST_GEOMETRY_ALGORITHMS_LENGTH_HPP |