1use std::fmt::Debug;
2
3use crate::geometry::*;
4use crate::{coord, CoordNum};
5
6use std::{fmt, iter, marker, slice};
7
8type CoordinateChainOnce<T> = iter::Chain<iter::Once<Coord<T>>, iter::Once<Coord<T>>>;
9
10pub trait CoordsIter<'a> {
12 type Iter: Iterator<Item = Coord<Self::Scalar>>;
13 type ExteriorIter: Iterator<Item = Coord<Self::Scalar>>;
14 type Scalar: CoordNum;
15
16 fn coords_iter(&'a self) -> Self::Iter;
36
37 fn coords_count(&'a self) -> usize;
54
55 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter;
92}
93
94impl<'a, T: CoordNum> CoordsIter<'a> for Point<T> {
99 type Iter = iter::Once<Coord<T>>;
100 type ExteriorIter = Self::Iter;
101 type Scalar = T;
102
103 fn coords_iter(&'a self) -> Self::Iter {
104 iter::once(self.0)
105 }
106
107 fn coords_count(&'a self) -> usize {
109 1
110 }
111
112 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
113 self.coords_iter()
114 }
115}
116
117impl<'a, T: CoordNum> CoordsIter<'a> for Line<T> {
122 type Iter = iter::Chain<iter::Once<Coord<T>>, iter::Once<Coord<T>>>;
123 type ExteriorIter = Self::Iter;
124 type Scalar = T;
125
126 fn coords_iter(&'a self) -> Self::Iter {
127 iter::once(self.start).chain(iter::once(self.end))
128 }
129
130 fn coords_count(&'a self) -> usize {
132 2
133 }
134
135 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
136 self.coords_iter()
137 }
138}
139
140type LineStringIter<'a, T> = iter::Copied<slice::Iter<'a, Coord<T>>>;
145
146impl<'a, T: CoordNum + 'a> CoordsIter<'a> for LineString<T> {
147 type Iter = LineStringIter<'a, T>;
148 type ExteriorIter = Self::Iter;
149 type Scalar = T;
150
151 fn coords_iter(&'a self) -> Self::Iter {
152 self.0.iter().copied()
153 }
154
155 fn coords_count(&'a self) -> usize {
157 self.0.len()
158 }
159
160 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
161 self.coords_iter()
162 }
163}
164
165type PolygonIter<'a, T> = iter::Chain<
170 LineStringIter<'a, T>,
171 iter::Flatten<MapCoordsIter<'a, T, slice::Iter<'a, LineString<T>>, LineString<T>>>,
172>;
173
174impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Polygon<T> {
175 type Iter = PolygonIter<'a, T>;
176 type ExteriorIter = LineStringIter<'a, T>;
177 type Scalar = T;
178
179 fn coords_iter(&'a self) -> Self::Iter {
180 self.exterior()
181 .coords_iter()
182 .chain(MapCoordsIter(self.interiors().iter(), marker::PhantomData).flatten())
183 }
184
185 fn coords_count(&'a self) -> usize {
187 self.exterior().coords_count()
188 + self
189 .interiors()
190 .iter()
191 .map(|i| i.coords_count())
192 .sum::<usize>()
193 }
194
195 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
196 self.exterior().coords_iter()
197 }
198}
199
200impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiPoint<T> {
205 type Iter = iter::Flatten<MapCoordsIter<'a, T, slice::Iter<'a, Point<T>>, Point<T>>>;
206 type ExteriorIter = Self::Iter;
207 type Scalar = T;
208
209 fn coords_iter(&'a self) -> Self::Iter {
210 MapCoordsIter(self.0.iter(), marker::PhantomData).flatten()
211 }
212
213 fn coords_count(&'a self) -> usize {
215 self.0.len()
216 }
217
218 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
219 self.coords_iter()
220 }
221}
222
223impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiLineString<T> {
228 type Iter = iter::Flatten<MapCoordsIter<'a, T, slice::Iter<'a, LineString<T>>, LineString<T>>>;
229 type ExteriorIter = Self::Iter;
230 type Scalar = T;
231
232 fn coords_iter(&'a self) -> Self::Iter {
233 MapCoordsIter(self.0.iter(), marker::PhantomData).flatten()
234 }
235
236 fn coords_count(&'a self) -> usize {
238 self.0
239 .iter()
240 .map(|line_string| line_string.coords_count())
241 .sum()
242 }
243
244 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
245 self.coords_iter()
246 }
247}
248
249impl<'a, T: CoordNum + 'a> CoordsIter<'a> for MultiPolygon<T> {
254 type Iter = iter::Flatten<MapCoordsIter<'a, T, slice::Iter<'a, Polygon<T>>, Polygon<T>>>;
255 type ExteriorIter =
256 iter::Flatten<MapExteriorCoordsIter<'a, T, slice::Iter<'a, Polygon<T>>, Polygon<T>>>;
257 type Scalar = T;
258
259 fn coords_iter(&'a self) -> Self::Iter {
260 MapCoordsIter(self.0.iter(), marker::PhantomData).flatten()
261 }
262
263 fn coords_count(&'a self) -> usize {
265 self.0.iter().map(|polygon| polygon.coords_count()).sum()
266 }
267
268 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
269 MapExteriorCoordsIter(self.0.iter(), marker::PhantomData).flatten()
270 }
271}
272
273impl<'a, T: CoordNum + 'a> CoordsIter<'a> for GeometryCollection<T> {
278 type Iter = Box<dyn Iterator<Item = Coord<T>> + 'a>;
279 type ExteriorIter = Box<dyn Iterator<Item = Coord<T>> + 'a>;
280 type Scalar = T;
281
282 fn coords_iter(&'a self) -> Self::Iter {
283 Box::new(self.0.iter().flat_map(|geometry| geometry.coords_iter()))
284 }
285
286 fn coords_count(&'a self) -> usize {
288 self.0.iter().map(|geometry| geometry.coords_count()).sum()
289 }
290
291 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
292 Box::new(
293 self.0
294 .iter()
295 .flat_map(|geometry| geometry.exterior_coords_iter()),
296 )
297 }
298}
299
300type RectIter<T> =
305 iter::Chain<iter::Chain<CoordinateChainOnce<T>, iter::Once<Coord<T>>>, iter::Once<Coord<T>>>;
306
307impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Rect<T> {
308 type Iter = RectIter<T>;
309 type ExteriorIter = Self::Iter;
310 type Scalar = T;
311
312 fn coords_iter(&'a self) -> Self::Iter {
313 iter::once(coord! {
314 x: self.min().x,
315 y: self.min().y,
316 })
317 .chain(iter::once(coord! {
318 x: self.min().x,
319 y: self.max().y,
320 }))
321 .chain(iter::once(coord! {
322 x: self.max().x,
323 y: self.max().y,
324 }))
325 .chain(iter::once(coord! {
326 x: self.max().x,
327 y: self.min().y,
328 }))
329 }
330
331 fn coords_count(&'a self) -> usize {
336 4
337 }
338
339 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
340 self.coords_iter()
341 }
342}
343
344impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Triangle<T> {
349 type Iter = iter::Chain<CoordinateChainOnce<T>, iter::Once<Coord<T>>>;
350 type ExteriorIter = Self::Iter;
351 type Scalar = T;
352
353 fn coords_iter(&'a self) -> Self::Iter {
354 iter::once(self.0)
355 .chain(iter::once(self.1))
356 .chain(iter::once(self.2))
357 }
358
359 fn coords_count(&'a self) -> usize {
361 3
362 }
363
364 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
365 self.coords_iter()
366 }
367}
368
369impl<'a, T: CoordNum + 'a> CoordsIter<'a> for Geometry<T> {
374 type Iter = GeometryCoordsIter<'a, T>;
375 type ExteriorIter = GeometryExteriorCoordsIter<'a, T>;
376 type Scalar = T;
377
378 fn coords_iter(&'a self) -> Self::Iter {
379 match self {
380 Geometry::Point(g) => GeometryCoordsIter::Point(g.coords_iter()),
381 Geometry::Line(g) => GeometryCoordsIter::Line(g.coords_iter()),
382 Geometry::LineString(g) => GeometryCoordsIter::LineString(g.coords_iter()),
383 Geometry::Polygon(g) => GeometryCoordsIter::Polygon(g.coords_iter()),
384 Geometry::MultiPoint(g) => GeometryCoordsIter::MultiPoint(g.coords_iter()),
385 Geometry::MultiLineString(g) => GeometryCoordsIter::MultiLineString(g.coords_iter()),
386 Geometry::MultiPolygon(g) => GeometryCoordsIter::MultiPolygon(g.coords_iter()),
387 Geometry::GeometryCollection(g) => {
388 GeometryCoordsIter::GeometryCollection(g.coords_iter())
389 }
390 Geometry::Rect(g) => GeometryCoordsIter::Rect(g.coords_iter()),
391 Geometry::Triangle(g) => GeometryCoordsIter::Triangle(g.coords_iter()),
392 }
393 }
394 crate::geometry_delegate_impl! {
395 fn coords_count(&'a self) -> usize;
397 }
398
399 fn exterior_coords_iter(&'a self) -> Self::ExteriorIter {
400 match self {
401 Geometry::Point(g) => GeometryExteriorCoordsIter::Point(g.exterior_coords_iter()),
402 Geometry::Line(g) => GeometryExteriorCoordsIter::Line(g.exterior_coords_iter()),
403 Geometry::LineString(g) => {
404 GeometryExteriorCoordsIter::LineString(g.exterior_coords_iter())
405 }
406 Geometry::Polygon(g) => GeometryExteriorCoordsIter::Polygon(g.exterior_coords_iter()),
407 Geometry::MultiPoint(g) => {
408 GeometryExteriorCoordsIter::MultiPoint(g.exterior_coords_iter())
409 }
410 Geometry::MultiLineString(g) => {
411 GeometryExteriorCoordsIter::MultiLineString(g.exterior_coords_iter())
412 }
413 Geometry::MultiPolygon(g) => {
414 GeometryExteriorCoordsIter::MultiPolygon(g.exterior_coords_iter())
415 }
416 Geometry::GeometryCollection(g) => {
417 GeometryExteriorCoordsIter::GeometryCollection(g.exterior_coords_iter())
418 }
419 Geometry::Rect(g) => GeometryExteriorCoordsIter::Rect(g.exterior_coords_iter()),
420 Geometry::Triangle(g) => GeometryExteriorCoordsIter::Triangle(g.exterior_coords_iter()),
421 }
422 }
423}
424
425#[doc(hidden)]
431#[derive(Debug)]
432pub struct MapCoordsIter<
433 'a,
434 T: 'a + CoordNum,
435 Iter1: Iterator<Item = &'a Iter2>,
436 Iter2: 'a + CoordsIter<'a>,
437>(Iter1, marker::PhantomData<T>);
438
439impl<'a, T: 'a + CoordNum, Iter1: Iterator<Item = &'a Iter2>, Iter2: CoordsIter<'a>> Iterator
440 for MapCoordsIter<'a, T, Iter1, Iter2>
441{
442 type Item = Iter2::Iter;
443
444 fn next(&mut self) -> Option<Self::Item> {
445 self.0.next().map(|g| g.coords_iter())
446 }
447
448 fn size_hint(&self) -> (usize, Option<usize>) {
449 self.0.size_hint()
450 }
451}
452
453#[doc(hidden)]
455#[derive(Debug)]
456pub struct MapExteriorCoordsIter<
457 'a,
458 T: 'a + CoordNum,
459 Iter1: Iterator<Item = &'a Iter2>,
460 Iter2: 'a + CoordsIter<'a>,
461>(Iter1, marker::PhantomData<T>);
462
463impl<'a, T: 'a + CoordNum, Iter1: Iterator<Item = &'a Iter2>, Iter2: CoordsIter<'a>> Iterator
464 for MapExteriorCoordsIter<'a, T, Iter1, Iter2>
465{
466 type Item = Iter2::ExteriorIter;
467
468 fn next(&mut self) -> Option<Self::Item> {
469 self.0.next().map(|g| g.exterior_coords_iter())
470 }
471
472 fn size_hint(&self) -> (usize, Option<usize>) {
473 self.0.size_hint()
474 }
475}
476
477#[doc(hidden)]
479pub enum GeometryCoordsIter<'a, T: CoordNum + 'a> {
480 Point(<Point<T> as CoordsIter<'a>>::Iter),
481 Line(<Line<T> as CoordsIter<'a>>::Iter),
482 LineString(<LineString<T> as CoordsIter<'a>>::Iter),
483 Polygon(<Polygon<T> as CoordsIter<'a>>::Iter),
484 MultiPoint(<MultiPoint<T> as CoordsIter<'a>>::Iter),
485 MultiLineString(<MultiLineString<T> as CoordsIter<'a>>::Iter),
486 MultiPolygon(<MultiPolygon<T> as CoordsIter<'a>>::Iter),
487 GeometryCollection(<GeometryCollection<T> as CoordsIter<'a>>::Iter),
488 Rect(<Rect<T> as CoordsIter<'a>>::Iter),
489 Triangle(<Triangle<T> as CoordsIter<'a>>::Iter),
490}
491
492impl<'a, T: CoordNum> Iterator for GeometryCoordsIter<'a, T> {
493 type Item = Coord<T>;
494
495 fn next(&mut self) -> Option<Self::Item> {
496 match self {
497 GeometryCoordsIter::Point(g) => g.next(),
498 GeometryCoordsIter::Line(g) => g.next(),
499 GeometryCoordsIter::LineString(g) => g.next(),
500 GeometryCoordsIter::Polygon(g) => g.next(),
501 GeometryCoordsIter::MultiPoint(g) => g.next(),
502 GeometryCoordsIter::MultiLineString(g) => g.next(),
503 GeometryCoordsIter::MultiPolygon(g) => g.next(),
504 GeometryCoordsIter::GeometryCollection(g) => g.next(),
505 GeometryCoordsIter::Rect(g) => g.next(),
506 GeometryCoordsIter::Triangle(g) => g.next(),
507 }
508 }
509
510 fn size_hint(&self) -> (usize, Option<usize>) {
511 match self {
512 GeometryCoordsIter::Point(g) => g.size_hint(),
513 GeometryCoordsIter::Line(g) => g.size_hint(),
514 GeometryCoordsIter::LineString(g) => g.size_hint(),
515 GeometryCoordsIter::Polygon(g) => g.size_hint(),
516 GeometryCoordsIter::MultiPoint(g) => g.size_hint(),
517 GeometryCoordsIter::MultiLineString(g) => g.size_hint(),
518 GeometryCoordsIter::MultiPolygon(g) => g.size_hint(),
519 GeometryCoordsIter::GeometryCollection(g) => g.size_hint(),
520 GeometryCoordsIter::Rect(g) => g.size_hint(),
521 GeometryCoordsIter::Triangle(g) => g.size_hint(),
522 }
523 }
524}
525
526impl<'a, T: CoordNum + Debug> fmt::Debug for GeometryCoordsIter<'a, T> {
527 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
528 match self {
529 GeometryCoordsIter::Point(i) => fmt.debug_tuple("Point").field(i).finish(),
530 GeometryCoordsIter::Line(i) => fmt.debug_tuple("Line").field(i).finish(),
531 GeometryCoordsIter::LineString(i) => fmt.debug_tuple("LineString").field(i).finish(),
532 GeometryCoordsIter::Polygon(i) => fmt.debug_tuple("Polygon").field(i).finish(),
533 GeometryCoordsIter::MultiPoint(i) => fmt.debug_tuple("MultiPoint").field(i).finish(),
534 GeometryCoordsIter::MultiLineString(i) => {
535 fmt.debug_tuple("MultiLineString").field(i).finish()
536 }
537 GeometryCoordsIter::MultiPolygon(i) => {
538 fmt.debug_tuple("MultiPolygon").field(i).finish()
539 }
540 GeometryCoordsIter::GeometryCollection(_) => fmt
541 .debug_tuple("GeometryCollection")
542 .field(&String::from("..."))
543 .finish(),
544 GeometryCoordsIter::Rect(i) => fmt.debug_tuple("Rect").field(i).finish(),
545 GeometryCoordsIter::Triangle(i) => fmt.debug_tuple("Triangle").field(i).finish(),
546 }
547 }
548}
549
550#[doc(hidden)]
552pub enum GeometryExteriorCoordsIter<'a, T: CoordNum + 'a> {
553 Point(<Point<T> as CoordsIter<'a>>::ExteriorIter),
554 Line(<Line<T> as CoordsIter<'a>>::ExteriorIter),
555 LineString(<LineString<T> as CoordsIter<'a>>::ExteriorIter),
556 Polygon(<Polygon<T> as CoordsIter<'a>>::ExteriorIter),
557 MultiPoint(<MultiPoint<T> as CoordsIter<'a>>::ExteriorIter),
558 MultiLineString(<MultiLineString<T> as CoordsIter<'a>>::ExteriorIter),
559 MultiPolygon(<MultiPolygon<T> as CoordsIter<'a>>::ExteriorIter),
560 GeometryCollection(<GeometryCollection<T> as CoordsIter<'a>>::ExteriorIter),
561 Rect(<Rect<T> as CoordsIter<'a>>::ExteriorIter),
562 Triangle(<Triangle<T> as CoordsIter<'a>>::ExteriorIter),
563}
564
565impl<'a, T: CoordNum> Iterator for GeometryExteriorCoordsIter<'a, T> {
566 type Item = Coord<T>;
567
568 fn next(&mut self) -> Option<Self::Item> {
569 match self {
570 GeometryExteriorCoordsIter::Point(g) => g.next(),
571 GeometryExteriorCoordsIter::Line(g) => g.next(),
572 GeometryExteriorCoordsIter::LineString(g) => g.next(),
573 GeometryExteriorCoordsIter::Polygon(g) => g.next(),
574 GeometryExteriorCoordsIter::MultiPoint(g) => g.next(),
575 GeometryExteriorCoordsIter::MultiLineString(g) => g.next(),
576 GeometryExteriorCoordsIter::MultiPolygon(g) => g.next(),
577 GeometryExteriorCoordsIter::GeometryCollection(g) => g.next(),
578 GeometryExteriorCoordsIter::Rect(g) => g.next(),
579 GeometryExteriorCoordsIter::Triangle(g) => g.next(),
580 }
581 }
582
583 fn size_hint(&self) -> (usize, Option<usize>) {
584 match self {
585 GeometryExteriorCoordsIter::Point(g) => g.size_hint(),
586 GeometryExteriorCoordsIter::Line(g) => g.size_hint(),
587 GeometryExteriorCoordsIter::LineString(g) => g.size_hint(),
588 GeometryExteriorCoordsIter::Polygon(g) => g.size_hint(),
589 GeometryExteriorCoordsIter::MultiPoint(g) => g.size_hint(),
590 GeometryExteriorCoordsIter::MultiLineString(g) => g.size_hint(),
591 GeometryExteriorCoordsIter::MultiPolygon(g) => g.size_hint(),
592 GeometryExteriorCoordsIter::GeometryCollection(g) => g.size_hint(),
593 GeometryExteriorCoordsIter::Rect(g) => g.size_hint(),
594 GeometryExteriorCoordsIter::Triangle(g) => g.size_hint(),
595 }
596 }
597}
598
599impl<'a, T: CoordNum + Debug> fmt::Debug for GeometryExteriorCoordsIter<'a, T> {
600 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
601 match self {
602 GeometryExteriorCoordsIter::Point(i) => fmt.debug_tuple("Point").field(i).finish(),
603 GeometryExteriorCoordsIter::Line(i) => fmt.debug_tuple("Line").field(i).finish(),
604 GeometryExteriorCoordsIter::LineString(i) => {
605 fmt.debug_tuple("LineString").field(i).finish()
606 }
607 GeometryExteriorCoordsIter::Polygon(i) => fmt.debug_tuple("Polygon").field(i).finish(),
608 GeometryExteriorCoordsIter::MultiPoint(i) => {
609 fmt.debug_tuple("MultiPoint").field(i).finish()
610 }
611 GeometryExteriorCoordsIter::MultiLineString(i) => {
612 fmt.debug_tuple("MultiLineString").field(i).finish()
613 }
614 GeometryExteriorCoordsIter::MultiPolygon(i) => {
615 fmt.debug_tuple("MultiPolygon").field(i).finish()
616 }
617 GeometryExteriorCoordsIter::GeometryCollection(_) => fmt
618 .debug_tuple("GeometryCollection")
619 .field(&String::from("..."))
620 .finish(),
621 GeometryExteriorCoordsIter::Rect(i) => fmt.debug_tuple("Rect").field(i).finish(),
622 GeometryExteriorCoordsIter::Triangle(i) => {
623 fmt.debug_tuple("Triangle").field(i).finish()
624 }
625 }
626 }
627}
628
629#[cfg(test)]
630mod test {
631 use super::CoordsIter;
632 use crate::{
633 coord, line_string, point, polygon, Coord, Geometry, GeometryCollection, Line, LineString,
634 MultiLineString, MultiPoint, MultiPolygon, Point, Polygon, Rect, Triangle,
635 };
636
637 #[test]
638 fn test_point() {
639 let (point, expected_coords) = create_point();
640
641 let actual_coords = point.coords_iter().collect::<Vec<_>>();
642
643 assert_eq!(expected_coords, actual_coords);
644 }
645
646 #[test]
647 fn test_line() {
648 let line = Line::new(coord! { x: 1., y: 2. }, coord! { x: 2., y: 3. });
649
650 let coords = line.coords_iter().collect::<Vec<_>>();
651
652 assert_eq!(
653 vec![coord! { x: 1., y: 2. }, coord! { x: 2., y: 3. },],
654 coords
655 );
656 }
657
658 #[test]
659 fn test_line_string() {
660 let (line_string, expected_coords) = create_line_string();
661
662 let actual_coords = line_string.coords_iter().collect::<Vec<_>>();
663
664 assert_eq!(expected_coords, actual_coords);
665 }
666
667 #[test]
668 fn test_polygon() {
669 let (polygon, expected_coords) = create_polygon();
670
671 let actual_coords = polygon.coords_iter().collect::<Vec<_>>();
672
673 assert_eq!(expected_coords, actual_coords);
674 }
675
676 #[test]
677 fn test_multi_point() {
678 let mut expected_coords = vec![];
679 let (point, mut coords) = create_point();
680 expected_coords.append(&mut coords.clone());
681 expected_coords.append(&mut coords);
682
683 let actual_coords = MultiPoint::new(vec![point, point])
684 .coords_iter()
685 .collect::<Vec<_>>();
686
687 assert_eq!(expected_coords, actual_coords);
688 }
689
690 #[test]
691 fn test_multi_line_string() {
692 let mut expected_coords = vec![];
693 let (line_string, mut coords) = create_line_string();
694 expected_coords.append(&mut coords.clone());
695 expected_coords.append(&mut coords);
696
697 let actual_coords = MultiLineString::new(vec![line_string.clone(), line_string])
698 .coords_iter()
699 .collect::<Vec<_>>();
700
701 assert_eq!(expected_coords, actual_coords);
702 }
703
704 #[test]
705 fn test_multi_polygon() {
706 let mut expected_coords = vec![];
707 let (polygon, mut coords) = create_polygon();
708 expected_coords.append(&mut coords.clone());
709 expected_coords.append(&mut coords);
710
711 let actual_coords = MultiPolygon::new(vec![polygon.clone(), polygon])
712 .coords_iter()
713 .collect::<Vec<_>>();
714
715 assert_eq!(expected_coords, actual_coords);
716 }
717
718 #[test]
719 fn test_geometry() {
720 let (line_string, expected_coords) = create_line_string();
721
722 let actual_coords = Geometry::LineString(line_string)
723 .coords_iter()
724 .collect::<Vec<_>>();
725
726 assert_eq!(expected_coords, actual_coords);
727 }
728
729 #[test]
730 fn test_rect() {
731 let (rect, expected_coords) = create_rect();
732
733 let actual_coords = rect.coords_iter().collect::<Vec<_>>();
734
735 assert_eq!(expected_coords, actual_coords);
736 }
737
738 #[test]
739 fn test_triangle() {
740 let (triangle, expected_coords) = create_triangle();
741
742 let actual_coords = triangle.coords_iter().collect::<Vec<_>>();
743
744 assert_eq!(expected_coords, actual_coords);
745 }
746
747 #[test]
748 fn test_geometry_collection() {
749 let mut expected_coords = vec![];
750 let (line_string, mut coords) = create_line_string();
751 expected_coords.append(&mut coords);
752 let (polygon, mut coords) = create_polygon();
753 expected_coords.append(&mut coords);
754
755 let actual_coords = GeometryCollection::new_from(vec![
756 Geometry::LineString(line_string),
757 Geometry::Polygon(polygon),
758 ])
759 .coords_iter()
760 .collect::<Vec<_>>();
761
762 assert_eq!(expected_coords, actual_coords);
763 }
764
765 fn create_point() -> (Point, Vec<Coord>) {
766 (point!(x: 1., y: 2.), vec![coord! { x: 1., y: 2. }])
767 }
768
769 fn create_triangle() -> (Triangle, Vec<Coord>) {
770 (
771 Triangle::new(
772 coord! { x: 1., y: 2. },
773 coord! { x: 3., y: 4. },
774 coord! { x: 5., y: 6. },
775 ),
776 vec![
777 coord! { x: 1., y: 2. },
778 coord! { x: 3., y: 4. },
779 coord! { x: 5., y: 6. },
780 ],
781 )
782 }
783
784 fn create_rect() -> (Rect, Vec<Coord>) {
785 (
786 Rect::new(coord! { x: 1., y: 2. }, coord! { x: 3., y: 4. }),
787 vec![
788 coord! { x: 1., y: 2. },
789 coord! { x: 1., y: 4. },
790 coord! { x: 3., y: 4. },
791 coord! { x: 3., y: 2. },
792 ],
793 )
794 }
795
796 fn create_line_string() -> (LineString, Vec<Coord>) {
797 (
798 line_string![
799 (x: 1., y: 2.),
800 (x: 2., y: 3.),
801 ],
802 vec![coord! { x: 1., y: 2. }, coord! { x: 2., y: 3. }],
803 )
804 }
805
806 fn create_polygon() -> (Polygon<f64>, Vec<Coord>) {
807 (
808 polygon!(
809 exterior: [(x: 0., y: 0.), (x: 5., y: 10.), (x: 10., y: 0.), (x: 0., y: 0.)],
810 interiors: [[(x: 1., y: 1.), (x: 9., y: 1.), (x: 5., y: 9.), (x: 1., y: 1.)]],
811 ),
812 vec![
813 coord! { x: 0.0, y: 0.0 },
814 coord! { x: 5.0, y: 10.0 },
815 coord! { x: 10.0, y: 0.0 },
816 coord! { x: 0.0, y: 0.0 },
817 coord! { x: 1.0, y: 1.0 },
818 coord! { x: 9.0, y: 1.0 },
819 coord! { x: 5.0, y: 9.0 },
820 coord! { x: 1.0, y: 1.0 },
821 ],
822 )
823 }
824}