Skip to content

Commit

Permalink
#3 utility function querying hri features
Browse files Browse the repository at this point in the history
  • Loading branch information
esride-jts committed Sep 24, 2024
1 parent 59f0f79 commit 86e871b
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 51 deletions.
62 changes: 11 additions & 51 deletions spatial-data-science/src/platformshell/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ use serde_json::Value;
use std::env;
use std::io::Read;

mod utils;



#[cfg(test)]
Expand Down Expand Up @@ -59,62 +61,20 @@ mod tests {
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create a Point with latitude and longitude
let location = Point::new(7.116004, 50.719847);
let location_str = format!("{}, {}", location.x(), location.y());
let location_wkid_str = "4326";

// Query the feature service
let urban_hri_url = env::var("URBAN_HEAT_RISK_INDEX_FEATURE_SERVICE_URL")?;
let out_fields = "HRI, TEMP";
let query_url = Url::parse_with_params(
&(urban_hri_url + "/query"),
&[
("where", "1=1"),
("geometryType", "esriGeometryPoint"),
("geometry", &location_str),
("inSR", &location_wkid_str),
("outFields", &out_fields),
("returnGeometry", "true"),
("f", "json"),
],
)?;
let mut response = reqwest::blocking::get(query_url)?;
let mut body = String::new();

// Read the request into a String
response.read_to_string(&mut body)?;

// Parse the response body as JSON
let json_body: Value = serde_json::from_str(&body)?;

// Check if the JSON contains an error
if let Some(error) = json_body.get("error") {
let code = error.get("code").and_then(Value::as_i64).unwrap_or(0) as i32;
let message = error.get("message").and_then(Value::as_str).unwrap_or("Unknown error").to_string();
//eprintln!("{}", message);
return Err(Box::new(LocationServicesError { code, message }));
}
//println!("{:?}", body);

// Parse into a 2D FeatureSet
let hri_featureset: FeatureSet<2> = serde_json::from_str(&body)?;

// 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);
}

match utils::query_heat_risk_index(urban_hri_url, location) {
Ok(hri_featureset) => {
let json = serde_json::to_string_pretty(&hri_featureset)?;
println!("{}", json);
}
if let Some(hri_geometry) = hri_feature.geometry {
if let Some(polygon) = hri_geometry.as_polygon() {
let json_geometry = json!(polygon);
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() }));
}
Err(e) => {
eprintln!("Error querying heat risk index: {}", e);
return Err(Box::new(LocationServicesError { code:9999, message:"Error querying heat risk index!".to_string() }));
}
}

Ok(())
}
}
79 changes: 79 additions & 0 deletions spatial-data-science/src/platformshell/src/utils.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use geo::Point;
use platformshell::LocationServicesError;
use reqwest::Url;
use serde_esri::features::FeatureSet;
use serde_json::json;
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>> {
let location_str = format!("{}, {}", location.x(), location.y());
let location_wkid_str = "4326";

// Query the feature service
let out_fields = "HRI, TEMP";
let query_url = Url::parse_with_params(
&(urban_hri_url + "/query"),
&[
("where", "1=1"),
("geometryType", "esriGeometryPoint"),
("geometry", &location_str),
("inSR", &location_wkid_str),
("outFields", &out_fields),
("returnGeometry", "true"),
("f", "json"),
],
)?;
let mut response = reqwest::blocking::get(query_url)?;
let mut body = String::new();

// Read the request into a String
response.read_to_string(&mut body)?;

// Parse the response body as JSON
let json_body: Value = serde_json::from_str(&body)?;

// Check if the JSON contains an error
if let Some(error) = json_body.get("error") {
let code = error.get("code").and_then(Value::as_i64).unwrap_or(0) as i32;
let message = error.get("message").and_then(Value::as_str).unwrap_or("Unknown error").to_string();
//eprintln!("{}", message);
return Err(Box::new(LocationServicesError { code, message }));
}
//println!("{:?}", body);

// 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() }));
}
}
}

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(),
features: filtered_features,
fields: hri_featureset.fields.clone(),
})
}

0 comments on commit 86e871b

Please sign in to comment.