Skip to content

Commit

Permalink
Start storing config in files, not passing in an awkward string on th…
Browse files Browse the repository at this point in the history
…e CLI. Still keep JSON
  • Loading branch information
dabreegster committed Aug 11, 2023
1 parent bbed56a commit 003cdf4
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 19 deletions.
4 changes: 0 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
*.swp
target/
node_modules/

# Particular places
bedfordshire/
cornwall/
43 changes: 32 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,31 @@ ogr2ogr -f GeoJSON -dialect sqlite -sql 'SELECT ST_Centroid(geometry) FROM multi

### Run the pipeline

Then run the pipeline, routing from every single building to the nearest school. Or to see a much more clear pattern in the output, use `FromEveryOriginToOneDestination` to go from every building to one arbitrary school.
Then create a file `$AREA/config.json` file containing:

```
{
"directory": "$AREA",
"requests": {
"Generate": {
"pattern": "FromEveryOriginToNearestDestination"
}
},
"routing": {
"FastPaths": {
"cost": "Distance"
}
},
"filter": {}
}
```

This would route from every single building to the nearest school. Or to see a much more clear pattern in the output, change the pattern to `FromEveryOriginToOneDestination` to go from every building to one arbitrary school.

Run the pipeline on this config:

```shell
cargo run --release -- '{"directory":"'"$AREA"'","requests":{"Generate":{"pattern":"FromEveryOriginToNearestDestination"}},"routing":{"FastPaths":{"cost":"Distance"}},"filter":{}}'
cargo run --release $AREA/config.json
```

It'll be slow the first time you run (compiling the tool, parsing OSM data, and building a contraction hierarchy). Subsequent runs will be faster.
Expand Down Expand Up @@ -67,13 +88,13 @@ The purpose of this tool is to generate route networks **quickly** for areas up

The pipeline needs a list of routing requests to run -- just a huge list of start/end coordinates. These should **not** be centroids of a large zone or anything like that.

Built-in options currently include:
Built-in options for `"requests"` currently include:

- `"requests":{"Generate":{"pattern":"FromEveryOriginToOneDestination"}}`
- `{ "Generate": { "pattern": "FromEveryOriginToOneDestination" } }`
- One trip for every $AREA/origins.geojson to the first point in $AREA/destinations.geojson
- `"requests":{"Generate":{"pattern":"FromEveryOriginToNearestDestination"}}`
- `{"Generate" : { "pattern": "FromEveryOriginToNearestDestination" } }`
- One trip for every $AREA/origins.geojson to the nearest (as the crow flies) point in $AREA/destinations.geojson
- `"requests":{"Odjitter":{"path":"file.geojson"}}`
- `{"Odjitter": { "path": "file.geojson" } }`
- Use LineStrings from a GeoJSON file. You can use [odjitter](https://github.com/dabreegster/odjitter) to generate a number of trips between zones, picking specific weighted points from each zone.
- Note this option is **not** recommended for performance. For an interesting amount of requests, the overhead of reading/writing this file full of requests and storing it in memory doesn't work.

Expand All @@ -84,12 +105,12 @@ Problems to solve include:

### Routing

The pipeline currently has two methods for calculating a route:
The pipeline currently has two methods for calculating a route, specified by `"routing"`:

- The built-in `"routing":"FastPaths"` option, which currently makes a number of very bad assumptions:
- The built-in `"FastPaths"` option, which currently makes a number of very bad assumptions:
- Every edge can be crossed either direction
- When `"cost":"Distance", edge cost is just distance -- equivalent to calculating the most direct route, ignoring LTS
- `"cost":"AvoidMainRoads"` uses hardcoded multipliers for main roads
- When `"cost": "Distance", edge cost is just distance -- equivalent to calculating the most direct route, ignoring LTS
- `"cost": "AvoidMainRoads"` uses hardcoded multipliers for main roads
- No penalty for elevation gain
- No handling for turn restrictions, penalties for crossing intersections, etc
- Calling a local instance of [OSRM](https://project-osrm.org)
Expand Down Expand Up @@ -121,7 +142,7 @@ curl 'http://localhost:5000/route/v1/driving/-0.24684906005859372,51.42955782907

After we calculate a route, we may want to exclude it because it's too long or hilly to reasonably expect people to cycle, even if the route was made very safe.

To exclude all routes over 16km: pass this instead of the empty JSON for `"filter":{"max_distance_meters":16000}`
To exclude all routes over 16km: `"filter": { "max_distance_meters": 16000 }`

### Visualization

Expand Down
14 changes: 10 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@ use indicatif::HumanCount;
#[derive(Parser)]
#[clap(about, version, author)]
struct Args {
/// A JSON string representing an InputConfig
config: String,
/// The path to a JSON file representing an InputConfig
config_path: String,
}

#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
let config: input::InputConfig = match serde_json::from_str(&args.config) {
let config_json = fs_err::read_to_string(&args.config_path)?;
let config: input::InputConfig = match serde_json::from_str(&config_json) {
Ok(config) => config,
Err(err) => panic!("--config is invalid: {err}"),
Err(err) => panic!("{} is invalid: {err}", args.config_path),
};
println!(
"Using config from {}:\n{}\n",
args.config_path,
serde_json::to_string_pretty(&config)?
);

let mut start = Instant::now();
let network = {
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod lts;
pub mod route_cost;
pub mod uptake;

// TODO osm2network initial filtering of valid roads, based on route_cost?

0 comments on commit 003cdf4

Please sign in to comment.