Skip to content

Commit

Permalink
When importing external scenario data, snap points outside the map bo…
Browse files Browse the repository at this point in the history
…undary to the nearest border.

Now the desire lines for cyipt/actdev#32 import without errors.
  • Loading branch information
dabreegster committed Jan 15, 2021
1 parent a7f3e99 commit 3143b57
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 17 deletions.
13 changes: 7 additions & 6 deletions book/src/trafficsim/travel_demand.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,13 @@ Run the tool:
cargo run --bin import_traffic -- --map=data/system/seattle/maps/montlake.bin --input=/path/to/input.json
```

The tool matches input positions to the nearest building or border intersection,
within 100 meters. The `departure` time is seconds since midnight. The tool will
fail if any point doesn't match to a building, or if any of the specified trips
can't be created (due to graph connectivity problems, for example). If your
requirements are different or you have any trouble using this format/tool,
please file a Github issue -- just consider this tool and format a prototype.
The tool matches input positions to the nearest building, within 100 meters. If
the point lies outside the map boundary, it's snapped to the nearest map border.
The `departure` time is seconds since midnight. The tool will fail if any point
doesn't match to a building, or if any of the specified trips can't be created
(due to graph connectivity problems, for example). If your requirements are
different or you have any trouble using this format/tool, please file a Github
issue -- just consider this tool and format a prototype.

## Modifying demand

Expand Down
16 changes: 13 additions & 3 deletions data/MANIFEST.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
"compressed_size_bytes": 2845017
},
"data/input/cambridge/desire_lines_disag.geojson": {
"checksum": "37020c1232b357b8f5753157eaf6b95f",
"uncompressed_size_bytes": 66601,
"compressed_size_bytes": 6385
"checksum": "1cb0f5fc91626099dca6582c97f49c43",
"uncompressed_size_bytes": 80600,
"compressed_size_bytes": 11174
},
"data/input/cambridge/osm/cambridgeshire-latest.osm.pbf": {
"checksum": "e7ac328f5b13c1a90da861abc84ae08d",
Expand Down Expand Up @@ -645,6 +645,16 @@
"uncompressed_size_bytes": 28191229,
"compressed_size_bytes": 9988667
},
"data/system/cambridge/scenarios/trumpington/baseline.bin": {
"checksum": "661ce8362a2854023d24822b9f2bb8fe",
"uncompressed_size_bytes": 71752,
"compressed_size_bytes": 18953
},
"data/system/cambridge/scenarios/trumpington/go_dutch.bin": {
"checksum": "b87b56638974c3ca6b88b498ac655a35",
"uncompressed_size_bytes": 71752,
"compressed_size_bytes": 18791
},
"data/system/krakow/maps/center.bin": {
"checksum": "6b39b2b5a2066603cbe5e4dc087e7071",
"uncompressed_size_bytes": 36111431,
Expand Down
2 changes: 1 addition & 1 deletion data/regen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ rm -fv data/system/seattle/maps/huge_seattle.bin data/input/raw_maps/huge_seattl
./import.sh --raw --map --scenario
./import.sh --raw --map --city=bellevue
./import.sh --raw --map --city=berlin
./import.sh --raw --map --city=cambridge # TODO Enable --scenario
./import.sh --raw --map --city=cambridge --scenario
./import.sh --raw --map --city=krakow
./import.sh --raw --map --city=leeds
./import.sh --raw --map --city=london
Expand Down
30 changes: 23 additions & 7 deletions sim/src/make/external.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,39 @@ pub enum ExternalTripEndpoint {
}

impl ExternalPerson {
/// Import external scenario data. The main difference between `ExternalPerson` and
/// `PersonSpec` is a way to specify endpoints by a `LonLat`. This is snapped to the nearest
/// building. If the point is outside of the map boundary, it's snapped to the nearest border
/// (by Euclidean distance -- the network outside the given map isn't known). Failure happens
/// if a point is within the map, but not close enough to any buildings.
pub fn import(map: &Map, input: Vec<ExternalPerson>) -> Result<Vec<PersonSpec>> {
let mut closest: FindClosest<TripEndpoint> = FindClosest::new(map.get_bounds());
for b in map.all_buildings() {
closest.add(TripEndpoint::Bldg(b.id), b.polygon.points());
}
let mut borders = Vec::new();
for i in map.all_intersections() {
closest.add(TripEndpoint::Border(i.id), i.polygon.points());
if i.is_border() {
borders.push((TripEndpoint::Border(i.id), i.polygon.center()));
}
}

let lookup_pt = |endpt| match endpt {
ExternalTripEndpoint::TripEndpoint(endpt) => Ok(endpt),
ExternalTripEndpoint::Position(gps) => {
match closest.closest_pt(gps.to_pt(map.get_gps_bounds()), Distance::meters(100.0)) {
Some((x, _)) => Ok(x),
None => Err(anyhow!(
"No building or border intersection within 100m of {}",
gps
)),
let pt = gps.to_pt(map.get_gps_bounds());
if map.get_boundary_polygon().contains_pt(pt) {
match closest.closest_pt(pt, Distance::meters(100.0)) {
Some((x, _)) => Ok(x),
None => Err(anyhow!("No building within 100m of {}", gps)),
}
} else {
Ok(borders
.iter()
.min_by_key(|(_, border)| border.fast_dist(pt))
.unwrap()
.0
.clone())
}
}
};
Expand Down

0 comments on commit 3143b57

Please sign in to comment.