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