Optionally just create a circle of some radius around the 'center' of a city. #326

This commit is contained in:
Dustin Carlino 2020-10-26 16:57:50 -07:00
parent 0c0104d1e2
commit 004ca95842
2 changed files with 42 additions and 16 deletions

View File

@ -9,12 +9,17 @@
//! directory!
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;
fn main() {
let mut args = CmdArgs::new();
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();
let mut timer = Timer::new(format!("extract cities from {}", input));
@ -33,19 +38,40 @@ fn main() {
println!("Found city relation for {}: {}", name, id);
let polygons = convert_osm::osm_geom::glue_multipolygon(
*id,
convert_osm::osm_geom::get_multipolygon_members(*id, rel, &doc),
None,
&mut timer,
);
println!(
"Extracted {} from {}, using the convex hull of {} polygons",
name,
id,
polygons.len(),
);
let clip = Polygon::convex_hull(polygons);
let clip = if let Some(radius) = radius_around_label {
// Just draw a circle around the relation's admin_centre or label
let mut center = None;
for (role, id) in &rel.members {
if role == "admin_centre" || role == "label" {
if let OsmID::Node(n) = id {
center = Some(doc.nodes[n].pt);
break;
}
}
}
if let Some(pt) = center {
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);
LonLat::write_osmosis_polygon(

View File

@ -38,11 +38,11 @@ impl Circle {
/// Renders the circle as a 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
/// 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 {
let mut pts = vec![self.center];
let mut indices = Vec::new();