gistools/geometry/tools/points/
average.rs1use s2json::{
2 Feature, Features, Geometry, GetXY, GetZ, MultiLineString, MultiLineString3D,
3 MultiLineString3DGeometry, MultiLineStringGeometry, MultiPoint, MultiPoint3D,
4 MultiPoint3DGeometry, MultiPointGeometry, MultiPolygon, MultiPolygon3D, MultiPolygon3DGeometry,
5 MultiPolygonGeometry, NewXY, NewXYZ, Point, Point3D, Point3DGeometry, PointGeometry,
6 VectorFeature, VectorGeometry, VectorMultiLineString, VectorMultiLineStringGeometry,
7 VectorMultiPoint, VectorMultiPointGeometry, VectorMultiPolygon, VectorMultiPolygonGeometry,
8 VectorPoint, VectorPointGeometry,
9};
10
11pub trait AverageOfPoints<Q: NewXY> {
41 fn average_of_points(&self) -> Q;
43}
44
45impl<Q: NewXY + NewXYZ, P: GetXY + GetZ> AverageOfPoints<Q> for &[P] {
46 fn average_of_points(&self) -> Q {
47 let mut x = 0.;
48 let mut y = 0.;
49 let mut z = 0.;
50 for p in self.iter() {
51 x += p.x();
52 y += p.y();
53 z += p.z().unwrap_or(0.);
54 }
55 let len = self.len() as f64;
56 x /= len;
57 y /= len;
58 z /= len;
59 Q::new_xyz(x, y, z)
60 }
61}
62
63impl<M, P: Clone + Default, D: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q>
66 for Feature<M, P, D>
67{
68 fn average_of_points(&self) -> Q {
69 self.geometry.average_of_points()
70 }
71}
72impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for Geometry<M> {
73 fn average_of_points(&self) -> Q {
74 match self {
75 Geometry::Point(g) => g.average_of_points(),
76 Geometry::MultiPoint(g) => g.average_of_points(),
77 Geometry::LineString(g) => g.average_of_points(),
78 Geometry::MultiLineString(g) => g.average_of_points(),
79 Geometry::Polygon(g) => g.average_of_points(),
80 Geometry::MultiPolygon(g) => g.average_of_points(),
81 Geometry::Point3D(g) => g.average_of_points(),
82 Geometry::MultiPoint3D(g) => g.average_of_points(),
83 Geometry::LineString3D(g) => g.average_of_points(),
84 Geometry::MultiLineString3D(g) => g.average_of_points(),
85 Geometry::Polygon3D(g) => g.average_of_points(),
86 Geometry::MultiPolygon3D(g) => g.average_of_points(),
87 }
88 }
89}
90impl<M: Clone + Default, Q: NewXY> AverageOfPoints<Q> for PointGeometry<M> {
91 fn average_of_points(&self) -> Q {
92 self.coordinates.average_of_points()
93 }
94}
95impl<M: Clone + Default, Q: NewXY> AverageOfPoints<Q> for MultiPointGeometry<M> {
96 fn average_of_points(&self) -> Q {
97 self.coordinates.average_of_points()
98 }
99}
100impl<M: Clone + Default, Q: NewXY> AverageOfPoints<Q> for MultiLineStringGeometry<M> {
101 fn average_of_points(&self) -> Q {
102 self.coordinates.average_of_points()
103 }
104}
105impl<M: Clone + Default, Q: NewXY> AverageOfPoints<Q> for MultiPolygonGeometry<M> {
106 fn average_of_points(&self) -> Q {
107 self.coordinates.average_of_points()
108 }
109}
110impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for Point3DGeometry<M> {
111 fn average_of_points(&self) -> Q {
112 self.coordinates.average_of_points()
113 }
114}
115impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiPoint3DGeometry<M> {
116 fn average_of_points(&self) -> Q {
117 self.coordinates.average_of_points()
118 }
119}
120impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiLineString3DGeometry<M> {
121 fn average_of_points(&self) -> Q {
122 self.coordinates.average_of_points()
123 }
124}
125impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiPolygon3DGeometry<M> {
126 fn average_of_points(&self) -> Q {
127 self.coordinates.average_of_points()
128 }
129}
130
131impl<Q: NewXY> AverageOfPoints<Q> for Point {
134 fn average_of_points(&self) -> Q {
135 Q::new_xy(self.0, self.1)
136 }
137}
138impl<Q: NewXY> AverageOfPoints<Q> for MultiPoint {
139 fn average_of_points(&self) -> Q {
140 let mut x = 0.;
141 let mut y = 0.;
142 for p in self {
143 x += p.0;
144 y += p.1;
145 }
146 let len = self.len() as f64;
147 x /= len;
148 y /= len;
149 Q::new_xy(x, y)
150 }
151}
152impl<Q: NewXY> AverageOfPoints<Q> for MultiLineString {
153 fn average_of_points(&self) -> Q {
154 let mut x = 0.;
155 let mut y = 0.;
156 let mut total = 0;
157 for line in self {
158 for p in line {
159 x += p.0;
160 y += p.1;
161 }
162 total += line.len();
163 }
164 let len = total as f64;
165 x /= len;
166 y /= len;
167 Q::new_xy(x, y)
168 }
169}
170impl<Q: NewXY> AverageOfPoints<Q> for MultiPolygon {
171 fn average_of_points(&self) -> Q {
172 let mut x = 0.;
173 let mut y = 0.;
174 let mut total = 0;
175 for poly in self {
176 for line in poly {
177 for p in line {
178 x += p.0;
179 y += p.1;
180 }
181 total += line.len();
182 }
183 }
184 let len = total as f64;
185 x /= len;
186 y /= len;
187 Q::new_xy(x, y)
188 }
189}
190impl<Q: NewXY + NewXYZ> AverageOfPoints<Q> for Point3D {
191 fn average_of_points(&self) -> Q {
192 Q::new_xyz(self.0, self.1, self.2)
193 }
194}
195impl<Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiPoint3D {
196 fn average_of_points(&self) -> Q {
197 let mut x = 0.;
198 let mut y = 0.;
199 let mut z = 0.;
200 for p in self {
201 x += p.0;
202 y += p.1;
203 z += p.2;
204 }
205 let len = self.len() as f64;
206 x /= len;
207 y /= len;
208 z /= len;
209 Q::new_xyz(x, y, z)
210 }
211}
212impl<Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiLineString3D {
213 fn average_of_points(&self) -> Q {
214 let mut x = 0.;
215 let mut y = 0.;
216 let mut z = 0.;
217 let mut total = 0;
218 for line in self {
219 for p in line {
220 x += p.0;
221 y += p.1;
222 z += p.2;
223 }
224 total += line.len();
225 }
226 let len = total as f64;
227 x /= len;
228 y /= len;
229 z /= len;
230 Q::new_xyz(x, y, z)
231 }
232}
233impl<Q: NewXY + NewXYZ> AverageOfPoints<Q> for MultiPolygon3D {
234 fn average_of_points(&self) -> Q {
235 let mut x = 0.;
236 let mut y = 0.;
237 let mut z = 0.;
238 let mut total = 0;
239 for poly in self {
240 for line in poly {
241 for p in line {
242 x += p.0;
243 y += p.1;
244 z += p.2;
245 }
246 total += line.len();
247 }
248 }
249 let len = total as f64;
250 x /= len;
251 y /= len;
252 z /= len;
253 Q::new_xyz(x, y, z)
254 }
255}
256
257impl<M, P: Clone + Default, D: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q>
260 for VectorFeature<M, P, D>
261{
262 fn average_of_points(&self) -> Q {
263 self.geometry.average_of_points()
264 }
265}
266impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorGeometry<M> {
267 fn average_of_points(&self) -> Q {
268 match self {
269 VectorGeometry::Point(g) => g.average_of_points(),
270 VectorGeometry::MultiPoint(g) => g.average_of_points(),
271 VectorGeometry::LineString(g) => g.average_of_points(),
272 VectorGeometry::MultiLineString(g) => g.average_of_points(),
273 VectorGeometry::Polygon(g) => g.average_of_points(),
274 VectorGeometry::MultiPolygon(g) => g.average_of_points(),
275 }
276 }
277}
278impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorPointGeometry<M> {
279 fn average_of_points(&self) -> Q {
280 self.coordinates.average_of_points()
281 }
282}
283impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorMultiPointGeometry<M> {
284 fn average_of_points(&self) -> Q {
285 self.coordinates.average_of_points()
286 }
287}
288impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q>
289 for VectorMultiLineStringGeometry<M>
290{
291 fn average_of_points(&self) -> Q {
292 self.coordinates.average_of_points()
293 }
294}
295impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorMultiPolygonGeometry<M> {
296 fn average_of_points(&self) -> Q {
297 self.coordinates.average_of_points()
298 }
299}
300
301impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorPoint<M> {
304 fn average_of_points(&self) -> Q {
305 Q::new_xyz(self.x, self.y, self.z.unwrap_or_default())
306 }
307}
308impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorMultiPoint<M> {
309 fn average_of_points(&self) -> Q {
310 let mut x = 0.;
311 let mut y = 0.;
312 let mut z = 0.;
313 for p in self {
314 x += p.x;
315 y += p.y;
316 z += p.z.unwrap_or_default();
317 }
318 let len = self.len() as f64;
319 x /= len;
320 y /= len;
321 z /= len;
322 Q::new_xyz(x, y, z)
323 }
324}
325impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorMultiLineString<M> {
326 fn average_of_points(&self) -> Q {
327 let mut x = 0.;
328 let mut y = 0.;
329 let mut z = 0.;
330 let mut total = 0;
331
332 for line in self {
333 for point in line {
334 x += point.x;
335 y += point.y;
336 z += point.z.unwrap_or_default();
337 }
338 total += line.len();
339 }
340
341 let len = total as f64;
342 x /= len;
343 y /= len;
344 z /= len;
345 Q::new_xyz(x, y, z)
346 }
347}
348impl<M: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q> for VectorMultiPolygon<M> {
349 fn average_of_points(&self) -> Q {
350 let mut x = 0.;
351 let mut y = 0.;
352 let mut z = 0.;
353 let mut total = 0;
354
355 for poly in self {
356 for line in poly {
357 for point in line {
358 x += point.x;
359 y += point.y;
360 z += point.z.unwrap_or_default();
361 }
362 total += line.len();
363 }
364 }
365
366 let len = total as f64;
367 x /= len;
368 y /= len;
369 z /= len;
370 Q::new_xyz(x, y, z)
371 }
372}
373
374impl<M, P: Clone + Default, D: Clone + Default, Q: NewXY + NewXYZ> AverageOfPoints<Q>
377 for Features<M, P, D>
378{
379 fn average_of_points(&self) -> Q {
380 match self {
381 Features::Feature(f) => f.average_of_points(),
382 Features::VectorFeature(f) => f.average_of_points(),
383 }
384 }
385}