Skip to content

Commit

Permalink
#3 Implemented a visitor pattern
Browse files Browse the repository at this point in the history
- we want to specify the filter criteria multiple times
  • Loading branch information
esride-jts committed Sep 24, 2024
1 parent 86e871b commit ec5a297
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 36 deletions.
17 changes: 11 additions & 6 deletions spatial-data-science/src/platformshell/src/main.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -64,8 +60,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

// 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);
Expand Down
49 changes: 19 additions & 30 deletions spatial-data-science/src/platformshell/src/utils.rs
Original file line number Diff line number Diff line change
@@ -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<FeatureSet<2>, Box<dyn std::error::Error>> {
pub fn query_heat_risk_index<F>(urban_hri_url: String, location: Point, filter_fn: F) -> Result<FeatureSet<2>, Box<dyn std::error::Error>> where F: Fn(&Feature<2>) -> bool, {
let location_str = format!("{}, {}", location.x(), location.y());
let location_wkid_str = "4326";

Expand Down Expand Up @@ -46,34 +45,24 @@ pub fn query_heat_risk_index(urban_hri_url: String, location: Point) -> Result<F

// Parse into a 2D FeatureSet
let hri_featureset: FeatureSet<2> = 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<Feature<2>> = 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)
}

0 comments on commit ec5a297

Please sign in to comment.