mirror of
https://github.com/a-b-street/abstreet.git
synced 2024-11-24 09:24:26 +03:00
Optionally just create a circle of some radius around the 'center' of a city. #326
This commit is contained in:
parent
0c0104d1e2
commit
004ca95842
@ -9,12 +9,17 @@
|
|||||||
//! directory!
|
//! directory!
|
||||||
|
|
||||||
use abstutil::{CmdArgs, Timer};
|
use abstutil::{CmdArgs, Timer};
|
||||||
use geom::{GPSBounds, LonLat, Polygon};
|
use geom::{Circle, Distance, GPSBounds, LonLat, Polygon};
|
||||||
|
use map_model::osm::OsmID;
|
||||||
use std::process::Command;
|
use std::process::Command;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut args = CmdArgs::new();
|
let mut args = CmdArgs::new();
|
||||||
let input = args.required_free();
|
let input = args.required_free();
|
||||||
|
let radius_around_label: Option<Distance> = args
|
||||||
|
.optional_parse("--radius_around_label_miles", |s| {
|
||||||
|
s.parse::<f64>().map(|x| Distance::miles(x))
|
||||||
|
});
|
||||||
args.done();
|
args.done();
|
||||||
let mut timer = Timer::new(format!("extract cities from {}", input));
|
let mut timer = Timer::new(format!("extract cities from {}", input));
|
||||||
|
|
||||||
@ -33,19 +38,40 @@ fn main() {
|
|||||||
|
|
||||||
println!("Found city relation for {}: {}", name, id);
|
println!("Found city relation for {}: {}", name, id);
|
||||||
|
|
||||||
let polygons = convert_osm::osm_geom::glue_multipolygon(
|
let clip = if let Some(radius) = radius_around_label {
|
||||||
*id,
|
// Just draw a circle around the relation's admin_centre or label
|
||||||
convert_osm::osm_geom::get_multipolygon_members(*id, rel, &doc),
|
let mut center = None;
|
||||||
None,
|
for (role, id) in &rel.members {
|
||||||
&mut timer,
|
if role == "admin_centre" || role == "label" {
|
||||||
);
|
if let OsmID::Node(n) = id {
|
||||||
println!(
|
center = Some(doc.nodes[n].pt);
|
||||||
"Extracted {} from {}, using the convex hull of {} polygons",
|
break;
|
||||||
name,
|
}
|
||||||
id,
|
}
|
||||||
polygons.len(),
|
}
|
||||||
);
|
if let Some(pt) = center {
|
||||||
let clip = Polygon::convex_hull(polygons);
|
Circle::new(pt, radius).to_polygon()
|
||||||
|
} else {
|
||||||
|
println!("... but it has no admin_centre or label member");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Glue together the outer members of the relation
|
||||||
|
let polygons = convert_osm::osm_geom::glue_multipolygon(
|
||||||
|
*id,
|
||||||
|
convert_osm::osm_geom::get_multipolygon_members(*id, rel, &doc),
|
||||||
|
None,
|
||||||
|
&mut timer,
|
||||||
|
);
|
||||||
|
// Simplify the result (which often has thousands of points)
|
||||||
|
println!(
|
||||||
|
"Extracted {} from {}, using the convex hull of {} polygons",
|
||||||
|
name,
|
||||||
|
id,
|
||||||
|
polygons.len(),
|
||||||
|
);
|
||||||
|
Polygon::convex_hull(polygons)
|
||||||
|
};
|
||||||
|
|
||||||
let clipping_polygon = format!("{}.poly", name);
|
let clipping_polygon = format!("{}.poly", name);
|
||||||
LonLat::write_osmosis_polygon(
|
LonLat::write_osmosis_polygon(
|
||||||
|
@ -38,11 +38,11 @@ impl Circle {
|
|||||||
|
|
||||||
/// Renders the circle as a polygon.
|
/// Renders the circle as a polygon.
|
||||||
pub fn to_polygon(&self) -> Polygon {
|
pub fn to_polygon(&self) -> Polygon {
|
||||||
self.to_partial_polygon(1.0)
|
self.to_ring().to_polygon()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders some percent, between [0, 1], of the circle as a polygon. The polygon starts from 0
|
/// Renders some percent, between [0, 1], of the circle as a polygon. The polygon starts from 0
|
||||||
/// degrees.
|
/// degrees. Be warned the resulting polygon doesn't have a ring as its boundary!
|
||||||
pub fn to_partial_polygon(&self, percent_full: f64) -> Polygon {
|
pub fn to_partial_polygon(&self, percent_full: f64) -> Polygon {
|
||||||
let mut pts = vec![self.center];
|
let mut pts = vec![self.center];
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
|
Loading…
Reference in New Issue
Block a user