extern crate alloc;
mod geometry;
mod impls;
mod map;
mod value;
mod vector_point;
#[cfg(test)]
mod tests {
use alloc::vec;
use s2json_core::*;
use serde::{Deserialize, Serialize};
#[test]
fn face() {
let face = Face::Face0;
assert_eq!(u8::from(face), 0);
let face = Face::Face1;
assert_eq!(u8::from(face), 1);
let face = Face::Face2;
assert_eq!(u8::from(face), 2);
let face = Face::Face3;
assert_eq!(u8::from(face), 3);
let face = Face::Face4;
assert_eq!(u8::from(face), 4);
let face = Face::Face5;
assert_eq!(u8::from(face), 5);
assert_eq!(Face::Face0, Face::from(0));
assert_eq!(Face::Face1, Face::from(1));
assert_eq!(Face::Face2, Face::from(2));
assert_eq!(Face::Face3, Face::from(3));
assert_eq!(Face::Face4, Face::from(4));
assert_eq!(Face::Face5, Face::from(5));
}
#[test]
fn defaults() {
let f: Feature = Default::default();
assert_eq!(f._type, "Feature".into());
assert_eq!(f.id, None);
assert_eq!(f.properties, Properties::default());
assert_eq!(f.geometry, Geometry::default());
assert_eq!(f.metadata, None);
let f: VectorFeature = Default::default();
assert_eq!(f._type, "VectorFeature".into());
assert_eq!(f.id, None);
assert_eq!(f.face, 0.into());
assert_eq!(f.properties, Properties::default());
assert_eq!(f.geometry, VectorGeometry::default());
assert_eq!(f.metadata, None);
}
#[test]
fn feature_collection_new() {
let mut attributions = Attributions::new();
attributions.insert("Open S2".into(), "https://opens2.com/legal/data".into());
let mut fc = FeatureCollection::<()>::new(Some(attributions.clone()));
assert_eq!(fc._type, FeatureCollectionType::FeatureCollection);
assert_eq!(fc.features.len(), 0);
assert_eq!(fc.attributions, Some(attributions.clone()));
fc.update_bbox(BBox::new(5., -2., 35., 2.2));
assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
let string = serde_json::to_string(&fc).unwrap();
assert_eq!(
string,
"{\"type\":\"FeatureCollection\",\"features\":[],\"attributions\":{\"Open S2\":\"https://opens2.com/legal/data\"},\"bbox\":[5.0,-2.0,35.0,2.2]}"
);
let back_to_fc: FeatureCollection = serde_json::from_str(&string).unwrap();
assert_eq!(back_to_fc, fc);
}
#[test]
fn s2_feature_collection_new() {
let mut attributions = Attributions::new();
attributions.insert("Open S2".into(), "https://opens2.com/legal/data".into());
let mut fc = S2FeatureCollection::new(Some(attributions.clone()));
assert_eq!(fc._type, S2FeatureCollectionType::S2FeatureCollection);
assert_eq!(fc.features.len(), 0);
assert_eq!(fc.attributions, Some(attributions.clone()));
fc.update_bbox(BBox::new(5., -2., 35., 2.2));
assert_eq!(fc.bbox, Some(BBox::new(5., -2., 35., 2.2)));
fc.add_face(0.into());
fc.add_face(3.into());
assert_eq!(fc.faces, vec![0.into(), 3.into()]);
let string = serde_json::to_string(&fc).unwrap();
assert_eq!(
string,
"{\"type\":\"S2FeatureCollection\",\"features\":[],\"faces\":[0,3],\"attributions\":{\"Open S2\":\"https://opens2.com/legal/data\"},\"bbox\":[5.0,-2.0,35.0,2.2]}"
);
let back_to_fc: S2FeatureCollection = serde_json::from_str(&string).unwrap();
assert_eq!(back_to_fc, fc);
}
#[test]
fn feature_new() {
let fc: Feature = Feature::new(
Some(22),
Properties::new(),
Geometry::Point(PointGeometry {
_type: "Point".into(),
coordinates: Point(0.0, 0.0),
m_values: None,
bbox: None,
}),
None,
);
assert_eq!(fc.id, Some(22));
assert_eq!(fc._type, "Feature".into());
assert_eq!(
fc.geometry,
Geometry::Point(PointGeometry {
_type: "Point".into(),
coordinates: Point(0.0, 0.0),
m_values: None,
bbox: None,
})
);
assert_eq!(fc.properties, Properties::new());
assert_eq!(fc.metadata, None);
}
#[test]
fn s2_feature_new() {
let fc: VectorFeature = VectorFeature::new_wm(
Some(55),
Properties::new(),
VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
}),
None,
);
assert_eq!(fc.id, Some(55));
assert_eq!(fc._type, "VectorFeature".into());
assert_eq!(
fc.geometry,
VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
})
);
assert_eq!(fc.properties, Properties::new());
assert_eq!(fc.metadata, None);
assert_eq!(fc.face, 0.into());
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug)]
struct MetaTest {
name: String,
value: String,
}
let fc = VectorFeature::<MetaTest>::new_s2(
Some(55),
3.into(),
Properties::new(),
VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
}),
Some(MetaTest { name: "test".into(), value: "value".into() }),
);
assert_eq!(fc.id, Some(55));
assert_eq!(fc._type, "S2Feature".into());
assert_eq!(
fc.geometry,
VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
})
);
assert_eq!(fc.properties, Properties::new());
assert_eq!(fc.metadata, Some(MetaTest { name: "test".into(), value: "value".into() }));
assert_eq!(fc.face, 3.into());
let new_geo = VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 5.0, y: 4.0, z: Some(-3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
});
let fc_clone_new_geometry =
VectorFeature::<MetaTest>::from_vector_feature(&fc, Some(new_geo.clone()));
assert_eq!(fc_clone_new_geometry.geometry, new_geo);
}
#[test]
fn parse_feature_multipoint() {
let json_string = r#"{
"type": "Feature",
"properties": {},
"geometry": {
"type": "MultiPoint",
"coordinates": [
[-13.292352825505162, 54.34883408204476],
[36.83102287804303, 59.56941785818924],
[50.34083898563978, 16.040052775278994],
[76.38149901912357, 35.155968522292056]
]
}
}"#;
let feature: Feature = serde_json::from_str(json_string).unwrap();
assert_eq!(feature._type, "Feature".into());
assert_eq!(
feature.geometry,
Geometry::MultiPoint(MultiPointGeometry {
_type: "MultiPoint".into(),
coordinates: vec![
Point(-13.292352825505162, 54.34883408204476),
Point(36.83102287804303, 59.56941785818924),
Point(50.34083898563978, 16.040052775278994),
Point(76.38149901912357, 35.155968522292056),
],
..Default::default()
})
);
let back_to_str = serde_json::to_string(&feature).unwrap();
assert_eq!(
back_to_str,
"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"MultiPoint\",\"\
coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
155968522292056]]}}"
);
}
#[test]
fn parse_feature_linestring() {
let json_string = r#"{
"type": "Feature",
"properties": {},
"geometry": {
"type": "LineString",
"coordinates": [
[-13.292352825505162, 54.34883408204476],
[36.83102287804303, 59.56941785818924],
[50.34083898563978, 16.040052775278994],
[76.38149901912357, 35.155968522292056]
]
}
}"#;
let feature: Feature = serde_json::from_str(json_string).unwrap();
assert_eq!(feature._type, "Feature".into());
assert_eq!(
feature.geometry,
Geometry::LineString(LineStringGeometry {
_type: "LineString".into(),
coordinates: vec![
Point(-13.292352825505162, 54.34883408204476),
Point(36.83102287804303, 59.56941785818924),
Point(50.34083898563978, 16.040052775278994),
Point(76.38149901912357, 35.155968522292056),
],
..Default::default()
})
);
let back_to_str = serde_json::to_string(&feature).unwrap();
assert_eq!(
back_to_str,
"{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"\
coordinates\":[[-13.292352825505162,54.34883408204476],[36.83102287804303,59.\
56941785818924],[50.34083898563978,16.040052775278994],[76.38149901912357,35.\
155968522292056]]}}"
);
}
#[test]
fn parse_vector_feature_linestring() {
let json_string = r#"{
"type": "VectorFeature",
"face": 0,
"properties": {},
"geometry": {
"type": "LineString",
"is3D": false,
"coordinates": [
{ "x": -13.292352825505162, "y": 54.34883408204476 },
{ "x": 36.83102287804303, "y": 59.56941785818924 },
{ "x": 50.34083898563978, "y": 16.040052775278994 },
{ "x": 76.38149901912357, "y": 35.155968522292056 }
]
}
}"#;
let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
assert_eq!(feature._type, "VectorFeature".into());
let geometry = feature.geometry;
assert_eq!(
geometry,
VectorGeometry::LineString(VectorLineStringGeometry {
_type: VectorGeometryType::LineString,
is_3d: false,
coordinates: vec![
VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
],
..Default::default()
})
)
}
#[test]
#[should_panic(expected = "Invalid vector geometry type: LinesString")]
fn vector_geometry_type_from() {
let str_bad = "LinesString";
let _ = VectorGeometryType::from(str_bad);
}
#[test]
fn parse_vector_feature_multipoint() {
let json_string = r#"{
"type": "VectorFeature",
"face": 0,
"properties": {},
"geometry": {
"type": "MultiPoint",
"is3D": false,
"coordinates": [
{ "x": -13.292352825505162, "y": 54.34883408204476 },
{ "x": 36.83102287804303, "y": 59.56941785818924 },
{ "x": 50.34083898563978, "y": 16.040052775278994 },
{ "x": 76.38149901912357, "y": 35.155968522292056 }
]
}
}"#;
let feature: VectorFeature = serde_json::from_str(json_string).unwrap();
assert_eq!(feature._type, "VectorFeature".into());
let geometry = feature.geometry;
assert_eq!(
geometry,
VectorGeometry::MultiPoint(VectorMultiPointGeometry {
_type: VectorGeometryType::MultiPoint,
is_3d: false,
coordinates: vec![
VectorPoint::from_xy(-13.292352825505162, 54.34883408204476),
VectorPoint::from_xy(36.83102287804303, 59.56941785818924),
VectorPoint::from_xy(50.34083898563978, 16.040052775278994),
VectorPoint::from_xy(76.38149901912357, 35.155968522292056),
],
..Default::default()
})
)
}
#[test]
#[should_panic(expected = "Invalid geometry type: MultiLinesString")]
fn vector_geometry_type_from_bad() {
let str_bad = "MultiLinesString";
let _ = GeometryType::from(str_bad);
}
#[test]
fn serde_face() {
let face_0 = Face::Face0;
let serialized = serde_json::to_string(&face_0).unwrap();
assert_eq!(serialized, "0");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face0);
let face_1 = Face::Face1;
let serialized = serde_json::to_string(&face_1).unwrap();
assert_eq!(serialized, "1");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face1);
let face_2 = Face::Face2;
let serialized = serde_json::to_string(&face_2).unwrap();
assert_eq!(serialized, "2");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face2);
let face_3 = Face::Face3;
let serialized = serde_json::to_string(&face_3).unwrap();
assert_eq!(serialized, "3");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face3);
let face_4 = Face::Face4;
let serialized = serde_json::to_string(&face_4).unwrap();
assert_eq!(serialized, "4");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face4);
let face_5 = Face::Face5;
let serialized = serde_json::to_string(&face_5).unwrap();
assert_eq!(serialized, "5");
let deserialize = serde_json::from_str::<Face>(&serialized).unwrap();
assert_eq!(deserialize, Face::Face5);
}
#[test]
#[should_panic(expected = "Invalid face value")]
fn serde_face_err() {
let _ = serde_json::from_str::<Face>("6").unwrap();
}
#[test]
fn to_m() {
#[derive(Serialize, Deserialize, PartialEq, Clone, Debug, Default)]
struct MetaTest {
name: String,
value: String,
}
let fc = VectorFeature::<MetaTest>::new_s2(
Some(55),
3.into(),
Properties::new(),
VectorGeometry::Point(VectorPointGeometry {
_type: "Point".into(),
coordinates: VectorPoint { x: 0.0, y: 1.0, z: Some(3.), m: None, t: None },
bbox: None,
is_3d: true,
offset: None,
vec_bbox: None,
indices: None,
tessellation: None,
}),
Some(MetaTest { name: "test".into(), value: "value".into() }),
);
let fc_m = fc.to_m_vector_feature(|meta| {
let meta = meta.unwrap().clone();
Some(MValue::from([("a".into(), meta.name.into())]))
});
assert_eq!(fc_m.metadata, Some(MValue::from([("a".into(), "test".into())])));
}
#[test]
fn semi_bad_data_test() {
let data = r#"{"type": "VectorFeature", "geometry": {"type": "Point", "coordinates": {"x": 637012.2400, "y": 849028.3100, "z": 431.6600, "m": {"intensity": 143, "gps_time": 245380.7825, "rgba": {"r": 68, "g": 77, "b": 88, "a": 255}}}}}"#;
let vec_feat: VectorFeature = serde_json::from_str(data).unwrap();
assert_eq!(vec_feat.properties, Properties::new());
assert_eq!(vec_feat.face, Face::default());
let features: Features = serde_json::from_str(data).unwrap();
assert_eq!(features, Features::VectorFeature(vec_feat));
}
}