From c78b5b9a28fc42ad99af59599c247d9ceff62364 Mon Sep 17 00:00:00 2001 From: Dustin Carlino Date: Sat, 9 Nov 2024 11:26:21 +0000 Subject: [PATCH] Upgrade geo and related packages. No behavioral changes. I was hoping this would solve #54, but the new iOverlay code isn't used for polygon-contains-linestring. WIP: Tests fail with this, need to investigate later. --- backend/Cargo.lock | 196 ++++++++++++----------------------- backend/Cargo.toml | 6 +- backend/src/cells.rs | 2 +- backend/src/geo_helpers.rs | 5 +- backend/src/map_model.rs | 11 +- backend/src/neighbourhood.rs | 16 +-- backend/src/render_cells.rs | 15 +-- backend/src/route_snapper.rs | 3 +- backend/src/shortcuts.rs | 6 +- 9 files changed, 99 insertions(+), 161 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index ed72b33..e8e9847 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -50,15 +50,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-polyfill" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ff7eb3f316534d83a8a2c3d1674ace8a5a71198eba31e2e2b597833f699b28" -dependencies = [ - "critical-section", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -75,12 +66,12 @@ dependencies = [ "console_log", "contour", "fast_paths", - "geo 0.27.0 (git+https://github.com/dabreegster/geo?branch=boolops_and_linesplit)", + "geo", "geojson", "log", "osm-reader", "route-snapper-graph", - "rstar 0.12.0", + "rstar", "serde", "serde-wasm-bindgen", "serde_json", @@ -170,12 +161,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "critical-section" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7059fff8937831a9ae6f0fe4d658ffabf58f2ca96aa9dec1c889f936f705f216" - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -276,51 +261,19 @@ checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" [[package]] name = "geo" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4841b40fdbccd4b7042bd6195e4de91da54af34c50632e371bcbfcdfb558b873" -dependencies = [ - "earcutr", - "float_next_after", - "geo-types", - "geographiclib-rs", - "log", - "num-traits", - "robust", - "rstar 0.11.0", - "spade", -] - -[[package]] -name = "geo" -version = "0.27.0" -source = "git+https://github.com/dabreegster/geo?branch=boolops_and_linesplit#74b7c687ec8a7f9d47db3b02a729a1de76d5758b" -dependencies = [ - "earcutr", - "float_next_after", - "geo-types", - "geographiclib-rs", - "log", - "num-traits", - "robust", - "rstar 0.11.0", - "spade", -] - -[[package]] -name = "geo" -version = "0.28.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f811f663912a69249fa620dcd2a005db7254529da2d8a0b23942e81f47084501" +checksum = "8798f09c0fb3625cf216569408e151a1884c3a028a0b533b7c223ae8f695c89a" dependencies = [ "earcutr", "float_next_after", "geo-types", "geographiclib-rs", + "i_overlay", "log", "num-traits", "robust", - "rstar 0.12.0", + "rstar", "spade", ] @@ -332,8 +285,7 @@ checksum = "9ff16065e5720f376fbced200a5ae0f47ace85fd70b7e54269790281353b6d61" dependencies = [ "approx", "num-traits", - "rstar 0.11.0", - "rstar 0.12.0", + "rstar", "serde", ] @@ -358,15 +310,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "hash32" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67" -dependencies = [ - "byteorder", -] - [[package]] name = "hash32" version = "0.3.1" @@ -392,26 +335,13 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "heapless" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db04bc24a18b9ea980628ecf00e6c0264f3c1426dac36c00cb49b6fbad8b0743" -dependencies = [ - "atomic-polyfill", - "hash32 0.2.1", - "rustc_version", - "spin", - "stable_deref_trait", -] - [[package]] name = "heapless" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" dependencies = [ - "hash32 0.3.1", + "hash32", "stable_deref_trait", ] @@ -424,6 +354,50 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "i_float" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fe043aae28ce70bd2f78b2f5f82a3654d63607c82594da4dabb8b6cb81f2b2" +dependencies = [ + "serde", +] + +[[package]] +name = "i_key_sort" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "347c253b4748a1a28baf94c9ce133b6b166f08573157e05afe718812bc599fcd" + +[[package]] +name = "i_overlay" +version = "1.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d5024b4346ff4699e2db65674bbcb3a7cb8c5a820e9745ec777a7cb2bb5f42" +dependencies = [ + "i_float", + "i_key_sort", + "i_shape", + "i_tree", + "rayon", +] + +[[package]] +name = "i_shape" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b44852d57a991c7dedaf76c55bc44f677f547ff899a430d29e13efd6133d7d8" +dependencies = [ + "i_float", + "serde", +] + +[[package]] +name = "i_tree" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155181bc97d770181cf9477da51218a19ee92a8e5be642e796661aee2b601139" + [[package]] name = "indexmap" version = "1.9.3" @@ -492,16 +466,6 @@ version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" -[[package]] -name = "lock_api" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.20" @@ -728,9 +692,9 @@ checksum = "cbf4a6aa5f6d6888f39e980649f3ad6b666acdce1d78e95b8a2cb076e687ae30" [[package]] name = "route-snapper-graph" version = "0.1.0" -source = "git+https://github.com/dabreegster/route_snapper#aeb83caee46a2dc46984faad3fe55def3b984cf7" +source = "git+https://github.com/dabreegster/route_snapper#0834519b09152168ee4908dcd630d54605aa759b" dependencies = [ - "geo 0.27.0 (registry+https://github.com/rust-lang/crates.io-index)", + "geo", "serde", ] @@ -740,24 +704,13 @@ version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cd14fd5e3b777a7422cca79358c57a8f6e3a703d9ac187448d0daf220c2407f" -[[package]] -name = "rstar" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73111312eb7a2287d229f06c00ff35b51ddee180f017ab6dec1f69d62ac098d6" -dependencies = [ - "heapless 0.7.16", - "num-traits", - "smallvec", -] - [[package]] name = "rstar" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "133315eb94c7b1e8d0cb097e5a710d850263372fd028fff18969de708afc7008" dependencies = [ - "heapless 0.8.0", + "heapless", "num-traits", "smallvec", ] @@ -768,15 +721,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc_version" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" -dependencies = [ - "semver", -] - [[package]] name = "rustix" version = "0.38.26" @@ -802,12 +746,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "semver" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" - [[package]] name = "serde" version = "1.0.193" @@ -861,15 +799,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "spade" -version = "2.4.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d3bf265ec2d5dd1ddf87863252123447c550491adba2c70c574173a95cd8ba" +checksum = "93f5ef1f863aca7d1d7dda7ccfc36a0a4279bd6d3c375176e5e0712e25cb4889" dependencies = [ "hashbrown 0.14.3", "num-traits", @@ -877,15 +815,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -dependencies = [ - "lock_api", -] - [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -945,12 +874,15 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "utils" version = "0.1.0" -source = "git+https://github.com/a-b-street/utils#bfb2c435944ce825616d53240e1e3adcee94f047" +source = "git+https://github.com/a-b-street/utils#b4addd630b398009381b1e9da8f04faa06d300c3" dependencies = [ "anyhow", "fast_paths", - "geo 0.28.0", + "geo", + "geo-types", + "log", "osm-reader", + "serde", ] [[package]] diff --git a/backend/Cargo.toml b/backend/Cargo.toml index 0187a93..f09c70d 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -13,16 +13,16 @@ console_error_panic_hook = "0.1.6" console_log = "1.0.0" contour = "0.12.0" fast_paths = "1.0.0" -geo = { git = "https://github.com/dabreegster/geo", branch = "boolops_and_linesplit" } +geo = "0.29.1" geojson = { git = "https://github.com/georust/geojson", features = ["geo-types"] } log = "0.4.20" osm-reader = { git = "https://github.com/a-b-street/osm-reader" } route-snapper-graph = { git = "https://github.com/dabreegster/route_snapper" } +rstar = "0.12.0" serde = "1.0.188" serde_json = "1.0.105" serde-wasm-bindgen = "0.6.0" -rstar = "0.12.0" -utils = { git = "https://github.com/a-b-street/utils" } +utils = { git = "https://github.com/a-b-street/utils", features = ["serde"] } wasm-bindgen = "0.2.87" web-sys = { version = "0.3.64", features = ["console"] } web-time = "1.0.0" diff --git a/backend/src/cells.rs b/backend/src/cells.rs index 00a40ff..83e4e3b 100644 --- a/backend/src/cells.rs +++ b/backend/src/cells.rs @@ -177,6 +177,6 @@ fn floodfill(map: &MapModel, start: RoadID, neighbourhood: &Neighbourhood) -> Ce } } -fn is_private(road: &Road) -> bool { +fn is_private(_road: &Road) -> bool { false } diff --git a/backend/src/geo_helpers.rs b/backend/src/geo_helpers.rs index 956eaf1..5d86991 100644 --- a/backend/src/geo_helpers.rs +++ b/backend/src/geo_helpers.rs @@ -1,7 +1,8 @@ use geo::{ - Contains, Intersects, LineInterpolatePoint, LineIntersection, LineLocatePoint, LineSplit, - LineString, Polygon, + Contains, Intersects, LineInterpolatePoint, LineIntersection, LineLocatePoint, LineString, + Polygon, }; +use utils::LineSplit; /// Looks for the first place ls2 crosses ls1. Returns the percent_along ls1 of that point. pub fn linestring_intersection(ls1: &LineString, ls2: &LineString) -> Option { diff --git a/backend/src/map_model.rs b/backend/src/map_model.rs index daa01f7..afbc5c6 100644 --- a/backend/src/map_model.rs +++ b/backend/src/map_model.rs @@ -3,7 +3,7 @@ use std::fmt; use anyhow::Result; use geo::{ - Closest, ClosestPoint, Coord, EuclideanLength, Line, LineInterpolatePoint, LineLocatePoint, + Closest, ClosestPoint, Coord, Euclidean, Length, Line, LineInterpolatePoint, LineLocatePoint, LineString, Point, Polygon, }; use geojson::{Feature, FeatureCollection, GeoJson, Geometry}; @@ -73,6 +73,7 @@ pub struct Road { pub struct Intersection { pub id: IntersectionID, + #[allow(unused)] pub node: osm_reader::NodeID, pub point: Point, pub roads: Vec, @@ -146,7 +147,7 @@ impl MapModel { Closest::SinglePoint(pt) => Some(pt), Closest::Indeterminate => None, } { - let score = Line::new(click_pt, hit_pt.into()).euclidean_length(); + let score = Line::new(click_pt, hit_pt.into()).length::(); let percent_along = road.linestring.line_locate_point(&hit_pt).unwrap(); Some(((score * 100.0) as usize, road.id, percent_along)) } else { @@ -167,12 +168,12 @@ impl MapModel { r.linestring.points().next().unwrap(), linestring.points().next().unwrap(), ) - .euclidean_length(); + .length::(); let diff2 = Line::new( r.linestring.points().last().unwrap(), linestring.points().last().unwrap(), ) - .euclidean_length(); + .length::(); ((diff1 + diff2) * 100.0) as usize }) .unwrap() @@ -491,7 +492,7 @@ impl MapModel { impl Road { pub fn length(&self) -> f64 { - self.linestring.euclidean_length() + self.linestring.length::() } pub fn to_gj(&self, mercator: &Mercator) -> Feature { diff --git a/backend/src/neighbourhood.rs b/backend/src/neighbourhood.rs index 9bba7e7..617eb9e 100644 --- a/backend/src/neighbourhood.rs +++ b/backend/src/neighbourhood.rs @@ -2,8 +2,8 @@ use std::collections::{BTreeMap, BTreeSet}; use anyhow::Result; use geo::{ - Contains, EuclideanDistance, EuclideanLength, Intersects, LineInterpolatePoint, - LineLocatePoint, LineString, Point, Polygon, + Contains, Distance, Euclidean, Intersects, Length, LineInterpolatePoint, LineLocatePoint, + LineString, Point, Polygon, }; use geojson::{Feature, FeatureCollection, Geometry}; use web_time::Instant; @@ -54,8 +54,8 @@ impl Neighbourhood { let mut border_intersections = BTreeSet::new(); for i in &map.intersections { // Check distance to the polygon's linestring, rather than the polygon itself. Points - // contained within a polygon and eight on the linestring both count as 0. - let dist = i.point.euclidean_distance(boundary_polygon.exterior()); + // contained within a polygon and right on the linestring both count as 0. + let dist = Euclidean::distance(&i.point, boundary_polygon.exterior()); // Allow a small tolerance if dist < 0.1 { border_intersections.insert(i.id); @@ -187,12 +187,12 @@ fn line_in_polygon(linestring: &LineString, polygon: &Polygon) -> LineInPolygon // Multiple segments generally don't happen, but might right on a boundary let mut sum = 0.0; for clipped in clip_linestring_to_polygon(linestring, polygon) { - sum += clipped.euclidean_length(); + sum += clipped.length::(); } // How much of the clipped linestring is inside the boundary? If it's nearly 1, then this // road is interior. Round to make diffs less noisy. - let percent = (sum / linestring.euclidean_length() * 10e3).round() / 10e3; + let percent = (sum / linestring.length::() * 10e3).round() / 10e3; if percent <= 0.99 { return LineInPolygon::Crosses { percent }; } @@ -208,8 +208,8 @@ fn double_check_line_in_polygon(linestring: &LineString, polygon: &Polygon) -> L let polygon_pt1 = closest_point(polygon.exterior(), ls_pt1); let polygon_pt2 = closest_point(polygon.exterior(), ls_pt2); - if ls_pt1.euclidean_distance(&polygon_pt1) < 0.1 - && ls_pt2.euclidean_distance(&polygon_pt2) < 0.1 + if Euclidean::distance(ls_pt1, polygon_pt1) < 0.1 + && Euclidean::distance(ls_pt2, polygon_pt2) < 0.1 { return LineInPolygon::Crosses { percent: 1.0 }; } diff --git a/backend/src/render_cells.rs b/backend/src/render_cells.rs index baa3a8e..5804416 100644 --- a/backend/src/render_cells.rs +++ b/backend/src/render_cells.rs @@ -1,6 +1,6 @@ use std::collections::{HashSet, VecDeque}; -use geo::{BooleanOps, BoundingRect, Coord, Densify, LineString, MultiPolygon, Rect}; +use geo::{BooleanOps, BoundingRect, Coord, Densify, Euclidean, LineString, MultiPolygon, Rect}; use utils::Grid; use crate::{Cell, MapModel, Neighbourhood}; @@ -46,7 +46,7 @@ impl RenderCells { slice_linestring(&road.linestring, interval.start, interval.end) { // Walk along the center line - for pt in slice.densify(RESOLUTION_M / 2.0).0 { + for pt in slice.densify::(RESOLUTION_M / 2.0).0 { let grid_idx = grid.idx( ((pt.x - bounds.min().x) / RESOLUTION_M) as usize, ((pt.y - bounds.min().y) / RESOLUTION_M) as usize, @@ -80,7 +80,11 @@ impl RenderCells { // the area. The grid covers the rectangular bounds of the polygon. Rather than make an // enum with 3 cases, just assign a new index to mean "boundary." let boundary_marker = cells.len(); - for pt in boundary_polygon.exterior().densify(RESOLUTION_M / 2.0).0 { + for pt in boundary_polygon + .exterior() + .densify::(RESOLUTION_M / 2.0) + .0 + { // TODO Refactor helpers to transform between map-space and the grid tiles. Possibly // Grid should know about this. let grid_idx = grid.idx( @@ -305,8 +309,7 @@ fn color_cells(num_cells: usize, adjacencies: HashSet<(usize, usize)>) -> Vec Option { +// TODO Use linesplit +fn slice_linestring(linestring: &LineString, _start: f64, _end: f64) -> Option { Some(linestring.clone()) } diff --git a/backend/src/route_snapper.rs b/backend/src/route_snapper.rs index c03a80d..49538c3 100644 --- a/backend/src/route_snapper.rs +++ b/backend/src/route_snapper.rs @@ -1,7 +1,8 @@ use std::collections::BTreeMap; -use geo::{Coord, LineIntersection, LineLocatePoint, LineSplit, Point}; +use geo::{Coord, LineIntersection, LineLocatePoint, Point}; use route_snapper_graph::{Edge, NodeID, RouteSnapperMap}; +use utils::LineSplit; use crate::{MapModel, RoadID}; diff --git a/backend/src/shortcuts.rs b/backend/src/shortcuts.rs index a116ceb..c6b792b 100644 --- a/backend/src/shortcuts.rs +++ b/backend/src/shortcuts.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use fast_paths::InputGraph; -use geo::{EuclideanLength, LineString}; +use geo::{Euclidean, Length, LineString}; use geojson::{Feature, Geometry}; use utils::NodeMap; @@ -79,7 +79,7 @@ impl Shortcuts { map.get_i(*start).point.into(), map.get_i(*end).point.into(), ) { - Some(linestring) => linestring.euclidean_length(), + Some(linestring) => linestring.length::(), None => { warn!("Found a shortcut from {start} to {end}, but not a route using the whole map"); shortcut_length @@ -123,7 +123,7 @@ impl Path { } let linestring = LineString::new(pts); - let length = linestring.euclidean_length(); + let length = linestring.length::(); let mut f = Feature::from(Geometry::from(&map.mercator.to_wgs84(&linestring))); f.set_property("directness", self.directness); f.set_property("length_meters", length);