Some preps for importing Paris: avoid crashing on some previously unseen

OSM things, and making geojson_to_osmosis handle multiple polygons in
one input file.
This commit is contained in:
Dustin Carlino 2020-11-13 16:31:22 -08:00
parent 2d928b7ecf
commit 6fe49ce0fa
4 changed files with 49 additions and 31 deletions

View File

@ -35,9 +35,9 @@ If the area is small enough, try the "export" tool on
<https://download.bbbike.org/> or <http://download.geofabrik.de/index.html>,
then clip them to a smaller area. Use [geojson.io](http://geojson.io/) or
[geoman.io](https://geoman.io/geojson-editor) to draw a boundary around the
region you want to simulate and save the geojson locally. Use
`cargo run --bin geojson_to_osmosis < boundary.geojson > clipping.poly` to
convert that geojson to the
region you want to simulate and save the GeoJSON locally. Use
`cargo run --bin geojson_to_osmosis < boundary.geojson` to convert that GeoJSON
to the
[Osmosis format](https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format)
required by osmconvert.
@ -61,11 +61,13 @@ use it as well.
[geoman.io](https://geoman.io/geojson-editor) to draw a boundary around the
region you want to simulate and save the geojson locally.
4. Use
`cargo run --bin geojson_to_osmosis < boundary.geojson > importer/config/your_city/region_name.poly`
to convert that geojson to the
4. Use `cargo run --bin geojson_to_osmosis < boundary.geojson` to convert that
geojson to the
[Osmosis format](https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format)
required by osmconvert.
required by osmconvert. This tool writes one file per feature in the input,
so you'd then
`mv boundary0.poly importer/config/your_city/region_name.poly`, repeating if
you drew multiple polygons.
5. Copy `importer/config/tel_aviv/cfg.json` to
`importer/config/your_city/cfg.json` and edit this file. See

View File

@ -215,7 +215,9 @@ pub fn extract_osm(map: &mut RawMap, opts: &Options, timer: &mut Timer) -> OsmEx
via_node_id = Some(*n);
}
}
_ => unreachable!(),
OsmID::Relation(r) => {
warn!("{} contains {} as {}", id, r, role);
}
}
}
if let Some(restriction) = rel.tags.get("restriction") {

View File

@ -2,37 +2,45 @@ use std::io::{self, Read};
use geojson::{GeoJson, Value};
/// Convert geojson boundary suitable for osmfilter and other osmosis based tools.
/// Expects the input to contain no element other than the boundary of interest.
//
/// Reads geojson text from stdin
/// Writes "poly" formatted text to stdout
use geom::LonLat;
/// Reads GeoJSON input from STDIN, extracts a polygon from every feature, and writes numbered
/// files in the https://wiki.openstreetmap.org/wiki/Osmosis/Polygon_Filter_File_Format format as
/// output.
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut buffer = String::new();
io::stdin().read_to_string(&mut buffer)?;
let geojson = buffer.parse::<GeoJson>()?;
let points = boundary_coords(&geojson)?;
println!("boundary");
println!("1");
for point in points {
println!(" {} {}", point[0], point[1]);
for (idx, points) in extract_boundaries(geojson)?.into_iter().enumerate() {
let path = format!("boundary{}.poly", idx);
LonLat::write_osmosis_polygon(&path, &points)?;
println!("Wrote {}", path);
}
println!("END");
println!("END");
Ok(())
}
fn boundary_coords(geojson: &GeoJson) -> Result<Vec<Vec<f64>>, Box<dyn std::error::Error>> {
let feature = match geojson {
GeoJson::Feature(feature) => feature,
GeoJson::FeatureCollection(feature_collection) => &feature_collection.features[0],
fn extract_boundaries(geojson: GeoJson) -> Result<Vec<Vec<LonLat>>, Box<dyn std::error::Error>> {
let features = match geojson {
GeoJson::Feature(feature) => vec![feature],
GeoJson::FeatureCollection(feature_collection) => feature_collection.features,
_ => return Err(format!("Unexpected geojson: {:?}", geojson).into()),
};
match &feature.geometry.as_ref().map(|g| &g.value) {
Some(Value::MultiPolygon(multi_polygon)) => return Ok(multi_polygon[0][0].clone()),
Some(Value::Polygon(polygon)) => return Ok(polygon[0].clone()),
_ => Err(format!("Unexpected feature: {:?}", feature).into()),
let mut polygons = Vec::new();
for mut feature in features {
let points = match feature.geometry.take().map(|g| g.value) {
Some(Value::MultiPolygon(multi_polygon)) => multi_polygon[0][0].clone(),
Some(Value::Polygon(polygon)) => polygon[0].clone(),
_ => {
return Err(format!("Unexpected feature: {:?}", feature).into());
}
};
polygons.push(
points
.into_iter()
.map(|pt| LonLat::new(pt[0], pt[1]))
.collect(),
);
}
Ok(polygons)
}

View File

@ -132,8 +132,14 @@ impl Map {
dst_i: i2,
speed_limit: Speed::ZERO,
zorder: if let Some(layer) = raw.roads[&r.id].osm_tags.get("layer") {
// Just drop .5 for now
layer.parse::<f64>().unwrap() as isize
match layer.parse::<f64>() {
// Just drop .5 for now
Ok(l) => l as isize,
Err(_) => {
warn!("Weird layer={} on {}", layer, r.id);
0
}
}
} else {
0
},