Skip to content

Commit

Permalink
Optionally use centroids for origin zones without any points. #27
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Sep 18, 2023
1 parent ab9a7a4 commit 0b50baa
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 8 deletions.
2 changes: 2 additions & 0 deletions aggregate_routes/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ pub enum ODPattern {
csv_path: String,
/// Path to a GeoJSON file containing Points with a "name" property
destinations_path: String,
/// If a zone doesn't have any matching origin points, use the zone's centroid instead.
origin_zone_centroid_fallback: bool,
},
}

Expand Down
25 changes: 20 additions & 5 deletions aggregate_routes/src/od.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::BufReader;

use anyhow::Result;
use fs_err::File;
use geo::{BoundingRect, Contains, MultiPolygon};
use geo::{BoundingRect, Centroid, Contains, MultiPolygon};
use geojson::{FeatureReader, Value};
use indicatif::HumanCount;
use nanorand::{Rng, WyRand};
Expand Down Expand Up @@ -81,8 +81,9 @@ pub fn generate(
let zones = load_zones(&zones_path)?;
timer.stop();
timer.start("Matching points to zones");
let origins_per_zone = points_per_polygon("origin", origins, &zones)?;
let destinations_per_zone = points_per_polygon("destination", destinations, &zones)?;
let origins_per_zone = points_per_polygon("origin", origins, &zones, false)?;
let destinations_per_zone =
points_per_polygon("destination", destinations, &zones, false)?;
timer.stop();

timer.start(format!("Generating requests from {csv_path}"));
Expand Down Expand Up @@ -118,6 +119,7 @@ pub fn generate(
zones_path,
csv_path,
destinations_path,
origin_zone_centroid_fallback,
} => {
let zones_path = format!("{input_directory}/{zones_path}");
let csv_path = format!("{input_directory}/{csv_path}");
Expand All @@ -130,7 +132,8 @@ pub fn generate(
let destinations = load_named_points(&destinations_path)?;
timer.stop();
timer.start("Matching points to zones");
let origins_per_zone = points_per_polygon("origin", origins, &zones)?;
let origins_per_zone =
points_per_polygon("origin", origins, &zones, origin_zone_centroid_fallback)?;
timer.stop();

timer.start(format!("Generating requests from {csv_path}"));
Expand Down Expand Up @@ -209,6 +212,7 @@ fn points_per_polygon(
name: &str,
points: Vec<(f64, f64)>,
polygons: &HashMap<String, MultiPolygon<f64>>,
use_centroids_for_empty_zones: bool,
) -> Result<HashMap<String, Vec<(f64, f64)>>> {
let tree = RTree::bulk_load(points);

Expand All @@ -231,9 +235,20 @@ fn points_per_polygon(
output.insert(key.clone(), pts_inside);
}

if !empty.is_empty() {
if !empty.is_empty() && !use_centroids_for_empty_zones {
bail!("Some zones have no matching {name} points: {:?}", empty);
}
println!(
"{} zones have no matching {name} points. Using centroid instead.",
HumanCount(empty.len() as u64)
);
for key in empty {
if let Some(centroid) = polygons[key].centroid() {
output.insert(key.clone(), vec![centroid.into()]);
} else {
bail!("{key} had no matching {name} points, and couldn't calculate its centroid");
}
}

Ok(output)
}
Expand Down
5 changes: 4 additions & 1 deletion aggregate_routes/src/timer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,10 @@ impl Timer {
impl Drop for Timer {
fn drop(&mut self) {
if let Some(current) = self.stack.last() {
println!("WARNING: Dropping timer during block {}. Probably crashing.", current.name);
println!(
"WARNING: Dropping timer during block {}. Probably crashing.",
current.name
);
return;
}

Expand Down
3 changes: 2 additions & 1 deletion examples/liverpool/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"ZoneToPoint": {
"zones_path": "zones.geojson",
"destinations_path": "destinations.geojson",
"csv_path": "od.csv"
"csv_path": "od.csv",
"origin_zone_centroid_fallback": true
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion examples/york/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"ZoneToPoint": {
"zones_path": "zones.geojson",
"destinations_path": "destinations.geojson",
"csv_path": "od.csv"
"csv_path": "od.csv",
"origin_zone_centroid_fallback": false
}
}
}
Expand Down

0 comments on commit 0b50baa

Please sign in to comment.