Hey all,

What I want do is extract a piece of the roadsystem out of an osm file and put it in a csv. This should contain the lat lon for every node belong to that roadsystem, the node id, and the name of the road to where the node belongs.

I did some searching on the net and found that I can use osmfilter and osmconvert to get the job done. I managed to get the nodeId, the lat and the lon into a csv using the next statements:

./osmfilter test.o5m --keep="highway=motorway =motorway_link =primary" --drop-ways --drop-relations > highways.osm

to filter the osm file and

./osmconvert highways.osm --csv="@oname @id @lon @lat" --csv-headline -o=test.csv

On the other hand I also need the names of the road for eacht node. Is there anwy way to do so? thanks

asked 15 Oct '15, 14:01

Jorne's gravatar image

accept rate: 0%


I have no experience with those tools, but since you drop the ways, I think you lost the name information. You should look for the ways fulfilling your criteria and then take the nodes of those ways. Nodes that are defining a road do not have the attributes you are looking for (name, highway=primary). Those tags are set on the ways.

(16 Oct '15, 06:23) escada

This is not something you will be able to solve without programming skills. You will need to write a little program in a language of your choice that can parse XML documents. Download the area of interest as XML file. You will notice that it consists of three sections - one with all the nodes, one with all the ways, and one with all the relations.

Build your program so that it first reads the nodes, storing the latitude and longitude for each node found. Then, when your program arrives at the ways section, let it check whether the way is indeed a road (could also be a building or a power line or something), and when it is, have your program output the way's nodes together with the (previously recorded) node id.

A very simple Perl program that does this might look like this

while(<>) {
  if (/<node id="(\d+)" .*lat="([^"]+)" .*lon="([^"]+)"/) {
  } elsif(/<tag k="(.*)" v="(.*)"/) {
    $hwy = $2 if ($1 eq "highway");
    $nam = $2 if ($1 eq "name");
  } elsif(/<nd ref="(\d+)"/) {
  } elsif(/<\/way/) {
    if (defined($hwy)) {
      printf "%d,\"%s\",%s\n", $_, $nam, $loc{$_} foreach(@nodes);
    undef $hwy, $nam, @nodes;

Of course there's many ways in which this can be made more resilient and faster if you need to process large amounts of data.

permanent link

answered 19 Oct '15, 22:56

Frederik%20Ramm's gravatar image

Frederik Ramm ♦
accept rate: 24%

edited 19 Oct '15, 22:59

Your answer
toggle preview

Follow this question

By Email:




Answers and Comments

Markdown Basics

  • *italic* or _italic_
  • **bold** or __bold__
  • numbered list: 1. Foo 2. Bar
  • basic HTML tags are also supported

Question tags:


question asked: 15 Oct '15, 14:01

question was seen: 2,385 times

last updated: 19 Oct '15, 22:59

powered by OSQA