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