5

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

{
    red,
    green,
    blue,
    yellow
}

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.

Problem

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

(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 Oct 25 '14 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 Oct 26 '14 at 8:57
  • I edited my original question to answer to your comment. – Misch Oct 26 '14 at 16:12
  • I added some further explanations to my answer :) – scai Oct 26 '14 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 Oct 26 '14 at 20:34
3

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

http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm

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.)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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