tyrasd / osmtogeojson

convert osm to geojson
http://tyrasd.github.io/osmtogeojson/
MIT License
683 stars 113 forks source link

broken multipolygon -> some members are ignored #73

Open tyrasd opened 7 years ago

tyrasd commented 7 years ago

It looks like in the case of a broken multipolygon (e.g. missing roles), not all geometries are rendered. Example: http://overpass-turbo.eu/s/nNI (note the missing inner way of the broken multipolygon is present in the output of the Overpass API, but not in the generated GeoJSON).

dtoddenroth commented 2 years ago

I stumbled across a few similar constellations in current landuse features where osmtogeojson appears to miss out on some inner polygons in relations where surrounding polygons lack explicit 'outer' roles, namely 11834983, 6258488, 6337271, 7303647, 12420590 and 12420591. It seems that inner areas do not show up in outputs because without explicit outer polygons, osmtogeojson reverts to outputting LineString features according to line 716 if (outer_count == 0).

For example (tested with version 3.0.0-beta.4):

wget -q -O - http://overpass-api.de/api/interpreter?data=%5Bout%3Ajson%5D%3B%0Arelation%2811834983%29%3B%20%0Aout%20geom%3B | osmtogeojson -v | json-query features[0].geometry.type
Multipolygon relation/11834983 member way/_fullGeom866975554 ignored because it has an invalid role: ""
Multipolygon relation relation/11834983 ignored because it has no outer ways
"LineString"

For the other instances, outputs look similar. One could debate whether this is even bug, because when explicit roles are seen as mandatory, these inputs seem faulty. Maybe osmtogeojson could still be a bit more accommodating in such cases, since these role-less features where most likely intended as outer polygons, i.e. that mappers wanted them to define perimeters from which 'inner' areas should be subtracted.

A simple fix might involve interpreting outer as a sort of default role, e.g. by counting non-inner members as outer by changing line 701 into if (rels[i].members[j].role != "inner") or into if ((rels[i].members[j].role == "outer") || (rels[i].members[j].role == "")), but I have no idea whether this would break other important assumptions. Another approach might involve imputing missing roles from geometries, although this would probably be more difficult to implement...

osmtogeojson is awesome! Keep up the great work!