mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-12-24 15:02:59 +03:00
Add an API call to export intersection geometry to geojson, for experimental streetmix3d integration.
To get an example: > cargo run --bin headless -- --port=1234 > curl http://localhost:1234/map/get-intersection-geometry?id=291
This commit is contained in:
parent
3ed7e73aa8
commit
f187cf4bd8
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1278,6 +1278,7 @@ name = "headless"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"abstutil",
|
||||
"geojson",
|
||||
"geom",
|
||||
"hyper",
|
||||
"lazy_static",
|
||||
@ -1286,6 +1287,7 @@ dependencies = [
|
||||
"rand",
|
||||
"rand_xorshift",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sim",
|
||||
"tokio",
|
||||
"url",
|
||||
|
@ -90,6 +90,10 @@ are missing, etc. A summary of the commands available so far:
|
||||
`--edits=name_of_edits`.
|
||||
- **GET /map/get-edit-road-command?id=123**: Returns an object that can be
|
||||
modified and then added to map edits.
|
||||
- **GET /map/get-intersection-geometry?id=123**: Returns a GeoJSON object with
|
||||
one feature for the intersection and a feature for all connecting roads. The
|
||||
polygon coordinates are measured in meters, with the origin centered at the
|
||||
intersection's center.
|
||||
|
||||
## Working with the map model
|
||||
|
||||
|
@ -75,6 +75,17 @@ impl PolyLine {
|
||||
PolyLine::new(pts)
|
||||
}
|
||||
|
||||
/// Like make_polygons, but make sure the points actually form a ring.
|
||||
pub fn to_thick_ring(&self, width: Distance) -> Ring {
|
||||
let mut side1 = self.shift_with_sharp_angles(width / 2.0, MITER_THRESHOLD);
|
||||
let mut side2 = self.shift_with_sharp_angles(-width / 2.0, MITER_THRESHOLD);
|
||||
side2.reverse();
|
||||
side1.extend(side2);
|
||||
side1.push(side1[0]);
|
||||
side1.dedup();
|
||||
Ring::must_new(side1)
|
||||
}
|
||||
|
||||
pub fn to_thick_boundary(
|
||||
&self,
|
||||
self_width: Distance,
|
||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
abstutil = { path = "../abstutil" }
|
||||
geojson = "0.19.0"
|
||||
geom = { path = "../geom" }
|
||||
hyper = "0.13.8"
|
||||
lazy_static = "1.4.0"
|
||||
@ -14,6 +15,7 @@ map_model = { path = "../map_model" }
|
||||
rand = "0.7.0"
|
||||
rand_xorshift = "0.2.0"
|
||||
serde = "1.0.116"
|
||||
serde_json = "1.0.57"
|
||||
sim = { path = "../sim" }
|
||||
tokio = { version = "0.2.22", features = ["full"] }
|
||||
url = "2.1.1"
|
||||
|
@ -325,6 +325,10 @@ fn handle_command(
|
||||
&map.edit_road_cmd(r, |_| {}).to_perma(map),
|
||||
))
|
||||
}
|
||||
"/map/get-intersection-geometry" => {
|
||||
let i = IntersectionID(params["id"].parse::<usize>()?);
|
||||
Ok(abstutil::to_json(&export_geometry(map, i)))
|
||||
}
|
||||
_ => Err("Unknown command".into()),
|
||||
}
|
||||
}
|
||||
@ -415,3 +419,57 @@ impl LoadSim {
|
||||
(map, sim)
|
||||
}
|
||||
}
|
||||
|
||||
fn export_geometry(map: &Map, i: IntersectionID) -> geojson::GeoJson {
|
||||
use geojson::{Feature, FeatureCollection, GeoJson, Geometry, Value};
|
||||
|
||||
let i = map.get_i(i);
|
||||
// Translate all geometry to center around the intersection, with distances in meters.
|
||||
let center = i.polygon.center();
|
||||
|
||||
// The intersection itself
|
||||
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(Geometry::new(Value::Polygon(vec![i
|
||||
.polygon
|
||||
.translate(-center.x(), -center.y())
|
||||
.points()
|
||||
.iter()
|
||||
.map(|pt| vec![pt.x(), pt.y()])
|
||||
.collect()]))),
|
||||
id: None,
|
||||
properties: Some(props),
|
||||
foreign_members: None,
|
||||
}];
|
||||
|
||||
// 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(Geometry::new(Value::Polygon(vec![r
|
||||
.center_pts
|
||||
.to_thick_ring(2.0 * r.get_half_width(map))
|
||||
.into_points()
|
||||
.into_iter()
|
||||
.map(|pt| pt.offset(-center.x(), -center.y()))
|
||||
.map(|pt| vec![pt.x(), pt.y()])
|
||||
.collect()]))),
|
||||
id: None,
|
||||
properties: Some(props),
|
||||
foreign_members: None,
|
||||
});
|
||||
}
|
||||
|
||||
GeoJson::from(FeatureCollection {
|
||||
bbox: None,
|
||||
features,
|
||||
foreign_members: None,
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user