s2json_core/geometry/
mod.rs

1/// BBox and BBox3D shapes and utilities
2pub mod bbox;
3/// Primitive geometry types (used by GeoJSON spec)
4pub mod primitive;
5/// Vector geometry types (used by the s2json spec for both WGS84 and S2Geometry)
6pub mod vector;
7
8use crate::{Face, MValue, MValueCompatible};
9pub use bbox::*;
10pub use primitive::*;
11use serde::{Deserialize, Serialize};
12pub use vector::*;
13
14/// The axis to apply an operation to
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub enum Axis {
17    /// X axis
18    X = 0,
19    /// Y axis
20    Y = 1,
21}
22
23/// A Point in S2 Space with a Face
24#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
25pub struct STPoint<M: MValueCompatible = MValue> {
26    /// The face of the point
27    pub face: Face,
28    /// The s coordinate
29    pub s: f64,
30    /// The t coordinate
31    pub t: f64,
32    /// The z coordinate
33    pub z: Option<f64>,
34    /// The m coordinate
35    pub m: Option<M>,
36}
37
38#[cfg(test)]
39mod tests {
40    use crate::*;
41
42    use super::*;
43    use alloc::{string::ToString, vec};
44    use serde_json::json;
45
46    #[test]
47    fn test_vector_offset() {
48        let offset = VectorOffsets::default();
49        assert_eq!(offset, VectorOffsets::LineOffset(0.0));
50        let offset: VectorOffsets = Default::default();
51        assert_eq!(offset, VectorOffsets::LineOffset(0.0));
52    }
53
54    #[test]
55    fn test_bbox() {
56        let bbox = BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0 };
57        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0 });
58        let bbox_str = serde_json::to_string(&bbox).unwrap();
59        assert_eq!(bbox_str, "[0.0,0.0,1.0,1.0]");
60        let str_bbox: BBox = serde_json::from_str(&bbox_str).unwrap();
61        assert_eq!(str_bbox, bbox);
62
63        let default_bbox = BBox::default();
64        assert_eq!(
65            default_bbox,
66            BBox {
67                left: f64::INFINITY,
68                bottom: f64::INFINITY,
69                right: -f64::INFINITY,
70                top: -f64::INFINITY
71            }
72        );
73
74        let default_bbox_2 = BBOX::default();
75        assert_eq!(
76            default_bbox_2,
77            BBOX::BBox(BBox {
78                left: f64::INFINITY,
79                bottom: f64::INFINITY,
80                right: -f64::INFINITY,
81                top: -f64::INFINITY
82            })
83        );
84    }
85
86    #[test]
87    fn test_bbox_serialize() {
88        let bbox = BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0 };
89        let bbox_str = serde_json::to_string(&bbox).unwrap();
90        assert_eq!(bbox_str, "[0.0,0.0,1.0,1.0]");
91    }
92
93    #[test]
94    fn test_bbox_deserialize() {
95        let bbox_str = "[0.0,0.0,1.0,1.0]";
96        let bbox: BBox = serde_json::from_str(bbox_str).unwrap();
97        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0 });
98    }
99
100    #[test]
101    fn test_bbox_clip() {
102        let bbox = BBox::new(0., 0., 1., 1.);
103        let bbox2 = BBox { left: 0.5, bottom: 0., right: 0.75, top: 1. };
104        assert_eq!(bbox.clip(Axis::X, 0.5, 0.75), bbox2);
105        let bbox2 = BBox { left: 0., bottom: 0.5, right: 1., top: 0.75 };
106        assert_eq!(bbox.clip(Axis::Y, 0.5, 0.75), bbox2);
107    }
108
109    #[test]
110    fn test_bbox_overlap() {
111        let bbox = BBox::new(0., 0., 1., 1.);
112        assert!(bbox.point_overlap(VectorPoint::<MValue>::new(0.5, 0.5, None, None)));
113        assert!(!bbox.point_overlap(VectorPoint::<MValue>::new(2.0, 2.0, None, None)));
114        let bbox2 = BBox { left: 0.5, bottom: 0.5, right: 1.5, top: 1.5 };
115        assert_eq!(
116            bbox.overlap(&bbox2),
117            Some(BBox { left: 0.5, bottom: 0.5, right: 1.0, top: 1.0 })
118        );
119        let bbox3 = BBox { left: 2.0, bottom: 2.0, right: 3.0, top: 3.0 };
120        assert_eq!(bbox3.overlap(&bbox), None);
121    }
122
123    #[test]
124    fn test_bbox_merge() {
125        let bbox = BBox::new(0., 0., 1., 1.);
126        let bbox2 = BBox { left: 0.5, bottom: 0.5, right: 1.5, top: 1.5 };
127        assert_eq!(bbox.merge(&bbox2), BBox { left: 0.0, bottom: 0.0, right: 1.5, top: 1.5 });
128        assert_eq!(bbox2.merge(&bbox), BBox { left: 0.0, bottom: 0.0, right: 1.5, top: 1.5 });
129        let bbox3 = BBox { left: 2.0, bottom: 2.0, right: 3.0, top: 3.0 };
130        assert_eq!(bbox.merge(&bbox3), BBox { left: 0.0, bottom: 0.0, right: 3.0, top: 3.0 });
131    }
132
133    #[test]
134    fn test_bbox_from_st_uv() {
135        let bbox = BBox::from_st_zoom(0., 0., 0);
136        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 1., top: 1. });
137
138        let bbox = BBox::from_st_zoom(1., 0., 1);
139        assert_eq!(bbox, BBox { left: 0.5, bottom: 0.0, right: 1., top: 0.5 });
140
141        let bbox = BBox::from_st_zoom(2., 0., 2);
142        assert_eq!(bbox, BBox { left: 0.5, bottom: 0.0, right: 0.75, top: 0.25 });
143
144        let bbox = BBox::from_uv_zoom(0., 0., 0);
145        assert_eq!(bbox, BBox { left: -1.0, bottom: -1.0, right: 1., top: 1. });
146
147        let bbox = BBox::from_uv_zoom(1., 0., 1);
148        assert_eq!(bbox, BBox { left: 0., bottom: -1.0, right: 1., top: 0. });
149
150        let bbox = BBox::from_uv_zoom(2., 0., 2);
151        assert_eq!(bbox, BBox { left: 0., bottom: -1.0, right: 0.5, top: -0.5 });
152    }
153
154    #[test]
155    fn test_bbox_from_point() {
156        let bbox = BBox::from_point(&VectorPoint::<MValue>::new(0., 0., None, None));
157        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 0.0, top: 0.0 });
158    }
159
160    #[test]
161    fn test_bbox_from_linestring() {
162        let bbox = BBox::from_linestring(&vec![
163            VectorPoint::<MValue>::new(0., 0., None, None),
164            VectorPoint::new(1., 1.5, None, None),
165        ]);
166        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.5 });
167    }
168
169    #[test]
170    fn test_bbox_from_multilinestring() {
171        let bbox = BBox::from_multi_linestring(&vec![vec![
172            VectorPoint::<MValue>::new(0., 0., None, None),
173            VectorPoint::new(1., 1.5, None, None),
174        ]]);
175        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 1.0, top: 1.5 });
176    }
177
178    #[test]
179    fn test_bbox_from_polygon() {
180        let bbox = BBox::from_polygon(&vec![vec![
181            VectorPoint::<MValue>::new(0., 0., None, None),
182            VectorPoint::new(2., 1.5, None, None),
183        ]]);
184        assert_eq!(bbox, BBox { left: 0.0, bottom: 0.0, right: 2.0, top: 1.5 });
185    }
186
187    #[test]
188    fn test_bbox_from_multipolygon() {
189        let bbox = BBox::from_multi_polygon(&vec![
190            vec![vec![
191                VectorPoint::<MValue>::new(0., 0., None, None),
192                VectorPoint::new(2., 1.5, None, None),
193            ]],
194            vec![vec![
195                VectorPoint::new(0., 0., None, None),
196                VectorPoint::new(-1., 3.5, None, None),
197            ]],
198        ]);
199        assert_eq!(bbox, BBox { left: -1.0, bottom: 0.0, right: 2.0, top: 3.5 });
200    }
201
202    #[test]
203    fn test_bbox3d() {
204        let bbox = BBox3D { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0, near: 0.0, far: 1.0 };
205        assert_eq!(
206            bbox,
207            BBox3D { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0, near: 0.0, far: 1.0 }
208        );
209        let bbox_str = serde_json::to_string(&bbox).unwrap();
210        assert_eq!(bbox_str, "[0.0,0.0,1.0,1.0,0.0,1.0]");
211        let str_bbox: BBox3D = serde_json::from_str(&bbox_str).unwrap();
212        assert_eq!(str_bbox, bbox);
213
214        let default_bbox = BBox3D::default();
215        assert_eq!(
216            default_bbox,
217            BBox3D {
218                left: f64::INFINITY,
219                bottom: f64::INFINITY,
220                right: -f64::INFINITY,
221                top: -f64::INFINITY,
222                near: f64::INFINITY,
223                far: -f64::INFINITY
224            }
225        );
226    }
227
228    #[test]
229    fn test_bbox_3d_serialize() {
230        let bbox = BBox3D { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0, near: 0.0, far: 1.0 };
231        let bbox_str = serde_json::to_string(&bbox).unwrap();
232        assert_eq!(bbox_str, "[0.0,0.0,1.0,1.0,0.0,1.0]");
233    }
234
235    #[test]
236    fn test_bbox_3_d_deserialize() {
237        let bbox_str = "[0.0,0.0,1.0,1.0,0.0,1.0]";
238        let bbox: BBox3D = serde_json::from_str(bbox_str).unwrap();
239        assert_eq!(
240            bbox,
241            BBox3D { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0, near: 0.0, far: 1.0 }
242        );
243    }
244
245    #[test]
246    fn test_bbox_3_d_overlap() {
247        let bbox = BBox3D::new(0., 0., 1., 1., 0., 1.);
248        assert!(bbox.point_overlap(VectorPoint::<MValue>::new(0.5, 0.5, None, None)));
249        assert!(!bbox.point_overlap(VectorPoint::<MValue>::new(2.0, 2.0, None, None)));
250        let bbox2 = BBox3D { left: 0.5, bottom: 0.5, right: 1.5, top: 1.5, near: 0.5, far: 1.5 };
251        assert_eq!(
252            bbox.overlap(&bbox2),
253            Some(BBox3D { left: 0.5, bottom: 0.5, right: 1.0, top: 1.0, near: 0.5, far: 1.0 })
254        );
255        let bbox3 = BBox3D { left: 2.0, bottom: 2.0, right: 3.0, top: 3.0, near: 2.0, far: 3.0 };
256        assert_eq!(bbox3.overlap(&bbox), None);
257    }
258
259    #[test]
260    fn test_bbox_3_d_clip() {
261        let bbox = BBox3D::new(0., 0., 1., 1., -1., 5.);
262        let bbox2 = BBox3D { left: 0.5, bottom: 0., right: 0.75, top: 1., near: -1., far: 5. };
263        assert_eq!(bbox.clip(Axis::X, 0.5, 0.75), bbox2);
264        let bbox2 = BBox3D { left: 0., bottom: 0.5, right: 1., top: 0.75, near: -1., far: 5. };
265        assert_eq!(bbox.clip(Axis::Y, 0.5, 0.75), bbox2);
266    }
267
268    #[test]
269    fn test_bbox_3_d_merge() {
270        let bbox = BBox3D::new(0., 0., 1., 1., 0., 1.);
271        let bbox2 = BBox3D { left: 0.5, bottom: 0.5, right: 1.5, top: 1.5, near: 0.5, far: 1.5 };
272        assert_eq!(
273            bbox.merge(&bbox2),
274            BBox3D { left: 0.0, bottom: 0.0, right: 1.5, top: 1.5, near: 0.0, far: 1.5 }
275        );
276        assert_eq!(
277            bbox2.merge(&bbox),
278            BBox3D { left: 0.0, bottom: 0.0, right: 1.5, top: 1.5, near: 0.0, far: 1.5 }
279        );
280        let bbox3 = BBox3D { left: 2.0, bottom: 2.0, right: 3.0, top: 3.0, near: 2.0, far: 3.0 };
281        assert_eq!(
282            bbox.merge(&bbox3),
283            BBox3D { left: 0.0, bottom: 0.0, right: 3.0, top: 3.0, near: 0.0, far: 3.0 }
284        );
285    }
286
287    #[test]
288    fn test_bbox_3_d_from_point() {
289        let bbox = BBox3D::from_point(&VectorPoint::<MValue>::new(0., 0., None, None));
290        assert_eq!(
291            bbox,
292            BBox3D {
293                left: 0.0,
294                bottom: 0.0,
295                right: 0.0,
296                top: 0.0,
297                near: f64::INFINITY,
298                far: -f64::INFINITY
299            }
300        );
301    }
302
303    #[test]
304    fn test_bbox_3_d_from_linestring() {
305        let bbox = BBox3D::from_linestring(&vec![
306            VectorPoint::<MValue>::new(0., 0., None, None),
307            VectorPoint::new(1., 1.5, None, None),
308        ]);
309        assert_eq!(
310            bbox,
311            BBox3D {
312                left: 0.0,
313                bottom: 0.0,
314                right: 1.0,
315                top: 1.5,
316                near: f64::INFINITY,
317                far: -f64::INFINITY
318            }
319        );
320    }
321
322    #[test]
323    fn test_bbox_3_d_from_multilinestring() {
324        let bbox = BBox3D::from_multi_linestring(&vec![vec![
325            VectorPoint::<MValue>::new(0., 0., None, None),
326            VectorPoint::new(1., 1.5, None, None),
327        ]]);
328        assert_eq!(
329            bbox,
330            BBox3D {
331                left: 0.0,
332                bottom: 0.0,
333                right: 1.0,
334                top: 1.5,
335                near: f64::INFINITY,
336                far: -f64::INFINITY
337            }
338        );
339    }
340
341    #[test]
342    fn test_bbox_3_d_from_polygon() {
343        let bbox = BBox3D::from_polygon(&vec![vec![
344            VectorPoint::<MValue>::new(0., 0., None, None),
345            VectorPoint::new(2., 1.5, None, None),
346        ]]);
347        assert_eq!(
348            bbox,
349            BBox3D {
350                left: 0.0,
351                bottom: 0.0,
352                right: 2.0,
353                top: 1.5,
354                near: f64::INFINITY,
355                far: -f64::INFINITY
356            }
357        );
358    }
359
360    #[test]
361    fn test_bbox_3_d_from_multipolygon() {
362        let bbox = BBox3D::from_multi_polygon(&vec![
363            vec![vec![
364                VectorPoint::<MValue>::new(0., 0., None, None),
365                VectorPoint::new(2., 1.5, None, None),
366            ]],
367            vec![vec![
368                VectorPoint::new(0., 0., None, None),
369                VectorPoint::new(-1., 3.5, None, None),
370            ]],
371        ]);
372        assert_eq!(
373            bbox,
374            BBox3D {
375                left: -1.0,
376                bottom: 0.0,
377                right: 2.0,
378                top: 3.5,
379                near: f64::INFINITY,
380                far: -f64::INFINITY
381            }
382        );
383    }
384
385    #[test]
386    fn test_bbox_3_d_extend_from_point() {
387        let mut bbox = BBox3D::default();
388        bbox.extend_from_point(&VectorPoint::<MValue>::new(20., -4., None, None));
389        assert_eq!(
390            bbox,
391            BBox3D {
392                left: 20.0,
393                bottom: -4.0,
394                right: 20.0,
395                top: -4.0,
396                near: f64::INFINITY,
397                far: -f64::INFINITY
398            }
399        );
400    }
401
402    #[test]
403    fn test_bbox_3_d_from_st_uv() {
404        let bbox = BBox3D::from_st_zoom(0., 0., 0);
405        assert_eq!(
406            bbox,
407            BBox3D {
408                left: 0.0,
409                bottom: 0.0,
410                right: 1.,
411                top: 1.,
412                near: f64::INFINITY,
413                far: -f64::INFINITY
414            }
415        );
416
417        let bbox = BBox3D::from_st_zoom(1., 0., 1);
418        assert_eq!(
419            bbox,
420            BBox3D {
421                left: 0.5,
422                bottom: 0.0,
423                right: 1.,
424                top: 0.5,
425                near: f64::INFINITY,
426                far: -f64::INFINITY
427            }
428        );
429
430        let bbox = BBox3D::from_st_zoom(2., 0., 2);
431        assert_eq!(
432            bbox,
433            BBox3D {
434                left: 0.5,
435                bottom: 0.0,
436                right: 0.75,
437                top: 0.25,
438                near: f64::INFINITY,
439                far: -f64::INFINITY
440            }
441        );
442
443        let bbox = BBox3D::from_uv_zoom(0., 0., 0);
444        assert_eq!(
445            bbox,
446            BBox3D {
447                left: -1.0,
448                bottom: -1.0,
449                right: 1.,
450                top: 1.,
451                near: f64::INFINITY,
452                far: -f64::INFINITY
453            }
454        );
455
456        let bbox = BBox3D::from_uv_zoom(1., 0., 1);
457        assert_eq!(
458            bbox,
459            BBox3D {
460                left: 0.,
461                bottom: -1.0,
462                right: 1.,
463                top: 0.,
464                near: f64::INFINITY,
465                far: -f64::INFINITY
466            }
467        );
468
469        let bbox = BBox3D::from_uv_zoom(2., 0., 2);
470        assert_eq!(
471            bbox,
472            BBox3D {
473                left: 0.,
474                bottom: -1.0,
475                right: 0.5,
476                top: -0.5,
477                near: f64::INFINITY,
478                far: -f64::INFINITY
479            }
480        );
481    }
482
483    #[test]
484    fn test_bbox_3_d_from_bbox() {
485        let bbox: BBox3D = BBox::new(0., 0., 1., 1.).into();
486        assert_eq!(
487            bbox,
488            BBox3D { left: 0.0, bottom: 0.0, right: 1.0, top: 1.0, near: 0.0, far: 0.0 }
489        );
490    }
491
492    #[test]
493    fn test_point_geometry() {
494        let point = PointGeometry {
495            _type: "Point".into(),
496            coordinates: Point(0.0, 0.0),
497            m_values: None,
498            bbox: None,
499        };
500        assert_eq!(
501            point,
502            PointGeometry {
503                _type: "Point".into(),
504                coordinates: Point(0.0, 0.0),
505                m_values: None,
506                bbox: None
507            }
508        );
509        let point_str = serde_json::to_string(&point).unwrap();
510        assert_eq!(point_str, "{\"type\":\"Point\",\"coordinates\":[0.0,0.0]}");
511        let str_point: PointGeometry = serde_json::from_str(&point_str).unwrap();
512        assert_eq!(str_point, point);
513    }
514
515    #[test]
516    fn test_geometry_default() {
517        let geo = Geometry::default();
518        assert_eq!(geo, Geometry::Point(PointGeometry::default()));
519
520        let default_instance: Geometry = Default::default();
521        assert_eq!(geo, default_instance);
522    }
523
524    #[test]
525    fn test_point3d_geometry() {
526        let point = Point3DGeometry {
527            _type: "Point3D".into(),
528            coordinates: Point3D(0.0, 0.0, 0.0),
529            m_values: None,
530            bbox: Some(BBox3D {
531                left: 0.0,
532                bottom: 0.0,
533                right: 1.0,
534                top: 1.0,
535                near: 0.0,
536                far: 1.0,
537            }),
538        };
539        assert_eq!(
540            point,
541            Point3DGeometry {
542                _type: "Point3D".into(),
543                coordinates: Point3D(0.0, 0.0, 0.0),
544                m_values: None,
545                bbox: Some(BBox3D {
546                    left: 0.0,
547                    bottom: 0.0,
548                    right: 1.0,
549                    top: 1.0,
550                    near: 0.0,
551                    far: 1.0
552                })
553            }
554        );
555        let point_str = serde_json::to_string(&point).unwrap();
556        assert_eq!(
557            point_str,
558            "{\"type\":\"Point3D\",\"coordinates\":[0.0,0.0,0.0],\"bbox\":[0.0,0.0,1.0,1.0,0.0,1.\
559             0]}"
560        );
561        let str_point: Point3DGeometry = serde_json::from_str(&point_str).unwrap();
562        assert_eq!(str_point, point);
563    }
564
565    #[test]
566    fn test_line_string_geometry() {
567        let line = LineStringGeometry {
568            _type: "LineString".into(),
569            coordinates: vec![Point(0.0, 0.0), Point(1.0, 1.0)],
570            m_values: None,
571            bbox: None,
572        };
573        assert_eq!(
574            line,
575            LineStringGeometry {
576                _type: "LineString".into(),
577                coordinates: vec![Point(0.0, 0.0), Point(1.0, 1.0)],
578                m_values: None,
579                bbox: None
580            }
581        );
582        let line_str = serde_json::to_string(&line).unwrap();
583        assert_eq!(line_str, "{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[1.0,1.0]]}");
584        let str_line: LineStringGeometry = serde_json::from_str(&line_str).unwrap();
585        assert_eq!(str_line, line);
586    }
587
588    #[test]
589    fn test_line_string3d_geometry() {
590        let line = LineString3DGeometry::<MValue> {
591            _type: "LineString3D".into(),
592            coordinates: vec![Point3D(0.0, 0.0, 0.0), Point3D(1.0, 1.0, 1.0)],
593            m_values: None,
594            bbox: None,
595        };
596        assert_eq!(
597            line,
598            LineString3DGeometry {
599                _type: "LineString3D".into(),
600                coordinates: vec![Point3D(0.0, 0.0, 0.0), Point3D(1.0, 1.0, 1.0)],
601                m_values: None,
602                bbox: None
603            }
604        );
605        let line_str = serde_json::to_string(&line).unwrap();
606        assert_eq!(
607            line_str,
608            "{\"type\":\"LineString3D\",\"coordinates\":[[0.0,0.0,0.0],[1.0,1.0,1.0]]}"
609        );
610        let str_line: LineString3DGeometry = serde_json::from_str(&line_str).unwrap();
611        assert_eq!(str_line, line);
612    }
613
614    #[test]
615    fn test_multi_point_geometry() {
616        let multi_point = MultiPointGeometry {
617            _type: "MultiPoint".into(),
618            coordinates: vec![Point(0.0, 0.0), Point(1.0, 1.0)],
619            m_values: None,
620            bbox: None,
621        };
622        assert_eq!(
623            multi_point,
624            MultiPointGeometry {
625                _type: "MultiPoint".into(),
626                coordinates: vec![Point(0.0, 0.0), Point(1.0, 1.0)],
627                m_values: None,
628                bbox: None
629            }
630        );
631        let multi_point_str = serde_json::to_string(&multi_point).unwrap();
632        assert_eq!(
633            multi_point_str,
634            "{\"type\":\"MultiPoint\",\"coordinates\":[[0.0,0.0],[1.0,1.0]]}"
635        );
636        let str_multi_point: MultiPointGeometry = serde_json::from_str(&multi_point_str).unwrap();
637        assert_eq!(str_multi_point, multi_point);
638    }
639
640    #[test]
641    fn test_multi_point3d_geometry() {
642        let multi_point = MultiPoint3DGeometry {
643            _type: "MultiPoint3D".into(),
644            coordinates: vec![Point3D(0.0, 0.0, 0.0), Point3D(1.0, 1.0, 1.0)],
645            m_values: None,
646            bbox: None,
647        };
648        assert_eq!(
649            multi_point,
650            MultiPoint3DGeometry {
651                _type: "MultiPoint3D".into(),
652                coordinates: vec![Point3D(0.0, 0.0, 0.0), Point3D(1.0, 1.0, 1.0)],
653                m_values: None,
654                bbox: None
655            }
656        );
657        let multi_point_str = serde_json::to_string(&multi_point).unwrap();
658        assert_eq!(
659            multi_point_str,
660            "{\"type\":\"MultiPoint3D\",\"coordinates\":[[0.0,0.0,0.0],[1.0,1.0,1.0]]}"
661        );
662        let str_multi_point: MultiPoint3DGeometry = serde_json::from_str(&multi_point_str).unwrap();
663        assert_eq!(str_multi_point, multi_point);
664    }
665
666    #[test]
667    fn test_polygon_geometry() {
668        let polygon = PolygonGeometry {
669            _type: "Polygon".into(),
670            coordinates: vec![vec![Point(0.0, 0.0), Point(1.0, 1.0), Point(0.0, 1.0)]],
671            m_values: None,
672            bbox: None,
673        };
674        assert_eq!(
675            polygon,
676            PolygonGeometry {
677                _type: "Polygon".into(),
678                coordinates: vec![vec![Point(0.0, 0.0), Point(1.0, 1.0), Point(0.0, 1.0)]],
679                m_values: None,
680                bbox: None
681            }
682        );
683        let polygon_str = serde_json::to_string(&polygon).unwrap();
684        assert_eq!(
685            polygon_str,
686            "{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,1.0],[0.0,1.0]]]}"
687        );
688        let str_polygon: PolygonGeometry = serde_json::from_str(&polygon_str).unwrap();
689        assert_eq!(str_polygon, polygon);
690    }
691
692    #[test]
693    fn test_polygon3d_geometry() {
694        let polygon = Polygon3DGeometry {
695            _type: "Polygon3D".into(),
696            coordinates: vec![vec![
697                Point3D(0.0, 0.0, 0.0),
698                Point3D(1.0, 1.0, 1.0),
699                Point3D(0.0, 1.0, 1.0),
700            ]],
701            m_values: None,
702            bbox: None,
703        };
704        assert_eq!(
705            polygon,
706            Polygon3DGeometry {
707                _type: "Polygon3D".into(),
708                coordinates: vec![vec![
709                    Point3D(0.0, 0.0, 0.0),
710                    Point3D(1.0, 1.0, 1.0),
711                    Point3D(0.0, 1.0, 1.0)
712                ]],
713                m_values: None,
714                bbox: None
715            }
716        );
717        let polygon_str = serde_json::to_string(&polygon).unwrap();
718        assert_eq!(
719            polygon_str,
720            "{\"type\":\"Polygon3D\",\"coordinates\":[[[0.0,0.0,0.0],[1.0,1.0,1.0],[0.0,1.0,1.\
721             0]]]}"
722        );
723        let str_polygon: Polygon3DGeometry = serde_json::from_str(&polygon_str).unwrap();
724        assert_eq!(str_polygon, polygon);
725    }
726
727    #[test]
728    fn test_multi_polygon_geometry() {
729        let multi_polygon = MultiPolygonGeometry {
730            _type: "MultiPolygon".into(),
731            coordinates: vec![vec![vec![Point(0.0, 0.0), Point(1.0, 1.0), Point(0.0, 1.0)]]],
732            m_values: None,
733            bbox: None,
734        };
735        assert_eq!(
736            multi_polygon,
737            MultiPolygonGeometry {
738                _type: "MultiPolygon".into(),
739                coordinates: vec![vec![vec![Point(0.0, 0.0), Point(1.0, 1.0), Point(0.0, 1.0)]]],
740                m_values: None,
741                bbox: None
742            }
743        );
744        let multi_polygon_str = serde_json::to_string(&multi_polygon).unwrap();
745        assert_eq!(
746            multi_polygon_str,
747            "{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.0,0.0],[1.0,1.0],[0.0,1.0]]]]}"
748        );
749        let str_multi_polygon: MultiPolygonGeometry =
750            serde_json::from_str(&multi_polygon_str).unwrap();
751        assert_eq!(str_multi_polygon, multi_polygon);
752    }
753
754    #[test]
755    fn test_multi_polygon3d_geometry() {
756        let multi_polygon = MultiPolygon3DGeometry {
757            _type: "MultiPolygon3D".into(),
758            coordinates: vec![vec![vec![
759                Point3D(0.0, 0.0, 0.0),
760                Point3D(1.0, 1.0, 1.0),
761                Point3D(0.0, 1.0, 1.0),
762            ]]],
763            m_values: None,
764            bbox: None,
765        };
766        assert_eq!(
767            multi_polygon,
768            MultiPolygon3DGeometry {
769                _type: "MultiPolygon3D".into(),
770                coordinates: vec![vec![vec![
771                    Point3D(0.0, 0.0, 0.0),
772                    Point3D(1.0, 1.0, 1.0),
773                    Point3D(0.0, 1.0, 1.0)
774                ]]],
775                m_values: None,
776                bbox: None
777            }
778        );
779        let multi_polygon_str = serde_json::to_string(&multi_polygon).unwrap();
780        assert_eq!(
781            multi_polygon_str,
782            "{\"type\":\"MultiPolygon3D\",\"coordinates\":[[[[0.0,0.0,0.0],[1.0,1.0,1.0],[0.0,1.0,\
783             1.0]]]]}"
784        );
785        let str_multi_polygon: MultiPolygon3DGeometry =
786            serde_json::from_str(&multi_polygon_str).unwrap();
787        assert_eq!(str_multi_polygon, multi_polygon);
788    }
789
790    #[test]
791    fn test_vector_geometry_default() {
792        let default = VectorGeometry::default();
793        assert_eq!(default, VectorGeometry::Point(VectorPointGeometry::default()));
794
795        let default_instance: VectorGeometry = Default::default();
796        assert_eq!(default, default_instance);
797    }
798
799    #[test]
800    fn test_vector_geometry_bbox() {
801        let vgt_point: VectorGeometry = VectorGeometry::Point(VectorPointGeometry {
802            _type: "Point".into(),
803            coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(2.0), m: None, t: None },
804            bbox: Some(BBox3D {
805                left: -1.0,
806                bottom: -2.0,
807                right: -3.0,
808                top: -4.0,
809                near: -5.0,
810                far: -6.0,
811            }),
812            is_3d: true,
813            offset: None,
814            vec_bbox: Some(BBox3D {
815                left: 0.0,
816                bottom: 1.0,
817                right: 0.0,
818                top: 1.0,
819                near: 2.0,
820                far: 2.0,
821            }),
822            indices: None,
823            tesselation: None,
824        });
825        assert_eq!(vgt_point.bbox().unwrap(), BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0));
826        assert_eq!(vgt_point.vec_bbox().unwrap(), BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0));
827        let vgt_multi_point: VectorGeometry =
828            VectorGeometry::MultiPoint(VectorMultiPointGeometry {
829                _type: "MultiPoint".into(),
830                coordinates: vec![VectorPoint { x: 0.0, y: 1.0, z: Some(2.0), m: None, t: None }],
831                bbox: Some(BBox3D {
832                    left: -1.0,
833                    bottom: -2.0,
834                    right: -3.0,
835                    top: -4.0,
836                    near: -5.0,
837                    far: -6.0,
838                }),
839                is_3d: true,
840                offset: None,
841                vec_bbox: Some(BBox3D {
842                    left: 0.0,
843                    bottom: 1.0,
844                    right: 0.0,
845                    top: 1.0,
846                    near: 2.0,
847                    far: 2.0,
848                }),
849                indices: None,
850                tesselation: None,
851            });
852        assert_eq!(
853            vgt_multi_point.bbox().unwrap(),
854            BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0)
855        );
856        assert_eq!(vgt_multi_point.vec_bbox().unwrap(), BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0));
857        let vgt_line_string: VectorGeometry =
858            VectorGeometry::LineString(VectorLineStringGeometry {
859                _type: "LineString".into(),
860                coordinates: vec![VectorPoint { x: 0.0, y: 1.0, z: Some(2.0), m: None, t: None }],
861                bbox: Some(BBox3D {
862                    left: -1.0,
863                    bottom: -2.0,
864                    right: -3.0,
865                    top: -4.0,
866                    near: -5.0,
867                    far: -6.0,
868                }),
869                is_3d: true,
870                offset: None,
871                vec_bbox: Some(BBox3D {
872                    left: 0.0,
873                    bottom: 1.0,
874                    right: 0.0,
875                    top: 1.0,
876                    near: 2.0,
877                    far: 2.0,
878                }),
879                indices: None,
880                tesselation: None,
881            });
882        assert_eq!(
883            vgt_line_string.bbox().unwrap(),
884            BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0)
885        );
886        assert_eq!(vgt_line_string.vec_bbox().unwrap(), BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0));
887        let vgt_multi_line_string: VectorGeometry =
888            VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
889                _type: "MultiLineString".into(),
890                coordinates: vec![vec![VectorPoint {
891                    x: 0.0,
892                    y: 1.0,
893                    z: Some(2.0),
894                    m: None,
895                    t: None,
896                }]],
897                bbox: Some(BBox3D {
898                    left: -1.0,
899                    bottom: -2.0,
900                    right: -3.0,
901                    top: -4.0,
902                    near: -5.0,
903                    far: -6.0,
904                }),
905                is_3d: true,
906                offset: None,
907                vec_bbox: Some(BBox3D {
908                    left: 0.0,
909                    bottom: 1.0,
910                    right: 0.0,
911                    top: 1.0,
912                    near: 2.0,
913                    far: 2.0,
914                }),
915                indices: None,
916                tesselation: None,
917            });
918        assert_eq!(
919            vgt_multi_line_string.bbox().unwrap(),
920            BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0)
921        );
922        assert_eq!(
923            vgt_multi_line_string.vec_bbox().unwrap(),
924            BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0)
925        );
926        let vgt_polygon: VectorGeometry = VectorGeometry::Polygon(VectorPolygonGeometry {
927            _type: "Polygon".into(),
928            coordinates: vec![vec![VectorPoint { x: 0.0, y: 1.0, z: Some(2.0), m: None, t: None }]],
929            bbox: Some(BBox3D {
930                left: -1.0,
931                bottom: -2.0,
932                right: -3.0,
933                top: -4.0,
934                near: -5.0,
935                far: -6.0,
936            }),
937            is_3d: true,
938            offset: None,
939            vec_bbox: Some(BBox3D {
940                left: 0.0,
941                bottom: 1.0,
942                right: 0.0,
943                top: 1.0,
944                near: 2.0,
945                far: 2.0,
946            }),
947            indices: None,
948            tesselation: None,
949        });
950        assert_eq!(vgt_polygon.bbox().unwrap(), BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0));
951        assert_eq!(vgt_polygon.vec_bbox().unwrap(), BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0));
952        let vgt_multi_polygon: VectorGeometry =
953            VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
954                _type: "MultiPolygon".into(),
955                coordinates: vec![vec![vec![VectorPoint {
956                    x: 0.0,
957                    y: 1.0,
958                    z: Some(2.0),
959                    m: None,
960                    t: None,
961                }]]],
962                bbox: Some(BBox3D {
963                    left: -1.0,
964                    bottom: -2.0,
965                    right: -3.0,
966                    top: -4.0,
967                    near: -5.0,
968                    far: -6.0,
969                }),
970                is_3d: true,
971                offset: None,
972                vec_bbox: Some(BBox3D {
973                    left: 0.0,
974                    bottom: 1.0,
975                    right: 0.0,
976                    top: 1.0,
977                    near: 2.0,
978                    far: 2.0,
979                }),
980                indices: None,
981                tesselation: None,
982            });
983        assert_eq!(
984            vgt_multi_polygon.bbox().unwrap(),
985            BBox3D::new(-1.0, -2.0, -3.0, -4.0, -5.0, -6.0)
986        );
987        assert_eq!(
988            vgt_multi_polygon.vec_bbox().unwrap(),
989            BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 2.0)
990        );
991    }
992
993    #[test]
994    fn from_string() {
995        let geo_str = json!({
996            "type": "Point",
997            "coordinates": [0, 0],
998        })
999        .to_string();
1000        let _feature: Geometry = serde_json::from_str(&geo_str).unwrap();
1001
1002        let feature_str = json!({
1003            "type": "Feature",
1004            "properties": { "a": 1 },
1005            "geometry": {
1006                "type": "Point",
1007                "coordinates": [0, 0],
1008            }
1009        })
1010        .to_string();
1011        let _feature: Feature = serde_json::from_str(&feature_str).unwrap();
1012
1013        let json_string = r#"{
1014            "type": "FeatureCollection",
1015            "features": [
1016                {
1017                    "type": "Feature",
1018                    "properties": { "a": 1 },
1019                    "geometry": {
1020                        "type": "Point",
1021                        "coordinates": [0, 0]
1022                    }
1023                },
1024                {
1025                    "type": "Feature",
1026                    "properties": { "b": 2 },
1027                    "geometry": {
1028                        "type": "Point3D",
1029                        "coordinates": [45, 45, 1]
1030                    }
1031                },
1032                {
1033                    "type": "Feature",
1034                    "properties": { "c": 3 },
1035                    "geometry": {
1036                        "type": "MultiPoint",
1037                        "coordinates": [
1038                            [-45, -45],
1039                            [-45, 45]
1040                        ]
1041                    }
1042                },
1043                {
1044                    "type": "Feature",
1045                    "properties": { "d": 4 },
1046                    "geometry": {
1047                        "type": "MultiPoint3D",
1048                        "coordinates": [
1049                            [45, -45, 1],
1050                            [-180, 20, 2]
1051                        ]
1052                    }
1053                }
1054            ]
1055        }"#;
1056        let data: FeatureCollection = serde_json::from_str(json_string).unwrap();
1057        assert_eq!(data.features.len(), 4);
1058
1059        let data2: JSONCollection = serde_json::from_str(json_string).unwrap();
1060        if let JSONCollection::FeatureCollection(fc) = data2 {
1061            assert_eq!(fc.features.len(), 4);
1062            if let WMFeature::Feature(first_feature) = &fc.features[0] {
1063                assert_eq!(first_feature.id, None);
1064                assert_eq!(first_feature._type, "Feature".into());
1065                assert_eq!(
1066                    first_feature.geometry,
1067                    Geometry::Point(PointGeometry {
1068                        _type: "Point".into(),
1069                        coordinates: Point(0.0, 0.0),
1070                        ..Default::default()
1071                    })
1072                );
1073            } else {
1074                panic!("Expected Feature");
1075            }
1076        } else {
1077            panic!("Expected FeatureCollection");
1078        }
1079    }
1080
1081    #[test]
1082    fn vector_geometry_new_point() {
1083        let point = VectorPoint::from_xy(0.5, 0.75);
1084        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1085        let geometry = VectorGeometry::new_point(point.clone(), Some(bbox));
1086
1087        assert_eq!(
1088            geometry,
1089            VectorGeometry::Point(VectorPointGeometry {
1090                _type: "Point".into(),
1091                coordinates: point,
1092                bbox: Some(bbox),
1093                is_3d: false,
1094                ..Default::default()
1095            })
1096        );
1097    }
1098
1099    #[test]
1100    fn vector_geometry_new_point_3d() {
1101        let point = VectorPoint::from_xyz(0.5, 0.75, 1.0);
1102        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1103        let geometry = VectorGeometry::new_point(point.clone(), Some(bbox));
1104
1105        assert_eq!(
1106            geometry,
1107            VectorGeometry::Point(VectorPointGeometry {
1108                _type: "Point".into(),
1109                coordinates: point,
1110                bbox: Some(bbox),
1111                is_3d: true,
1112                ..Default::default()
1113            })
1114        );
1115    }
1116
1117    #[test]
1118    fn vector_geometry_new_multipoint() {
1119        let multipoint = vec![VectorPoint::from_xy(0.5, 0.75), VectorPoint::from_xy(1.75, 2.5)];
1120        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1121        let geometry = VectorGeometry::new_multipoint(multipoint.clone(), Some(bbox));
1122
1123        assert_eq!(
1124            geometry,
1125            VectorGeometry::MultiPoint(VectorMultiPointGeometry {
1126                _type: "MultiPoint".into(),
1127                coordinates: multipoint,
1128                bbox: Some(bbox),
1129                is_3d: false,
1130                ..Default::default()
1131            })
1132        );
1133    }
1134
1135    #[test]
1136    fn vector_geometry_new_multipoint_3d() {
1137        let multipoint =
1138            vec![VectorPoint::from_xyz(0.5, 0.75, -1.0), VectorPoint::from_xyz(1.75, 2.5, 1.)];
1139        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1140        let geometry = VectorGeometry::new_multipoint(multipoint.clone(), Some(bbox));
1141
1142        assert_eq!(
1143            geometry,
1144            VectorGeometry::MultiPoint(VectorMultiPointGeometry {
1145                _type: "MultiPoint".into(),
1146                coordinates: multipoint,
1147                bbox: Some(bbox),
1148                is_3d: true,
1149                ..Default::default()
1150            })
1151        );
1152    }
1153
1154    #[test]
1155    fn vector_geometry_new_line_string() {
1156        let line_string = vec![VectorPoint::from_xy(0.5, 0.75), VectorPoint::from_xy(1.75, 2.5)];
1157        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1158        let geometry = VectorGeometry::new_linestring(line_string.clone(), Some(bbox));
1159
1160        assert_eq!(
1161            geometry,
1162            VectorGeometry::LineString(VectorLineStringGeometry {
1163                _type: "LineString".into(),
1164                coordinates: line_string,
1165                bbox: Some(bbox),
1166                is_3d: false,
1167                ..Default::default()
1168            })
1169        );
1170    }
1171
1172    #[test]
1173    fn vector_geometry_new_linestring_3d() {
1174        let linestring =
1175            vec![VectorPoint::from_xyz(0.5, 0.75, -1.0), VectorPoint::from_xyz(1.75, 2.5, 1.)];
1176        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1177        let geometry = VectorGeometry::new_linestring(linestring.clone(), Some(bbox));
1178
1179        assert_eq!(
1180            geometry,
1181            VectorGeometry::LineString(VectorLineStringGeometry {
1182                _type: "LineString".into(),
1183                coordinates: linestring,
1184                bbox: Some(bbox),
1185                is_3d: true,
1186                ..Default::default()
1187            })
1188        );
1189    }
1190
1191    #[test]
1192    fn vector_geometry_new_multi_line_string() {
1193        let multi_line_string = vec![
1194            vec![VectorPoint::from_xy(0.5, 0.75), VectorPoint::from_xy(1.75, 2.5)],
1195            vec![VectorPoint::from_xy(1.5, 2.75), VectorPoint::from_xy(3.75, 4.5)],
1196        ];
1197        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1198        let geometry = VectorGeometry::new_multilinestring(multi_line_string.clone(), Some(bbox));
1199
1200        assert_eq!(
1201            geometry,
1202            VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
1203                _type: "MultiLineString".into(),
1204                coordinates: multi_line_string,
1205                bbox: Some(bbox),
1206                is_3d: false,
1207                ..Default::default()
1208            })
1209        );
1210    }
1211
1212    #[test]
1213    fn vector_geometry_new_multi_line_string_3d() {
1214        let multi_line_string = vec![
1215            vec![VectorPoint::from_xyz(0.5, 0.75, -1.), VectorPoint::from_xyz(1.75, 2.5, -2.)],
1216            vec![VectorPoint::from_xyz(1.5, 2.75, 1.), VectorPoint::from_xyz(3.75, 4.5, 2.)],
1217        ];
1218        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1219        let geometry = VectorGeometry::new_multilinestring(multi_line_string.clone(), Some(bbox));
1220
1221        assert_eq!(
1222            geometry,
1223            VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
1224                _type: "MultiLineString".into(),
1225                coordinates: multi_line_string,
1226                bbox: Some(bbox),
1227                is_3d: true,
1228                ..Default::default()
1229            })
1230        );
1231    }
1232
1233    #[test]
1234    fn vector_geometry_new_polygon() {
1235        let polygon = vec![
1236            vec![VectorPoint::from_xy(0.5, 0.75), VectorPoint::from_xy(1.75, 2.5)],
1237            vec![VectorPoint::from_xy(1.5, 2.75), VectorPoint::from_xy(3.75, 4.5)],
1238        ];
1239        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1240        let geometry = VectorGeometry::new_polygon(polygon.clone(), Some(bbox));
1241
1242        assert_eq!(
1243            geometry,
1244            VectorGeometry::Polygon(VectorPolygonGeometry {
1245                _type: "Polygon".into(),
1246                coordinates: polygon,
1247                bbox: Some(bbox),
1248                is_3d: false,
1249                ..Default::default()
1250            })
1251        );
1252    }
1253
1254    #[test]
1255    fn vector_geometry_new_polygon_3d() {
1256        let polygon_3d = vec![
1257            vec![VectorPoint::from_xyz(0.5, 0.75, -1.), VectorPoint::from_xyz(1.75, 2.5, -2.)],
1258            vec![VectorPoint::from_xyz(1.5, 2.75, 1.), VectorPoint::from_xyz(3.75, 4.5, 2.)],
1259        ];
1260        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1261        let geometry = VectorGeometry::new_polygon(polygon_3d.clone(), Some(bbox));
1262
1263        assert_eq!(
1264            geometry,
1265            VectorGeometry::Polygon(VectorPolygonGeometry {
1266                _type: "Polygon".into(),
1267                coordinates: polygon_3d,
1268                bbox: Some(bbox),
1269                is_3d: true,
1270                ..Default::default()
1271            })
1272        );
1273    }
1274
1275    #[test]
1276    fn vector_geometry_new_multipolygon() {
1277        let multipolygon = vec![
1278            vec![
1279                vec![VectorPoint::from_xy(0.5, 0.75), VectorPoint::from_xy(1.75, 2.5)],
1280                vec![VectorPoint::from_xy(1.5, 2.75), VectorPoint::from_xy(3.75, 4.5)],
1281            ],
1282            vec![
1283                vec![VectorPoint::from_xy(1.5, 2.75), VectorPoint::from_xy(3.75, 4.5)],
1284                vec![VectorPoint::from_xy(5.5, 6.75), VectorPoint::from_xy(7.75, 8.5)],
1285            ],
1286        ];
1287        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1288        let geometry = VectorGeometry::new_multipolygon(multipolygon.clone(), Some(bbox));
1289
1290        assert_eq!(
1291            geometry,
1292            VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
1293                _type: "MultiPolygon".into(),
1294                coordinates: multipolygon,
1295                bbox: Some(bbox),
1296                is_3d: false,
1297                ..Default::default()
1298            })
1299        );
1300    }
1301
1302    #[test]
1303    fn vector_geometry_new_multipolygon_3d() {
1304        let multipolygon = vec![
1305            vec![
1306                vec![VectorPoint::from_xyz(0.5, 0.75, -1.), VectorPoint::from_xyz(1.75, 2.5, -2.)],
1307                vec![VectorPoint::from_xyz(1.5, 2.75, -3.), VectorPoint::from_xyz(3.75, 4.5, -4.)],
1308            ],
1309            vec![
1310                vec![VectorPoint::from_xyz(1.5, 2.75, 1.), VectorPoint::from_xyz(3.75, 4.5, 2.)],
1311                vec![VectorPoint::from_xyz(5.5, 6.75, 3.), VectorPoint::from_xyz(7.75, 8.5, 4.)],
1312            ],
1313        ];
1314        let bbox = BBox3D::new(0.0, 1.0, 0.0, 1.0, 2.0, 3.0);
1315        let geometry = VectorGeometry::new_multipolygon(multipolygon.clone(), Some(bbox));
1316
1317        assert_eq!(
1318            geometry,
1319            VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
1320                _type: "MultiPolygon".into(),
1321                coordinates: multipolygon,
1322                bbox: Some(bbox),
1323                is_3d: true,
1324                ..Default::default()
1325            })
1326        );
1327    }
1328
1329    #[test]
1330    fn point_or_point3d() {
1331        let point = Point(0., 1.);
1332        let point_or_point3d: PointOrPoint3D = point.into();
1333        assert_eq!(point_or_point3d, PointOrPoint3D(0., 1., None));
1334
1335        let point = Point3D(0., 1., 2.);
1336        let point_or_point3d: PointOrPoint3D = point.into();
1337        assert_eq!(point_or_point3d, PointOrPoint3D(0., 1., Some(2.)));
1338    }
1339}