From ec5a2979f055fc5e8f1c9faaa7a8eb9886749ec5 Mon Sep 17 00:00:00 2001 From: Jan Tschada Date: Tue, 24 Sep 2024 17:29:47 +0200 Subject: [PATCH] #3 Implemented a visitor pattern - we want to specify the filter criteria multiple times --- .../src/platformshell/src/main.rs | 17 ++++--- .../src/platformshell/src/utils.rs | 49 +++++++------------ 2 files changed, 30 insertions(+), 36 deletions(-) diff --git a/spatial-data-science/src/platformshell/src/main.rs b/spatial-data-science/src/platformshell/src/main.rs index 7c178c7..31754ab 100644 --- a/spatial-data-science/src/platformshell/src/main.rs +++ b/spatial-data-science/src/platformshell/src/main.rs @@ -1,11 +1,7 @@ use geo::Point; use platformshell::LocationServicesError; -use reqwest::Url; -use serde_esri::features::FeatureSet; -use serde_json::json; -use serde_json::Value; +use serde_esri::features::Feature; use std::env; -use std::io::Read; mod utils; @@ -64,8 +60,17 @@ fn main() -> Result<(), Box> { // Query the feature service let urban_hri_url = env::var("URBAN_HEAT_RISK_INDEX_FEATURE_SERVICE_URL")?; + + // Define the filtering logic + let filter_fn = |feature: &Feature<2>| { + if let Some(geometry) = &feature.geometry { + geometry.clone().as_polygon().is_some() + } else { + false + } + }; - match utils::query_heat_risk_index(urban_hri_url, location) { + match utils::query_heat_risk_index(urban_hri_url, location, filter_fn) { Ok(hri_featureset) => { let json = serde_json::to_string_pretty(&hri_featureset)?; println!("{}", json); diff --git a/spatial-data-science/src/platformshell/src/utils.rs b/spatial-data-science/src/platformshell/src/utils.rs index de275d7..f8ca335 100644 --- a/spatial-data-science/src/platformshell/src/utils.rs +++ b/spatial-data-science/src/platformshell/src/utils.rs @@ -1,14 +1,13 @@ use geo::Point; use platformshell::LocationServicesError; use reqwest::Url; -use serde_esri::features::FeatureSet; -use serde_json::json; +use serde_esri::features::{Feature, FeatureSet}; use serde_json::Value; use std::io::Read; -pub fn query_heat_risk_index(urban_hri_url: String, location: Point) -> Result, Box> { +pub fn query_heat_risk_index(urban_hri_url: String, location: Point, filter_fn: F) -> Result, Box> where F: Fn(&Feature<2>) -> bool, { let location_str = format!("{}, {}", location.x(), location.y()); let location_wkid_str = "4326"; @@ -46,34 +45,24 @@ pub fn query_heat_risk_index(urban_hri_url: String, location: Point) -> Result = serde_json::from_str(&body)?; - let mut filtered_features = Vec::new(); - // Extract and print the JSON representation of the features - for hri_feature in &hri_featureset.features { - if let Some(hri_attributes) = &hri_feature.attributes { - for (key, value) in hri_attributes.iter() { - println!("{}: {}", key, value); - } - } - if let Some(hri_geometry) = &hri_feature.geometry { - if let Some(polygon) = hri_geometry.clone().as_polygon() { - let json_geometry = json!(polygon); - filtered_features.push(hri_feature.clone()); - println!("{}", serde_json::to_string_pretty(&json_geometry)?); - } else { - //eprintln!("Geometry is not a polygon."); - return Err(Box::new(LocationServicesError { code:9999, message:"Geometry is not a polygon.".to_string() })); - } - } - } + // Filter features using the provided closure + let filtered_features: Vec> = hri_featureset + .features + .into_iter() + .filter(|feature| filter_fn(feature)) + .collect(); - Ok(FeatureSet { - objectIdFieldName: hri_featureset.objectIdFieldName.clone(), - globalIdFieldName: hri_featureset.globalIdFieldName.clone(), - displayFieldName: hri_featureset.displayFieldName.clone(), - spatialReference: hri_featureset.spatialReference.clone(), - geometryType: hri_featureset.geometryType.clone(), + // Create a new FeatureSet with the filtered features + let filtered_featureset = FeatureSet { + objectIdFieldName: hri_featureset.objectIdFieldName, + globalIdFieldName: hri_featureset.globalIdFieldName, + displayFieldName: hri_featureset.displayFieldName, + spatialReference: hri_featureset.spatialReference, + geometryType: hri_featureset.geometryType, features: filtered_features, - fields: hri_featureset.fields.clone(), - }) + fields: hri_featureset.fields, + }; + + Ok(filtered_featureset) }