source: subversion/applications/routing/pyroute/loadOsm.py @ 5300

Last change on this file since 5300 was 5300, checked in by ojw, 12 years ago

Clean-up the interface

File size: 3.4 KB
Line 
1#!/usr/bin/python
2#----------------------------------------------------------------
3# load OSM data file into memory
4#
5#------------------------------------------------------
6# Usage:
7#  pyroute.py [input OSM file] [start node] [end node]
8#------------------------------------------------------
9# Copyright 2007, Oliver White
10#
11# This program is free software: you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation, either version 3 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program.  If not, see <http://www.gnu.org/licenses/>.
23#------------------------------------------------------
24# Changelog:
25#  2007-11-03  OJW  Created
26#------------------------------------------------------
27import sys
28from xml.sax import make_parser, handler
29
30class LoadOsm(handler.ContentHandler):
31  """Parse an OSM file looking for routing information, and do routing with it"""
32  def __init__(self, filename):
33    """Initialise an OSM-file parser"""
34    self.routing = {}
35    self.nodes = {}
36    parser = make_parser()
37    parser.setContentHandler(self)
38    parser.parse(filename)
39  def report(self):
40    """Display some info about the loaded data"""
41    return "Loaded %d nodes and %d routable sections" % ( \
42      len(self.nodes.keys()), 
43      len(self.routing.keys()))
44  def startElement(self, name, attrs):
45    """Handle XML elements"""
46    if name in('node','way','relation'):
47      self.tags = {}
48      self.waynodes = []
49      if name == 'node':
50        """Nodes need to be stored"""
51        id = int(attrs.get('id'))
52        lat = float(attrs.get('lat'))
53        lon = float(attrs.get('lon'))
54        self.nodes[id] = (lat,lon)
55    elif name == 'nd':
56      """Nodes within a way -- add them to a list"""
57      self.waynodes.append(int(attrs.get('ref')))
58    elif name == 'tag':
59      """Tags - store them in a hash"""
60      k,v = (attrs.get('k'), attrs.get('v'))
61      if not k in ('created_by'):
62        self.tags[k] = v
63  def endElement(self, name):
64    """Handle ways in the OSM data"""
65    if name == 'way':
66      last = -1
67      highway = self.tags.get('highway', '')
68      railway = self.tags.get('railway', '')
69      oneway = self.tags.get('oneway', '')
70      reversible = not oneway in('yes','true','1')
71      cyclable = highway in ('primary','secondary','tertiary','unclassified','minor','cycleway','residential', 'service')
72      if cyclable:
73        for i in self.waynodes:
74          if last != -1:
75            #print "%d -> %d & v.v." % (last, i)
76            self.addLink(last, i)
77            if reversible:
78              self.addLink(i, last)
79          last = i
80  def addLink(self,fr,to):
81    """Add a routeable edge to the scenario"""
82    # Look for existing
83    try:
84      if to in self.routing[fr]:
85        #print "duplicate %d from %d" % (to,fr)
86        return
87      # Try to add to list. If list doesn't exist, create it
88      self.routing[fr].append(to)
89    except KeyError:
90      self.routing[fr] = [to]
91
92# Parse the supplied OSM file
93if __name__ == "__main__":
94  print "Loading data..."
95  data = LoadOsm(sys.argv[1])
96  print data.report()
Note: See TracBrowser for help on using the repository browser.