]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Geometry (aka GGL, Generic Geometry Library) |
2 | ||
3 | // Copyright (c) 2007-2014 Barend Gehrels, Amsterdam, the Netherlands. | |
4 | // Copyright (c) 2008-2014 Bruno Lalande, Paris, France. | |
5 | // Copyright (c) 2009-2014 Mateusz Loskot, London, UK. | |
6 | ||
7 | // This file was modified by Oracle on 2014. | |
8 | // Modifications copyright (c) 2014, Oracle and/or its affiliates. | |
9 | ||
10 | // Contributed and/or modified by Menelaos Karavelas, on behalf of Oracle | |
11 | ||
12 | // Parts of Boost.Geometry are redesigned from Geodan's Geographic Library | |
13 | // (geolib/GGL), copyright (c) 1995-2010 Geodan, Amsterdam, the Netherlands. | |
14 | ||
15 | // Use, modification and distribution is subject to the Boost Software License, | |
16 | // Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at | |
17 | // http://www.boost.org/LICENSE_1_0.txt) | |
18 | ||
19 | #ifndef BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP | |
20 | #define BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP | |
21 | ||
22 | #include <boost/range/metafunctions.hpp> | |
23 | ||
24 | #include <boost/variant/apply_visitor.hpp> | |
25 | #include <boost/variant/static_visitor.hpp> | |
26 | #include <boost/variant/variant_fwd.hpp> | |
27 | ||
28 | #include <boost/geometry/algorithms/length.hpp> | |
29 | #include <boost/geometry/algorithms/detail/calculate_null.hpp> | |
30 | #include <boost/geometry/algorithms/detail/calculate_sum.hpp> | |
31 | #include <boost/geometry/algorithms/detail/multi_sum.hpp> | |
32 | // #include <boost/geometry/algorithms/detail/throw_on_empty_input.hpp> | |
33 | #include <boost/geometry/core/cs.hpp> | |
34 | #include <boost/geometry/core/closure.hpp> | |
35 | #include <boost/geometry/core/tags.hpp> | |
36 | #include <boost/geometry/geometries/concepts/check.hpp> | |
37 | #include <boost/geometry/strategies/default_length_result.hpp> | |
38 | #include <boost/geometry/strategies/default_strategy.hpp> | |
39 | ||
40 | namespace boost { namespace geometry | |
41 | { | |
42 | ||
43 | #ifndef DOXYGEN_NO_DISPATCH | |
44 | namespace dispatch | |
45 | { | |
46 | ||
47 | // Default perimeter is 0.0, specializations implement calculated values | |
48 | template <typename Geometry, typename Tag = typename tag<Geometry>::type> | |
49 | struct perimeter : detail::calculate_null | |
50 | { | |
51 | typedef typename default_length_result<Geometry>::type return_type; | |
52 | ||
53 | template <typename Strategy> | |
54 | static inline return_type apply(Geometry const& geometry, Strategy const& strategy) | |
55 | { | |
56 | return calculate_null::apply<return_type>(geometry, strategy); | |
57 | } | |
58 | }; | |
59 | ||
60 | template <typename Geometry> | |
61 | struct perimeter<Geometry, ring_tag> | |
62 | : detail::length::range_length | |
63 | < | |
64 | Geometry, | |
65 | closure<Geometry>::value | |
66 | > | |
67 | {}; | |
68 | ||
69 | template <typename Polygon> | |
70 | struct perimeter<Polygon, polygon_tag> : detail::calculate_polygon_sum | |
71 | { | |
72 | typedef typename default_length_result<Polygon>::type return_type; | |
73 | typedef detail::length::range_length | |
74 | < | |
75 | typename ring_type<Polygon>::type, | |
76 | closure<Polygon>::value | |
77 | > policy; | |
78 | ||
79 | template <typename Strategy> | |
80 | static inline return_type apply(Polygon const& polygon, Strategy const& strategy) | |
81 | { | |
82 | return calculate_polygon_sum::apply<return_type, policy>(polygon, strategy); | |
83 | } | |
84 | }; | |
85 | ||
86 | template <typename MultiPolygon> | |
87 | struct perimeter<MultiPolygon, multi_polygon_tag> : detail::multi_sum | |
88 | { | |
89 | typedef typename default_length_result<MultiPolygon>::type return_type; | |
90 | ||
91 | template <typename Strategy> | |
92 | static inline return_type apply(MultiPolygon const& multi, Strategy const& strategy) | |
93 | { | |
94 | return multi_sum::apply | |
95 | < | |
96 | return_type, | |
97 | perimeter<typename boost::range_value<MultiPolygon>::type> | |
98 | >(multi, strategy); | |
99 | } | |
100 | }; | |
101 | ||
102 | ||
103 | // box,n-sphere: to be implemented | |
104 | ||
105 | } // namespace dispatch | |
106 | #endif // DOXYGEN_NO_DISPATCH | |
107 | ||
108 | ||
109 | namespace resolve_strategy { | |
110 | ||
111 | struct perimeter | |
112 | { | |
113 | template <typename Geometry, typename Strategy> | |
114 | static inline typename default_length_result<Geometry>::type | |
115 | apply(Geometry const& geometry, Strategy const& strategy) | |
116 | { | |
117 | return dispatch::perimeter<Geometry>::apply(geometry, strategy); | |
118 | } | |
119 | ||
120 | template <typename Geometry> | |
121 | static inline typename default_length_result<Geometry>::type | |
122 | apply(Geometry const& geometry, default_strategy) | |
123 | { | |
124 | typedef typename strategy::distance::services::default_strategy | |
125 | < | |
126 | point_tag, point_tag, typename point_type<Geometry>::type | |
127 | >::type strategy_type; | |
128 | ||
129 | return dispatch::perimeter<Geometry>::apply(geometry, strategy_type()); | |
130 | } | |
131 | }; | |
132 | ||
133 | } // namespace resolve_strategy | |
134 | ||
135 | ||
136 | namespace resolve_variant { | |
137 | ||
138 | template <typename Geometry> | |
139 | struct perimeter | |
140 | { | |
141 | template <typename Strategy> | |
142 | static inline typename default_length_result<Geometry>::type | |
143 | apply(Geometry const& geometry, Strategy const& strategy) | |
144 | { | |
145 | concepts::check<Geometry const>(); | |
146 | return resolve_strategy::perimeter::apply(geometry, strategy); | |
147 | } | |
148 | }; | |
149 | ||
150 | template <BOOST_VARIANT_ENUM_PARAMS(typename T)> | |
151 | struct perimeter<boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> > | |
152 | { | |
153 | typedef typename default_length_result | |
154 | < | |
155 | boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> | |
156 | >::type result_type; | |
157 | ||
158 | template <typename Strategy> | |
159 | struct visitor: boost::static_visitor<result_type> | |
160 | { | |
161 | Strategy const& m_strategy; | |
162 | ||
163 | visitor(Strategy const& strategy): m_strategy(strategy) {} | |
164 | ||
165 | template <typename Geometry> | |
166 | typename default_length_result<Geometry>::type | |
167 | operator()(Geometry const& geometry) const | |
168 | { | |
169 | return perimeter<Geometry>::apply(geometry, m_strategy); | |
170 | } | |
171 | }; | |
172 | ||
173 | template <typename Strategy> | |
174 | static inline result_type | |
175 | apply(boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> const& geometry, | |
176 | Strategy const& strategy) | |
177 | { | |
178 | return boost::apply_visitor(visitor<Strategy>(strategy), geometry); | |
179 | } | |
180 | }; | |
181 | ||
182 | } // namespace resolve_variant | |
183 | ||
184 | ||
185 | /*! | |
186 | \brief \brief_calc{perimeter} | |
187 | \ingroup perimeter | |
188 | \details The function perimeter returns the perimeter of a geometry, | |
189 | using the default distance-calculation-strategy | |
190 | \tparam Geometry \tparam_geometry | |
191 | \param geometry \param_geometry | |
192 | \return \return_calc{perimeter} | |
193 | ||
194 | \qbk{[include reference/algorithms/perimeter.qbk]} | |
195 | */ | |
196 | template<typename Geometry> | |
197 | inline typename default_length_result<Geometry>::type perimeter( | |
198 | Geometry const& geometry) | |
199 | { | |
200 | // detail::throw_on_empty_input(geometry); | |
201 | return resolve_variant::perimeter<Geometry>::apply(geometry, default_strategy()); | |
202 | } | |
203 | ||
204 | /*! | |
205 | \brief \brief_calc{perimeter} \brief_strategy | |
206 | \ingroup perimeter | |
207 | \details The function perimeter returns the perimeter of a geometry, | |
208 | using specified strategy | |
209 | \tparam Geometry \tparam_geometry | |
210 | \tparam Strategy \tparam_strategy{distance} | |
211 | \param geometry \param_geometry | |
212 | \param strategy strategy to be used for distance calculations. | |
213 | \return \return_calc{perimeter} | |
214 | ||
215 | \qbk{distinguish,with strategy} | |
216 | \qbk{[include reference/algorithms/perimeter.qbk]} | |
217 | */ | |
218 | template<typename Geometry, typename Strategy> | |
219 | inline typename default_length_result<Geometry>::type perimeter( | |
220 | Geometry const& geometry, Strategy const& strategy) | |
221 | { | |
222 | // detail::throw_on_empty_input(geometry); | |
223 | return resolve_variant::perimeter<Geometry>::apply(geometry, strategy); | |
224 | } | |
225 | ||
226 | }} // namespace boost::geometry | |
227 | ||
228 | #endif // BOOST_GEOMETRY_ALGORITHMS_PERIMETER_HPP | |
229 |