[OSM-dev] osm-mysql2geom.py

Robert (Jamie) Munro rjmunro at arjam.net
Fri Apr 27 00:52:56 BST 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

#!/usr/bin/python
""" This script demonstrates how to take a dump from the OSM database
that returns data in a useful "geometric" order. This makes it much
easier to convert to shapefiles etc. than the standard .osm
format. It's been made to work with an OSM db made with the perl
script that converts osm2mysql - it will need adapting to work
with the real db which uses different tables."""

def process_data(db, output_way, limit=None, get_way_tags=True):
  """ Process the data. DB is the mysql handle. output_way is the
  function that should be called for each way. Limit is just for
  debugging by producing less data."""

  segment_query = """select way_segments.id as way_id,segments.*
    from way_segments
    inner join segments on way_segments.segment_id=segments.id
    order by way_segments.id,way_segments.sequence_id"""
  if limit: segment_query +=" limit %s;" % limit

  segment_cursor = db.cursor()
  segment_cursor.execute(segment_query)
  fields = [i[0] for i in segment_cursor.description]

  node_query = """select latitude, longitude from nodes where id=%s;"""
  tag_query = """select k, v from way_tags where id=%s;"""
  spare_cursor = db.cursor()

  def nodeDetails(nodeid):
    spare_cursor.execute(node_query,nodeid)
    latitude,longitude = spare_cursor.fetchone()
    return {'id':nodeid,'lat':latitude,'lon':longitude}

  def wayTags(wayid):
    spare_cursor.execute(tag_query,wayid)
    return dict(spare_cursor)

  def nextsegment_row():
    segment_row = segment_cursor.fetchone()
    if segment_row:
      return dict(zip(fields,segment_row))
    else:
      return None

  segment_row = nextsegment_row()
  while segment_row:
    way_id = segment_row['way_id']
    way_lines = []
    while segment_row and segment_row['way_id'] == way_id:
      part_way_points = [segment_row['node_a'],segment_row['node_b']]
      segment_row = nextsegment_row()
      while segment_row and \
          segment_row['node_a'] == part_way_points[-1] and \
          segment_row['way_id'] == way_id:
        part_way_points += [segment_row['node_b']]
        segment_row = nextsegment_row()
      way_lines += [ [nodeDetails(i) for i in part_way_points]]
    if len(way_lines)>1:
      type = "multiline"
    elif way_lines[0][0] == way_lines[0][-1]:
      type = "loop"
    else:
      type = "line"
    output_way(id = way_id, lines = way_lines, type = type,
                    tags = get_way_tags and wayTags(way_id))


if __name__ == "__main__":
  """ Example XML producing code. Call the script by itself to
  use, or import the script and do your own display."""
  import MySQLdb
  db = MySQLdb.connect(host="localhost", user="root", passwd="",db="osm")

  def output_way(id,type,lines,tags):
    """ function called with the details of each way. Replace this to
    customise the output of this script, e.g. change the schema,
    make SQL, or even insert straight into another database."""
    print '  <way id="%s", type="%s">' % (id,type)
    for line in lines:
      print '    <line>'
      for node in line:
        print '      <node id="%s" lat="%s" lon="%s" />' %
(node['id'],node['lat'],node['lon'])
      print '    </line>'
    for key in tags:
      print '    <tag k="%s">%s</tag>' % (key, tags[key])
    print '  </way>'


  from sys import argv
  if len(argv)==2:
    limit = argv[1]
  else:
    limit = 0
  print '<?xml version="1.0" encoding "UTF-8"?>'
  print '<geoosm>'
  process_data(db, output_way, limit)
  print '</geoosm>'
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGMTtVz+aYVHdncI0RApqNAJ4tSEbkdfpBMjfeWNoQCRJHkd5lrgCgjXHN
Hsy60bOpZ4a47Hf+mXhPz4g=
=witU
-----END PGP SIGNATURE-----




More information about the dev mailing list