# Collecting street data to populate a graph stucture for routing

I'm implementing a basic digraph with weighted edges for street routing in a small geo area (600mx600m). How and where can I get the required data to populate such a structure? I've been reading about OpenStreetMap, but am unsure as to how I can export the required data into my application.

The kind of data I would need is - all the streets (nodes) in the specified area, their connecting streets (subsequent nodes), and the distances between them.

-
Does it have to be a JAVA-only solution? – underdark May 13 '12 at 11:10

My bad. If you know Python, here's a code snippet that imports osm data and convert's it to a NetworkX graph:

``````"""
Read graphs in Open Street Maps osm format

Based on osm.py from brianw's osmgeocode
http://github.com/brianw/osmgeocode, which is based on osm.py from
comes from Graphserver:
2007, Brandon Martin-Anderson under the BSD License
"""

import xml.sax
import copy
import networkx

from urllib import urlopen
fp = urlopen( "http://api.openstreetmap.org/api/0.5/map?bbox=%f,%f,%f,%f"%(left,bottom,right,top) )
return fp

"""Read graph in OSM format from file specified by name or by stream object.

Parameters
----------
filename_or_stream : filename or stream object

Returns
-------
G : Graph

Examples
--------
>>> plot([G.node[n]['data'].lat for n in G], [G.node[n]['data'].lon for n in G], ',')

"""
osm = OSM(filename_or_stream)
G = networkx.Graph()

for w in osm.ways.itervalues():
if only_roads and 'highway' not in w.tags:
continue
for n_id in G.nodes_iter():
n = osm.nodes[n_id]
G.node[n_id] = dict(data=n)
return G

class Node:
def __init__(self, id, lon, lat):
self.id = id
self.lon = lon
self.lat = lat
self.tags = {}

class Way:
def __init__(self, id, osm):
self.osm = osm
self.id = id
self.nds = []
self.tags = {}

def split(self, dividers):
# slice the node-array using this nifty recursive function
def slice_array(ar, dividers):
for i in range(1,len(ar)-1):
if dividers[ar[i]]>1:
#print "slice at %s"%ar[i]
left = ar[:i+1]
right = ar[i:]

rightsliced = slice_array(right, dividers)

return [left]+rightsliced
return [ar]

slices = slice_array(self.nds, dividers)

# create a way object for each node-array slice
ret = []
i=0
for slice in slices:
littleway = copy.copy( self )
littleway.id += "-%d"%i
littleway.nds = slice
ret.append( littleway )
i += 1

return ret

class OSM:
def __init__(self, filename_or_stream):
""" File can be either a filename or stream/file object."""
nodes = {}
ways = {}

superself = self

class OSMHandler(xml.sax.ContentHandler):
@classmethod
def setDocumentLocator(self,loc):
pass

@classmethod
def startDocument(self):
pass

@classmethod
def endDocument(self):
pass

@classmethod
def startElement(self, name, attrs):
if name=='node':
self.currElem = Node(attrs['id'], float(attrs['lon']), float(attrs['lat']))
elif name=='way':
self.currElem = Way(attrs['id'], superself)
elif name=='tag':
self.currElem.tags[attrs['k']] = attrs['v']
elif name=='nd':
self.currElem.nds.append( attrs['ref'] )

@classmethod
def endElement(self,name):
if name=='node':
nodes[self.currElem.id] = self.currElem
elif name=='way':
ways[self.currElem.id] = self.currElem

@classmethod
def characters(self, chars):
pass

xml.sax.parse(filename_or_stream, OSMHandler)

self.nodes = nodes
self.ways = ways

#count times each node is used
node_histogram = dict.fromkeys( self.nodes.keys(), 0 )
for way in self.ways.values():
if len(way.nds) < 2:       #if a way has only one node, delete it out of the osm collection
del self.ways[way.id]
else:
for node in way.nds:
node_histogram[node] += 1

#use that histogram to split all ways, replacing the member set of ways
new_ways = {}
for id, way in self.ways.iteritems():
split_ways = way.split(node_histogram)
for split_way in split_ways:
new_ways[split_way.id] = split_way
self.ways = new_ways
``````

https://gist.github.com/287370

Code's not mine btw.

-
how can this help me load the data I need into my application? I can see that I can convert OSM to net files; how can I export route information that I can use? – wulfgarpro Mar 14 '12 at 2:48

If you opted for a PostGIS/pgrouting based solution, you could import OSM data via osm2pgrouting : http://www.pgrouting.org/docs/tools/osm2pgrouting.html.

-