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