diff --git a/rust/Cargo.toml b/rust/Cargo.toml index c5bb370e0..08f0066a6 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -9,26 +9,27 @@ members = [ ] [workspace.dependencies] -serde = { version = "1.0.209", features = ["derive"] } -serde_json = { version = "1.0.133", features = ["preserve_order"] } +serde = { version = "1.0.219", features = ["derive"] } +serde_json = { version = "1.0.140", features = ["preserve_order"] } rayon = "1.10.0" -geo = { version = "0.29.3", features = ["use-serde"] } -geo-types = "0.7.14" -geojson = { version = "0.24.1" } +geo = { version = "0.30.0", features = ["use-serde"] } +geo-traits = "0.2.0" +geo-types = "0.7.16" +geojson = { version = "0.24.2" } rstar = "0.12.2" -thiserror = "2.0.7" -flate2 = "1.0.35" +thiserror = "2.0.12" +flate2 = "1.1.1" kdam = "0.6.2" -log = "0.4.22" -env_logger = "0.11.5" +log = "0.4.27" +env_logger = "0.11.8" csv = { version = "1.3.1" } -itertools = { version = "0.13.0" } -chrono = "0.4.39" +itertools = { version = "0.14.0" } +chrono = "0.4.40" regex = "1.11.1" wkt = { version = "0.12.0", features = ["serde"] } -wkb = "0.7.1" -config = "0.14.1" -ordered-float = { version = "4.5.0", features = ["serde"] } +wkb = "0.8.0" +config = "0.15.11" +ordered-float = { version = "5.0.0", features = ["serde"] } allocative = "0.3.4" -indoc = "2.0.5" -derive_more = { version = "1.0.0", features = ["full"] } +indoc = "2.0.6" +derive_more = { version = "2.0.1", features = ["full"] } diff --git a/rust/routee-compass-core/Cargo.toml b/rust/routee-compass-core/Cargo.toml index 913177ce7..ff93f6de6 100644 --- a/rust/routee-compass-core/Cargo.toml +++ b/rust/routee-compass-core/Cargo.toml @@ -17,10 +17,11 @@ rayon = { workspace = true } thiserror = { workspace = true } flate2 = { workspace = true } geo = { workspace = true } +geo-traits = { workspace = true } ordered-float = { workspace = true } derive_more = { workspace = true } priority-queue = "2.0.2" -lru = "0.12" +lru = "0.14.0" csv = { workspace = true } kdam = { workspace = true } log = { workspace = true } diff --git a/rust/routee-compass-core/src/util/geo/geo_io_utils.rs b/rust/routee-compass-core/src/util/geo/geo_io_utils.rs index b0bc1d936..6f2f5dcb6 100644 --- a/rust/routee-compass-core/src/util/geo/geo_io_utils.rs +++ b/rust/routee-compass-core/src/util/geo/geo_io_utils.rs @@ -1,4 +1,5 @@ use geo::{Coord, CoordsIter, LineString, Point}; +use geo_traits::to_geo::ToGeoGeometry; use itertools::Itertools; use wkb; use wkt::{ToWkt, TryFromWkt}; @@ -113,14 +114,13 @@ pub fn parse_wkt_linestring(_idx: usize, row: String) -> Result, } pub fn parse_wkb_linestring(_idx: usize, row: String) -> Result, std::io::Error> { - let mut c = row.as_bytes(); - let geom = wkb::wkb_to_geom(&mut c).map_err(|e| { - let msg = format!("failure decoding WKB string: {:?}", e); - std::io::Error::new(std::io::ErrorKind::InvalidData, msg) - })?; - match geom { + let geom = wkb::reader::read_wkb(row.as_bytes()) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e.to_string()))?; + + match geom.to_geometry() { geo::Geometry::LineString(l) => { - // somewhat hackish solution since we cannot choose f32 when parsing wkbs + // somewhat hackish solution since we cannot choose f32 when parsing wkbs and + // geo::Convert does not support f64 -> f32, for good reason of course let coords32 = l.0.into_iter() .map(|c| Coord { @@ -131,10 +131,10 @@ pub fn parse_wkb_linestring(_idx: usize, row: String) -> Result, let l32 = LineString::new(coords32); Ok(l32) } - _ => { + g => { let msg = format!( "decoded WKB expected to be linestring, found: {}", - geom.to_wkt() + g.to_wkt() ); Err(std::io::Error::new(std::io::ErrorKind::InvalidData, msg)) } diff --git a/rust/routee-compass-powertrain/Cargo.toml b/rust/routee-compass-powertrain/Cargo.toml index e797062e4..a6c3e8b1e 100644 --- a/rust/routee-compass-powertrain/Cargo.toml +++ b/rust/routee-compass-powertrain/Cargo.toml @@ -12,19 +12,19 @@ documentation = "https://docs.rs/routee-compass" [dependencies] routee-compass-core = { path = "../routee-compass-core", version = "0.9.1" } -smartcore = { version = "0.3.1", features = ["serde"] } # random forest +smartcore = { version = "0.4.0", features = ["serde"] } # random forest thiserror = { workspace = true } log = { workspace = true } geo = { workspace = true } kdam = { workspace = true } -bincode = "1.3.3" +bincode = { version = "2.0.1", features = ["serde"] } env_logger = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_repr = "0.1" serde_json = { workspace = true } ordered-float = { workspace = true } ndarray = "0.16.1" -ort = { version = "2.0.0-alpha.4", optional = true } +ort = { version = "2.0.0-rc.9", optional = true } rayon = { workspace = true } itertools = { workspace = true } ninterp = { version = "0.1.0", features = ["serde"] } diff --git a/rust/routee-compass-powertrain/src/model/prediction/smartcore/smartcore_speed_grade_model.rs b/rust/routee-compass-powertrain/src/model/prediction/smartcore/smartcore_speed_grade_model.rs index 3d963c167..37d3b4379 100644 --- a/rust/routee-compass-powertrain/src/model/prediction/smartcore/smartcore_speed_grade_model.rs +++ b/rust/routee-compass-powertrain/src/model/prediction/smartcore/smartcore_speed_grade_model.rs @@ -6,7 +6,7 @@ use routee_compass_core::model::{ use smartcore::{ ensemble::random_forest_regressor::RandomForestRegressor, linalg::basic::matrix::DenseMatrix, }; -use std::{borrow::Cow, path::Path}; +use std::{borrow::Cow, fs::File, path::Path}; pub struct SmartcoreSpeedGradeModel { rf: RandomForestRegressor, Vec>, @@ -27,7 +27,13 @@ impl PredictionModel for SmartcoreSpeedGradeModel { let mut grade_value = Cow::Owned(grade); speed_unit.convert(&mut speed_value, &self.speed_unit)?; grade_unit.convert(&mut grade_value, &self.grade_unit)?; - let x = DenseMatrix::from_2d_vec(&vec![vec![speed_value.as_f64(), grade_value.as_f64()]]); + let x = DenseMatrix::from_2d_vec(&vec![vec![speed_value.as_f64(), grade_value.as_f64()]]) + .map_err(|e| { + TraversalModelError::TraversalModelFailure(format!( + "unable to set up prediction input vector: {}", + e + )) + })?; let y = self.rf.predict(&x).map_err(|e| { TraversalModelError::TraversalModelFailure(format!( "failure running underlying Smartcore random forest energy prediction: {}", @@ -47,22 +53,23 @@ impl SmartcoreSpeedGradeModel { grade_unit: GradeUnit, energy_rate_unit: EnergyRateUnit, ) -> Result { - // Load random forest binary file - let rf_binary = std::fs::read(routee_model_path).map_err(|e| { + let mut file = File::open(routee_model_path).map_err(|e| { TraversalModelError::BuildError(format!( - "failure reading smartcore binary text file {} due to {}", - routee_model_path.as_ref().to_str().unwrap_or_default(), + "failure opening file {}: {}", + routee_model_path.as_ref().to_string_lossy(), e )) })?; let rf: RandomForestRegressor, Vec> = - bincode::deserialize(&rf_binary).map_err(|e| { - TraversalModelError::BuildError(format!( - "failure deserializing smartcore model {} due to {}", - routee_model_path.as_ref().to_str().unwrap_or_default(), - e - )) - })?; + bincode::serde::decode_from_std_read(&mut file, bincode::config::legacy()).map_err( + |e| { + TraversalModelError::BuildError(format!( + "failure deserializing smartcore model {} due to {}", + routee_model_path.as_ref().to_str().unwrap_or_default(), + e + )) + }, + )?; Ok(SmartcoreSpeedGradeModel { rf, speed_unit, diff --git a/rust/routee-compass/Cargo.toml b/rust/routee-compass/Cargo.toml index bf896a976..2e0eb4bd9 100644 --- a/rust/routee-compass/Cargo.toml +++ b/rust/routee-compass/Cargo.toml @@ -26,6 +26,7 @@ serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } csv = { workspace = true } geo = { workspace = true } +geo-traits = { workspace = true } geo-types = { workspace = true } geojson = { workspace = true } rstar = { workspace = true } @@ -36,7 +37,7 @@ kdam = { workspace = true } log = { workspace = true } rayon = { workspace = true } serde_repr = "0.1" -rand = "0.8.5" +rand = "0.9.0" chrono = { workspace = true } config = { workspace = true } clap = { version = "4.3.19", features = ["derive"] } diff --git a/rust/routee-compass/src/main.rs b/rust/routee-compass/src/main.rs index bf16ecd4e..f90b7e144 100644 --- a/rust/routee-compass/src/main.rs +++ b/rust/routee-compass/src/main.rs @@ -12,7 +12,7 @@ fn main() { match run::command_line_runner(&args, Some(builder), None) { Ok(_) => {} Err(e) => { - error!("{}", e.to_string()) + error!("{}", e) } } } diff --git a/rust/routee-compass/src/plugin/output/default/traversal/traversal_output_format.rs b/rust/routee-compass/src/plugin/output/default/traversal/traversal_output_format.rs index 49700a431..1e6ba6572 100644 --- a/rust/routee-compass/src/plugin/output/default/traversal/traversal_output_format.rs +++ b/rust/routee-compass/src/plugin/output/default/traversal/traversal_output_format.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, sync::Arc}; use super::traversal_ops as ops; use crate::plugin::output::OutputPluginError; -use geo::{CoordFloat, Geometry}; +use geo::{CoordFloat, Geometry, TryConvert}; use routee_compass_core::{ algorithm::search::{EdgeTraversal, SearchTreeBranch}, model::{map::MapModel, network::vertex_id::VertexId}, @@ -100,18 +100,19 @@ impl TraversalOutputFormat { fn geometry_to_wkb_string>( geometry: &Geometry, ) -> Result { - let bytes = wkb::geom_to_wkb(geometry).map_err(|e| { - OutputPluginError::OutputPluginFailed(format!( - "failed to generate wkb for geometry '{:?}' - {:?}", - geometry, e - )) + let mut out_bytes = vec![]; + let geom: Geometry = geometry.try_convert().map_err(|e| { + OutputPluginError::OutputPluginFailed(format!("unable to convert geometry to f64: {}", e)) })?; - let wkb_str = bytes - .iter() - .map(|b| format!("{:02X?}", b)) - .collect::>() - .join(""); - Ok(wkb_str) + wkb::writer::write_geometry(&mut out_bytes, &geom, wkb::Endianness::BigEndian).map_err( + |e| { + OutputPluginError::OutputPluginFailed(format!("failed to write geometry as WKB: {}", e)) + }, + )?; + let out_string = String::from_utf8(out_bytes).map_err(|e| { + OutputPluginError::OutputPluginFailed(format!("failed to read WKB as utf8: {}", e)) + })?; + Ok(out_string) } // #[cfg(test)]