make more multipolygons work by dealing with closed ways

This commit is contained in:
Dustin Carlino 2019-02-11 12:50:56 -08:00
parent 72e823c2c6
commit ea3170a9a9

View File

@ -108,15 +108,18 @@ pub fn osm_to_raw_roads(
}
}
if ok {
if let Some(polygon) = glue_multipolygon(pts_per_way) {
let polygons = glue_multipolygon(pts_per_way);
if polygons.is_empty() {
println!("Relation {} failed to glue multipolygon", rel.id);
} else {
for points in polygons {
areas.push(raw_data::Area {
area_type: at,
osm_id: rel.id,
points: polygon,
points,
osm_tags: tags.clone(),
});
} else {
println!("Relation {} failed to glue multipolygon", rel.id);
}
}
}
}
@ -191,10 +194,23 @@ fn get_area_type(tags: &BTreeMap<String, String>) -> Option<AreaType> {
None
}
fn glue_multipolygon(mut pts_per_way: Vec<Vec<LonLat>>) -> Option<Vec<LonLat>> {
if pts_per_way.is_empty() {
return None;
// The result could be more than one disjoint polygon.
fn glue_multipolygon(mut pts_per_way: Vec<Vec<LonLat>>) -> Vec<Vec<LonLat>> {
// First deal with all of the closed loops.
let mut polygons: Vec<Vec<LonLat>> = Vec::new();
pts_per_way.retain(|pts| {
if pts[0] == *pts.last().unwrap() {
polygons.push(pts.to_vec());
false
} else {
true
}
});
if pts_per_way.is_empty() {
return polygons;
}
// The main polygon
let mut result = pts_per_way.pop().unwrap();
let mut reversed = false;
while !pts_per_way.is_empty() {
@ -211,7 +227,8 @@ fn glue_multipolygon(mut pts_per_way: Vec<Vec<LonLat>>) -> Option<Vec<LonLat>> {
result.extend(append);
} else {
if reversed {
return None;
// Totally filter the thing out, since something clearly broke.
return Vec::new();
} else {
reversed = true;
result.reverse();
@ -224,5 +241,6 @@ fn glue_multipolygon(mut pts_per_way: Vec<Vec<LonLat>>) -> Option<Vec<LonLat>> {
if result[0] != *result.last().unwrap() {
result.push(result[0]);
}
Some(result)
polygons.push(result);
polygons
}