Skip to content

Commit

Permalink
Update i_overlay to match geo.
Browse files Browse the repository at this point in the history
Note: this "minor" version bump of i_overlay introduces breaking
changes. The i_overlay maintainer intentionally does not follow semver,
so I've pegged the versions more conservatively, ensuring we only update
explicitly.
  • Loading branch information
michaelkirk authored and dabreegster committed Jan 14, 2025
1 parent f3b8c91 commit dc42679
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 23 deletions.
5 changes: 4 additions & 1 deletion backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ contour = "0.12.0"
fast_paths = "1.0.0"
geo = "0.29.1"
geojson = { git = "https://github.com/georust/geojson", features = ["geo-types"] }
i_overlay = { version = "1.7.4", default-features = false }
# Note: i_overlay doesn't follow semver, and only guarantees non-breaking across patch versions.
# https://github.com/iShape-Rust/iOverlay?tab=readme-ov-file#versioning-policy
# So we pin to a minor version.
i_overlay = { version = ">=1.9.4,<1.10.0", default-features = false }
i_float = "1.3.1"
log = "0.4.20"
osm-reader = { git = "https://github.com/a-b-street/osm-reader" }
Expand Down
35 changes: 13 additions & 22 deletions backend/src/auto_boundaries.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
use geo::{Area, Coord, Intersects, LineString, Polygon};
use geojson::FeatureCollection;
use i_float::f64_point::F64Point;
use i_overlay::core::fill_rule::FillRule;
use i_overlay::f64::string::F64StringOverlay;
use i_overlay::string::rule::StringRule;
use i_overlay::float::slice::FloatSlice;

use crate::MapModel;

Expand Down Expand Up @@ -80,42 +78,35 @@ impl MapModel {
}

// TODO Revisit some of this; conversions are now in geo

fn split_polygon(polygon: Polygon, linestrings: Vec<LineString>) -> Vec<Polygon> {
let mut overlay = F64StringOverlay::new();
overlay.add_shape_path(polygon.exterior().coords().map(to_pt).collect());
for ls in linestrings {
overlay.add_string_lines(
ls.lines()
.map(|l| [to_pt(&l.start), to_pt(&l.end)])
.collect(),
);
}
let mut shape = to_i_overlay_contour(polygon.exterior());

let graph = overlay.into_graph(FillRule::NonZero);
let shapes = graph.extract_shapes(StringRule::Slice);
// geo Polygon's are explicitly closed LineStrings, but i_overlay Polygon's are not.
shape.pop();

let splitters: Vec<_> = linestrings.iter().map(to_i_overlay_contour).collect();
let shapes = shape.slice_by(&splitters, FillRule::NonZero);
shapes.into_iter().map(to_geo_polygon).collect()
}

fn to_pt(pt: &Coord) -> F64Point {
F64Point::new(pt.x, pt.y)
}

fn to_geo_polygon(rings: Vec<Vec<F64Point>>) -> Polygon {
fn to_geo_polygon(rings: Vec<Vec<[f64; 2]>>) -> Polygon {
let mut interiors: Vec<LineString> = rings.into_iter().map(to_geo_linestring).collect();
let exterior = interiors.remove(0);
Polygon::new(exterior, interiors)
}

fn to_geo_linestring(pts: Vec<F64Point>) -> LineString {
fn to_geo_linestring(pts: Vec<[f64; 2]>) -> LineString {
LineString(
pts.into_iter()
.map(|pt| Coord { x: pt.x, y: pt.y })
.map(|pt| Coord { x: pt[0], y: pt[1] })
.collect(),
)
}

fn to_i_overlay_contour(line_string: &LineString) -> Vec<[f64; 2]> {
line_string.coords().map(|c| [c.x, c.y]).collect()
}

fn boundary_touches_any(polygon: &Polygon, linestrings: &Vec<LineString>) -> bool {
// TODO At least consider an rtree to prune!
linestrings
Expand Down

0 comments on commit dc42679

Please sign in to comment.