Skip to content

Commit

Permalink
Refactor places writing GeoJSON (working around georust/geojson#170)
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreegster committed Jul 15, 2022
1 parent 1b216cc commit 7e2667b
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 92 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ anyhow = "1.0.38"
csv = "1.1.4"
fs-err = "2.6.0"
geo = "0.22.0"
geojson = { version = "0.22.2", features = ["geo-types"] }
geom = { path = "../geom" }
importer = { path = "../importer" }
log = "0.4.14"
Expand Down
26 changes: 9 additions & 17 deletions cli/src/generate_houses.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use std::collections::HashSet;

use aabb_quadtree::QuadTree;
use geojson::{Feature, FeatureCollection, GeoJson};
use rand::{Rng, SeedableRng};
use rand_xorshift::XorShiftRng;

Expand All @@ -23,22 +22,15 @@ pub fn run(map: String, num_required: usize, rng_seed: u64, output: String) {
);
}

let mut features = Vec::new();
for poly in houses {
features.push(Feature {
bbox: None,
geometry: Some(poly.to_geojson(Some(map.get_gps_bounds()))),
id: None,
properties: None,
foreign_members: None,
});
}
let geojson = GeoJson::from(FeatureCollection {
bbox: None,
features,
foreign_members: None,
});
abstio::write_json(output, &geojson);
abstio::write_json(
output,
&geom::geometries_to_geojson(
houses
.into_iter()
.map(|poly| poly.to_geojson(Some(map.get_gps_bounds())))
.collect(),
),
);
}

fn generate_buildings_on_empty_residential_roads(
Expand Down
1 change: 1 addition & 0 deletions geom/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ instant = "0.1.7"
ordered-float = { version = "2.4.0", features=["serde"] }
polylabel = "2.4.0"
serde = "1.0.123"
serde_json = "1.0.61"

[dev-dependencies]
rand = "0.8.3"
Expand Down
44 changes: 44 additions & 0 deletions geom/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,50 @@ impl Default for CornerRadii {
}
}

/// Create a GeoJson with one feature per geometry, with the specified properties.
// TODO Rethink after https://github.com/georust/geojson/issues/170
pub fn geometries_with_properties_to_geojson(
input: Vec<(
geojson::Geometry,
serde_json::Map<String, serde_json::Value>,
)>,
) -> geojson::GeoJson {
let mut features = Vec::new();
for (geom, properties) in input {
features.push(geojson::Feature {
bbox: None,
geometry: Some(geom),
id: None,
properties: Some(properties),
foreign_members: None,
});
}
geojson::GeoJson::from(geojson::FeatureCollection {
bbox: None,
features,
foreign_members: None,
})
}

/// Create a GeoJson with one feature per geometry, and no properties.
pub fn geometries_to_geojson(input: Vec<geojson::Geometry>) -> geojson::GeoJson {
let mut features = Vec::new();
for geom in input {
features.push(geojson::Feature {
bbox: None,
geometry: Some(geom),
id: None,
properties: None,
foreign_members: None,
});
}
geojson::GeoJson::from(geojson::FeatureCollection {
bbox: None,
features,
foreign_members: None,
})
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
81 changes: 25 additions & 56 deletions headless/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ impl LoadSim {
}

fn export_geometry(map: &Map, i: IntersectionID) -> geojson::GeoJson {
use geojson::{Feature, FeatureCollection, GeoJson};
let mut pairs = Vec::new();

let i = map.get_i(i);
// Translate all geometry to center around the intersection, with distances in meters.
Expand All @@ -533,84 +533,53 @@ fn export_geometry(map: &Map, i: IntersectionID) -> geojson::GeoJson {
let mut props = serde_json::Map::new();
props.insert("type".to_string(), "intersection".into());
props.insert("id".to_string(), i.orig_id.to_string().into());
let mut features = vec![Feature {
bbox: None,
geometry: Some(
i.polygon
.translate(-center.x(), -center.y())
.into_ring()
.to_geojson(None),
),
id: None,
properties: Some(props),
foreign_members: None,
}];
pairs.push((
i.polygon
.translate(-center.x(), -center.y())
.into_ring()
.to_geojson(None),
props,
));

// Each connected road
for r in &i.roads {
let r = map.get_r(*r);
let mut props = serde_json::Map::new();
props.insert("type".to_string(), "road".into());
props.insert("id".to_string(), r.orig_id.osm_way_id.to_string().into());
features.push(Feature {
bbox: None,
geometry: Some(
r.center_pts
.to_thick_ring(r.get_width())
.translate(-center.x(), -center.y())
.to_geojson(None),
),
id: None,
properties: Some(props),
foreign_members: None,
});
pairs.push((
r.center_pts
.to_thick_ring(r.get_width())
.translate(-center.x(), -center.y())
.to_geojson(None),
props,
));
}

GeoJson::from(FeatureCollection {
bbox: None,
features,
foreign_members: None,
})
geom::geometries_with_properties_to_geojson(pairs)
}

fn export_all_geometry(map: &Map) -> geojson::GeoJson {
use geojson::{Feature, FeatureCollection, GeoJson};

let mut features = Vec::new();
let mut pairs = Vec::new();
let gps_bounds = Some(map.get_gps_bounds());

for i in map.all_intersections() {
let mut props = serde_json::Map::new();
props.insert("type".to_string(), "intersection".into());
props.insert("id".to_string(), i.orig_id.to_string().into());
features.push(Feature {
bbox: None,
geometry: Some(i.polygon.clone().into_ring().to_geojson(gps_bounds)),
id: None,
properties: Some(props),
foreign_members: None,
});
pairs.push((i.polygon.clone().into_ring().to_geojson(gps_bounds), props));
}
for r in map.all_roads() {
let mut props = serde_json::Map::new();
props.insert("type".to_string(), "road".into());
props.insert("id".to_string(), r.orig_id.osm_way_id.to_string().into());
features.push(Feature {
bbox: None,
geometry: Some(
r.center_pts
.to_thick_ring(r.get_width())
.to_geojson(gps_bounds),
),
id: None,
properties: Some(props),
foreign_members: None,
});
pairs.push((
r.center_pts
.to_thick_ring(r.get_width())
.to_geojson(gps_bounds),
props,
));
}

GeoJson::from(FeatureCollection {
bbox: None,
features,
foreign_members: None,
})
geom::geometries_with_properties_to_geojson(pairs)
}
21 changes: 4 additions & 17 deletions map_gui/src/tools/city_picker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -526,8 +526,6 @@ fn chose_city<A: AppLike + 'static>(

#[cfg(not(target_arch = "wasm32"))]
fn reimport_city<A: AppLike + 'static>(ctx: &mut EventCtx, app: &A) -> Transition<A> {
use geojson::{Feature, FeatureCollection, GeoJson};

let name = format!("updated_{}", app.map().get_name().as_filename());

let mut args = vec![
Expand All @@ -543,21 +541,10 @@ fn reimport_city<A: AppLike + 'static>(ctx: &mut EventCtx, app: &A) -> Transitio
// Write the current map boundary
abstio::write_json(
"boundary.json".to_string(),
&GeoJson::from(FeatureCollection {
bbox: None,
foreign_members: None,
features: vec![Feature {
bbox: None,
id: None,
properties: None,
foreign_members: None,
geometry: Some(
app.map()
.get_boundary_polygon()
.to_geojson(Some(app.map().get_gps_bounds())),
),
}],
}),
&geom::geometries_to_geojson(vec![app
.map()
.get_boundary_polygon()
.to_geojson(Some(app.map().get_gps_bounds()))]),
);

return Transition::Push(crate::tools::RunCommand::new_state(
Expand Down

0 comments on commit 7e2667b

Please sign in to comment.