diff --git a/client/src/pages/Playground.tsx b/client/src/pages/Playground.tsx index 82048143..2b714507 100644 --- a/client/src/pages/Playground.tsx +++ b/client/src/pages/Playground.tsx @@ -89,6 +89,7 @@ const PROPERTIES = { mode: 'boolean', parent: 'boolean', group: 'boolean', + fullcoords: 'boolean', } const PARAMS = { diff --git a/server/model/src/api/args.rs b/server/model/src/api/args.rs index 8546d777..e21a08fa 100644 --- a/server/model/src/api/args.rs +++ b/server/model/src/api/args.rs @@ -60,6 +60,8 @@ pub struct ApiQueryArgs { pub rt: Option, /// If true, the `group` property is set from the parent property pub group: Option, + /// If true, the full 64 bit coordinates are used + pub fullcoords: Option, // ------------------------------------------------------------------------- // Name Property Manipulation @@ -108,6 +110,7 @@ impl Default for ApiQueryArgs { geofence_id: None, parent: None, rt: None, + fullcoords: None, lowercase: None, uppercase: None, capitalize: None, diff --git a/server/model/src/api/collection.rs b/server/model/src/api/collection.rs index 352dfcb3..b4d64e33 100644 --- a/server/model/src/api/collection.rs +++ b/server/model/src/api/collection.rs @@ -39,6 +39,21 @@ impl GeometryHelpers for FeatureCollection { }) .collect() } + + fn to_f32(self) -> Self { + self.into_iter() + .map(|feat| { + if let Some(geometry) = feat.geometry { + Feature { + geometry: Some(geometry.to_f32()), + ..feat + } + } else { + feat + } + }) + .collect() + } } impl EnsureProperties for FeatureCollection { diff --git a/server/model/src/api/geometry.rs b/server/model/src/api/geometry.rs index 3735be19..67b59dde 100644 --- a/server/model/src/api/geometry.rs +++ b/server/model/src/api/geometry.rs @@ -37,6 +37,24 @@ impl EnsurePoints for Geometry { } } +fn trim_precision(data: Vec>>) -> Vec>> { + let mut formatted_data = Vec::new(); + + for outer_vec in data { + let mut formatted_outer_vec = Vec::new(); + for inner_vec in outer_vec { + let mut formatted_inner_vec = Vec::new(); + for num in inner_vec { + formatted_inner_vec.push(format!("{:.6}", num).parse().unwrap()); + } + formatted_outer_vec.push(formatted_inner_vec); + } + formatted_data.push(formatted_outer_vec); + } + + formatted_data +} + impl GeometryHelpers for Geometry { fn simplify(self) -> Self { let mut geometry = match self.value { @@ -53,6 +71,21 @@ impl GeometryHelpers for Geometry { geometry.bbox = geometry.get_bbox(); geometry } + fn to_f32(self) -> Self { + let mut geometry = match self.value { + Value::Polygon(value) => Geometry::from(geojson::Value::Polygon(trim_precision(value))), + Value::MultiPolygon(value) => { + let mut formatted_data: Vec>>> = Vec::new(); + for outer_vec in value { + formatted_data.push(trim_precision(outer_vec)) + } + Geometry::from(geojson::Value::MultiPolygon(formatted_data)) + } + _ => self, + }; + geometry.bbox = geometry.get_bbox(); + geometry + } } impl GetBbox for Geometry { diff --git a/server/model/src/api/mod.rs b/server/model/src/api/mod.rs index c913ad46..5cbd4de4 100644 --- a/server/model/src/api/mod.rs +++ b/server/model/src/api/mod.rs @@ -48,6 +48,7 @@ pub trait ValueHelpers { pub trait GeometryHelpers { fn simplify(self) -> Self; + fn to_f32(self) -> Self; } pub trait FeatureHelpers { diff --git a/server/model/src/db/geofence.rs b/server/model/src/db/geofence.rs index 19c45081..2c2661bc 100644 --- a/server/model/src/db/geofence.rs +++ b/server/model/src/db/geofence.rs @@ -15,6 +15,8 @@ use crate::{ }, }; +use self::api::GeometryHelpers; + use super::{ geofence_property::{Basic, FullPropertyModel}, sea_orm_active_enums::Type, @@ -202,9 +204,14 @@ impl Model { value: serde_json::Value::from(parent_name.clone()), }); } + let geometry = Geometry::from_json_value(self.geometry)?; let mut feature = Feature { - geometry: Some(Geometry::from_json_value(self.geometry)?), + geometry: Some(if args.internal.is_some() || args.fullcoords.is_some() { + geometry + } else { + geometry.to_f32() + }), ..Feature::default() }; for prop in properties.into_iter() {