7

I would like a convert a relation (e.g. https://openstreetmap.org/relation/2851613) to a list of coordinates that can be displayed on a map, potentially using geojson. I ported over this converter https://wiki.openstreetmap.org/wiki/Relations/Relations_to_GPX (the converted code is at https://github.com/e-mission/e-mission-eval-public-data/blob/master/spec_creation/autofill_eval_spec.py#L71) and it works iff the relations are sane.

However, many relations are malformed. Although the relation spec https://wiki.openstreetmap.org/wiki/Relation says that the members have to be ordered, this relation for the route of bus #52 (https://www.openstreetmap.org/relation/8094017) has the following way order

Way West El Camino Real (516422275) as forward
Way Castro Street (417101895) as forward
Way North El Monte Avenue (52869637) as forward 

which is clearly incorrect since since the 52 goes from Castro to El Monte via El Camino. So if I use the algorithm above, I end up with a map like so

enter image description here

At the same time, OSM displays the route without any zigzags, so it is clearly able to order the relation members correctly even if they are not ordered originally.

In response to @neogeomat, I looked at the nodes displayed by overpass and the nodes displayed by the reconstruction algorithm above for a correctly created relation, and it looks like overpass returns fewer nodes than the algorithm above. comparing overpass with reconstructed path directly from nodes

Does anybody know how OSM displays relations, or have a pointer to an algorithm that deals gracefully with malformed relations?

2
  • Did you try github.com/tyrasd/osmtogeojson or one of the alternatives at GeoJSON? Not sure which one supports sorting relation members, though.
    – scai
    Jul 23, 2019 at 7:40
  • @scai I haven't looked at osmtogeojson before - thank you for the pointer. Since it is used by the overpass turbo project, it does look super promising. Unfortunately, I came up with a workaround so I don't have time to explore this right now. Would you like to submit this as an answer so that I can accept it after I try it out and you can get the points?
    – Shankari
    Jul 31, 2019 at 5:00

4 Answers 4

1

You can try osmtogeojson (used by overpass turbo) or one of the alternatives listed at the GeoJSON OSM wiki page. Unfortunately I have no experience with any of them and I'm unsure which one supports sorting of relation members.

1

Your underlying assumption that the members of a (route-)relation are ordered is not correct. The quote in the API doc simply means that the order in which you provided the member elements will be maintained.

This should not be a surprise as the API does not and cannot know the semantics (for example in which way it should be ordered) of a specific relation type.

A superficial check of the code of osmtogeojson would indicate that it indeed does properly create geometries for route relations (and for multipolygons) by connecting adjacent ways.

Note there are some cases in which automatic ordering will not produce the correct results, but as long as you are only rendering and not traversing the ways that doesn't really matter.

3
  • Welcome to gis stackexchange! My assumption is based on the spec that I linked to in the original question. wiki.openstreetmap.org/wiki/Relation, which says "and also an ordered list of one or more nodes, ways and/or relations as members". And I am using the relations to generate a sequence of traversal points, so the ordering does matter to me.
    – Shankari
    Aug 1, 2019 at 13:54
  • As said that simply means that the OSM data model and the API guarantees that the ordering you supplied the members in is maintained, but it doesn't mean that the API orders relation members. As there are further no input checks, as there is no way for the API to know how the members should be ordered, the onus is on the data consumer / the tools consuming OSM data to order the members in an appropriate fashion for their needs. Aug 2, 2019 at 14:07
  • I am a data consumer for OSM - I am writing a tool that uses the relation to generate a sequence of traversal points. And while I still think that the spec specifies that the nodes should be ordered, but they clearly are not in some cases. My question was for pointers on how to deal with the inconsistency programatically, since the algorithm on the wiki does not work in all cases.
    – Shankari
    Aug 6, 2019 at 21:56
1

OSM does not display relations. relations are not geographical objects and cannot be dispalyed as is, so only the members are displayed. to convert relation to nodes and use you can use overpass-api. e.g. here and here

5
  • This is an interesting solution that almost works but not quite. Note that you can also retrieve the members of a relation directly from OSM using the osmapi - e.g. openstreetmap.org/relation/9709380 I use that already to retrieve the members - my problem is that the retrieved ways are not ordered. So when I use the algorithm from the wiki wiki.openstreetmap.org/wiki/Relations/Relations_to_GPX to iterate through them and aggregate the nodes, I get a lot of zigzags.
    – Shankari
    Aug 11, 2019 at 15:02
  • I was excited to see that overpass returned more nodes than just the stops/platforms, but when I compared the overpass nodes to the nodes returned by the wiki algorithm, I found that overpass was actually missing some nodes. I've updated the question to reflect this since I cannot attach screenshots to comments
    – Shankari
    Aug 11, 2019 at 15:16
  • We won't be able to tell unless you post the exact Overpass query you used. Screenshots don't really help to figure out the difference.
    – mmd
    Aug 11, 2019 at 15:31
  • So this is close, and might be a reasonable solution for a developer who does not need too much density, but I'm still holding out for something better...
    – Shankari
    Aug 11, 2019 at 15:37
  • Both queries already return all data. What you see is the result of overpass turbo rendering this data. In particular, overpass turbo won't display a node without tags that is part of a way - in which case you will see the way. That doesn't mean however that the data is incomplete.
    – mmd
    Aug 11, 2019 at 16:00
1

I tested your example (https://overpass-turbo.eu/s/UA9) with osm2geojson. And result looks good.

Example code:

import requests
import urllib
import codecs
import json
from osm2geojson import json2geojson

OVERPASS = "https://overpass-api.de/api/interpreter/"


def overpass_call(query):
    encoded = urllib.parse.quote(query.encode('utf-8'), safe='~()*!.\'')
    r = requests.post(OVERPASS,
                      data=f"data={encoded}",
                      headers={'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'})
    if not r.status_code is 200:
        raise requests.exceptions.HTTPError('Overpass server respond with status '+str(r.status_code))
    return r.text


def save_data(data, geom_file):
    json_data = json.dumps(data, indent=2)
    f = codecs.open(geom_file, 'w')
    f.write(json_data)
    f.close()


data = overpass_call(f"""
    [out:json];
    rel(8094017);
    out geom;
""")

geojson_data = json2geojson(data)
save_data(geojson_data, 'road.geojson')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.