I use the Overpass API to get the boundary of an OSM relation. I then use the result to display the boundary on a leaflet map. My problem is however, that the nodes are not in the "right order".

Leaflet of course expects to get a polygon in which the nodes are in the order in which they should be connected afterwards, like in the following picture:

How it should be

The Overpass API however just gives me the nodes in any order, like for example this:

Nodes in the wrong order

This problem results in the following output:

enter image description here

Is there some way I can get Overpass to give me the nodes in the "right order"? I guess that this is the only alternative, as I guess leaflet isn't able to reorder the nodes on its own (it can't really know which order is right).

It has to be possible to get the data in an automatic way. I only need to generate this data once (or maybe once a year) but for over 100 different areas.

Answer to scai's comment:

After closer inspection of the data, not taking the nodes in the order they appear in the result but taking them in the order they appear in the ways seams like the right approach. However, it is still a little more complicated.

There are two problems: First, who guarantees that the ways belonging to a relation are in the right order (all the boundaries I just queried seemed to be ordered the right way, but I have already found a lot of relations where the ways were not ordered in the right way).

Example: Let's assume I get the following data, and the relation consists of


Problem 1

Secondly, the ways don't all point in the same direction. This problem does definitely happen.

In the example below, the blue way points in the opposite direction than the other ways. Taking the nodes in the order they appear in the ways won't give me the right result.


A possible solution to all this would be the following algorithm: Start with the first way, add all nodes to an array, then search for a new way whose first or last node has the same id as the last added node, repeat until arriving at the first node ever added. But isn't there a better way to do this?

3 Answers 3


(I edited my answer for your follow-up questions)

You have to use the order in which the node IDs are referenced by the corresponding <way> element in the XML file. In contrast, the order in which the <nodes> elements appear in the XML file is completely irrelevant.

Furthermore, as you already discovered, a relation can contain multiple separate ways forming a single polygon. Here, the relation doesn't necessarily has to reference the ways in the correct order. Consequently the correct order of the ways has to be determined by looking at the first and last node of the way. Consecutive ways will share the same last and first node.

For a neat sorting algorithm you can take a look at the source code of JOSM.

Alternatively you might take a look at overpass turbo which provides a GeoJSON output which Leaflet should be able to handle.

  • 1
    My processing algorithm is probably the problem: I iterate through all elements and ignore everything except nodes. I then take these nodes and add them as a polygon in leaflet. How is the right way to do this?
    – Misch
    Commented Oct 25, 2014 at 17:30
  • Store all the nodes and their attributes while iterating. You can ignore the node's tags if you are only interested in the geometry, but remember their IDs and coordinates. When encountering the way you are interested in (there might be more than one way depending on your Overpass query) then iterate over the way's nodes. The order in which the nodes are referenced by the way is the correct order you need for the polygon geometry. The way only references the node IDs, so you have to lookup the IDs in your previously stored node attributes in order to obtain the corresponding coordinates.
    – scai
    Commented Oct 26, 2014 at 8:57
  • I edited my original question to answer to your comment.
    – Misch
    Commented Oct 26, 2014 at 16:12
  • I added some further explanations to my answer :)
    – scai
    Commented Oct 26, 2014 at 17:55
  • 1
    There seems to be no such documented feature, unfortunately. Overpass API features a JSON export but as far as I know it's not GeoJSON. But you can take a look at the osmtogeojson project. I think this is the same lib as used by overpass turbo, stored in the osmtogeojson lib directory of the overpass-ide project.
    – scai
    Commented Oct 26, 2014 at 20:34

I am not sure if this is helpful, but a suggestion for an algoritm to process OSM multipolygon into into proper GIS multipolygons is given here


Helpful reading regarding boundaries, enclaves and exclaves: http://wiki.openstreetmap.org/wiki/Relation:boundary

Especially the last example is important: Relation id 2 is defined using just one simple list of four ways which create two areas!

(Unable to add this as comment due to missing reputation. Sorry.)


In case this is still a topic, I took the following approach to call for ways, and then transform the nodes into the lat lon coordinates in the proper order, trying to avoid the mess that apparently the API gets into when calling a list of nodes in bulk:

Let's say the query has this structure, where the list of nodes are coming from a particular way previously requested in another call to the API.

ids = [0001,0002,0003, etc.] #way with nodes in a certain order.
query = f"""[out:json][timeout:900][maxsize:1073741824];node(id:{ids});out;"""

The code calls the query, and retrieves the nodes' info, but it does not do it in the same order.

    api= overpy.Overpass() #calling the API
    nodes = api2.query(query).nodes #Retrieve the nodes (id, lon and lat)

Then, we create a dictionary where the nodes' id becomes the key, and the lat lon the values.

    nodes_dict = {item.id:[float(str(item.lon)),float(str(item.lat))] for item in nodes}

And finally, with some list comprehension, we keep the order from the original list in the query

    ordered_nodes = [[id_] + nodes_dict[id_] for id_ in ids]

Hope it helps!

Your Answer

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

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