Skip to content

Commit

Permalink
refactor: more consistent and flexible precision trait usage
Browse files Browse the repository at this point in the history
  • Loading branch information
TurtIeSocks committed Jul 30, 2024
1 parent 3c6d3b8 commit 0b873d7
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 35 deletions.
6 changes: 3 additions & 3 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "koji"
version = "1.4.2"
version = "1.5.1"
edition = "2021"

[workspace]
Expand Down
2 changes: 1 addition & 1 deletion server/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "api"
version = "1.5.0"
version = "1.5.1"
edition = "2021"
publish = false

Expand Down
7 changes: 4 additions & 3 deletions server/api/src/public/v1/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use model::{
FeatureHelpers, GeometryHelpers, ToCollection, ToFeature,
},
db::sea_orm_active_enums::Type,
utils::TrimPrecision,
};

#[post("/data")]
Expand All @@ -21,11 +22,11 @@ async fn convert_data(payload: web::Json<Args>) -> Result<HttpResponse, Error> {
..
} = payload.into_inner().init(Some("convert_data"));

let area = if arg_simplify { area.simplify() } else { area };
let area = area
let area = if arg_simplify { area.simplify() } else { area }
.into_iter()
.map(|feat| feat.remove_internal_props())
.collect();
.collect::<FeatureCollection>()
.trim_precision(6);

Ok(utils::response::send(
area,
Expand Down
2 changes: 1 addition & 1 deletion server/model/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "model"
version = "1.5.0"
version = "1.5.1"
edition = "2021"
publish = false

Expand Down
8 changes: 6 additions & 2 deletions server/model/src/api/collection.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use utils::TrimPrecision;

use self::utils::sql_raw;

use super::{args::UnknownId, multi_vec::MultiVec, *};
Expand Down Expand Up @@ -39,13 +41,15 @@ impl GeometryHelpers for FeatureCollection {
})
.collect()
}
}

fn to_f32(self) -> Self {
impl TrimPrecision for FeatureCollection {
fn trim_precision(self, precision: u32) -> Self {
self.into_iter()
.map(|feat| {
if let Some(geometry) = feat.geometry {
Feature {
geometry: Some(geometry.to_f32()),
geometry: Some(geometry.trim_precision(precision)),
..feat
}
} else {
Expand Down
38 changes: 23 additions & 15 deletions server/model/src/api/geometry.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use geo::{MultiPolygon, Polygon, Simplify};
use utils::TrimPrecision;

use super::*;

Expand Down Expand Up @@ -37,22 +38,24 @@ impl EnsurePoints for Geometry {
}
}

fn trim_precision(data: Vec<Vec<Vec<f64>>>) -> Vec<Vec<Vec<f64>>> {
let mut formatted_data = Vec::new();
impl TrimPrecision for Vec<Vec<Vec<f64>>> {
fn trim_precision(self, precision: u32) -> Self {
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());
for outer_vec in self {
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(num.trim_precision(precision));
}
formatted_outer_vec.push(formatted_inner_vec);
}
formatted_outer_vec.push(formatted_inner_vec);
formatted_data.push(formatted_outer_vec);
}
formatted_data.push(formatted_outer_vec);
}

formatted_data
formatted_data
}
}

impl GeometryHelpers for Geometry {
Expand All @@ -71,13 +74,18 @@ impl GeometryHelpers for Geometry {
geometry.bbox = geometry.get_bbox();
geometry
}
fn to_f32(self) -> Self {
}

impl TrimPrecision for Geometry {
fn trim_precision(self, precision: u32) -> Self {
let mut geometry = match self.value {
Value::Polygon(value) => Geometry::from(geojson::Value::Polygon(trim_precision(value))),
Value::Polygon(value) => {
Geometry::from(geojson::Value::Polygon(value.trim_precision(precision)))
}
Value::MultiPolygon(value) => {
let mut formatted_data: Vec<Vec<Vec<Vec<f64>>>> = Vec::new();
for outer_vec in value {
formatted_data.push(trim_precision(outer_vec))
formatted_data.push(outer_vec.trim_precision(precision))
}
Geometry::from(geojson::Value::MultiPolygon(formatted_data))
}
Expand Down
1 change: 0 additions & 1 deletion server/model/src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ pub trait ValueHelpers {

pub trait GeometryHelpers {
fn simplify(self) -> Self;
fn to_f32(self) -> Self;
}

pub trait FeatureHelpers {
Expand Down
2 changes: 1 addition & 1 deletion server/model/src/api/point_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl ToCollection for PointArray {

impl ToText for PointArray {
fn to_text(self, sep_1: &str, sep_2: &str, _poly_sep: bool) -> String {
format!("{}{}{}{}", self[0] as f32, sep_1, self[1] as f32, sep_2)
format!("{}{}{}{}", self[0], sep_1, self[1], sep_2)
}
}

Expand Down
2 changes: 1 addition & 1 deletion server/model/src/api/point_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl ToCollection for PointStruct {

impl ToText for PointStruct {
fn to_text(self, sep_1: &str, sep_2: &str, _poly_sep: bool) -> String {
format!("{}{}{}{}", self.lat as f32, sep_1, self.lon as f32, sep_2)
format!("{}{}{}{}", self.lat, sep_1, self.lon, sep_2)
}
}

Expand Down
4 changes: 3 additions & 1 deletion server/model/src/api/single_vec.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use utils::TrimPrecision;

use super::{collection::Default, *};

pub type SingleVec = Vec<point_array::PointArray>;
Expand Down Expand Up @@ -46,7 +48,7 @@ impl GetBbox for SingleVec {
bbox[3] = point[0]
}
}
Some(bbox)
Some(bbox.into_iter().map(|e| e.trim_precision(6)).collect())
}
}

Expand Down
5 changes: 2 additions & 3 deletions server/model/src/db/geofence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ use crate::{
},
};

use self::api::GeometryHelpers;

use super::{
geofence_property::{Basic, FullPropertyModel},
sea_orm_active_enums::Type,
Expand All @@ -27,6 +25,7 @@ use geojson::{GeoJson, Geometry};
use sea_orm::{entity::prelude::*, UpdateResult};
use serde::{Deserialize, Serialize};
use serde_json::json;
use utils::TrimPrecision;

#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq, Serialize, Deserialize)]
#[sea_orm(table_name = "geofence")]
Expand Down Expand Up @@ -233,7 +232,7 @@ impl Model {
geometry: Some(if args.internal.is_some() || args.fullcoords.is_some() {
geometry
} else {
geometry.to_f32()
geometry.trim_precision(6)
}),
..Feature::default()
};
Expand Down
18 changes: 16 additions & 2 deletions server/model/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,20 @@ use crate::{
pub mod json;
pub mod normalize;

pub trait TrimPrecision {
fn trim_precision(self, precision: u32) -> Self;
}

impl TrimPrecision for f64 {
fn trim_precision(self, precision: u32) -> f64 {
if !self.is_finite() {
return self;
}
let precision_factor = 10u32.pow(precision) as f64;
(self * precision_factor).round() / precision_factor
}
}

pub fn sql_raw(area: &FeatureCollection) -> String {
let mut string = "".to_string();
for (i, feature) in area.into_iter().enumerate() {
Expand All @@ -27,9 +41,9 @@ pub fn sql_raw(area: &FeatureCollection) -> String {
let geo = geometry.ensure_first_last();
match geo.value {
Value::Polygon(_) | Value::MultiPolygon(_) => {
string = format!("{}{} (lon BETWEEN {} AND {}\nAND lat BETWEEN {} AND {}\nAND ST_CONTAINS(ST_GeomFromGeoJSON('{}', 2, 0), POINT(lon, lat)))",
string = format!("{}{} (\n\tlon BETWEEN {} AND {}\n\tAND lat BETWEEN {} AND {}\n\tAND ST_CONTAINS(\n\t\tST_GeomFromGeoJSON('{}', 2, 0),\n\t\tPOINT(lon, lat)\n\t)\n)",
string,
if i == 0 { "" } else { " OR" },
if i == 0 { "" } else { "\nOR" },
bbox[0], bbox[2], bbox[1], bbox[3], geo.to_string()
);
}
Expand Down

0 comments on commit 0b873d7

Please sign in to comment.