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

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

Fix changelog to indicate this was copy-pasted from pyroute, not created

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