source: subversion/applications/utils/import/geobase2osm/geobase2osm.py @ 5763

Last change on this file since 5763 was 4887, checked in by jrreid, 13 years ago

geobase2osm: initial import

  • Property svn:eol-style set to native
File size: 7.7 KB
Line 
1import cElementTree as ET
2import sys
3import codecs
4import optparse
5
6# Allow enforcing of required arguements
7# code from http://www.python.org/doc/2.3/lib/optparse-extending-examples.html
8class OptionParser (optparse.OptionParser):
9
10    def check_required (self, opt):
11      option = self.get_option(opt)
12
13      # Assumes the option's 'default' is set to None!
14      if getattr(self.values, option.dest) is None:
15          self.error("%s option not supplied" % option)
16
17# Format the output in a prettier style.
18# code from the elementtree web site
19def indent(elem, level=0):
20    i = "\n" + level*"  "
21    if len(elem):
22        if not elem.text or not elem.text.strip():
23            elem.text = i + "  "
24        for e in elem:
25            indent(e, level+1)
26            if not e.tail or not e.tail.strip():
27                e.tail = i + "  "
28        if not e.tail or not e.tail.strip():
29            e.tail = i
30    else:
31        if level and (not elem.tail or not elem.tail.strip()):
32            elem.tail = i
33
34# Convert a string to an int if possible
35def convertStr(s):
36  try:
37    return int(s)
38  except ValueError:
39    return s
40 
41
42# Namespaces
43nrn_ns = "{http://www.geobase.ca/nrn}"
44ogc_ns = "{http://www.opengis.net/gml}"
45
46# Mapping of NRN road types to OSM highway types
47highway = {}
48highway["Freeway"] = "trunk"
49highway["Expressway / Highway"] = "primary"
50highway["Arterial"] = "secondary"
51highway["Collector"] = "tertiary"
52highway["Local / Street"] = "residential"
53highway["Local / Unknown"] = "unclassified"
54highway["Alleyway / Lane"] = "service"
55highway["Ramp"] = "unclassified"
56highway["Service Lane"] = "service"
57highway["Resource / Recreation"] = "unclassified"
58highway["Local / Strata"] = "unclassified"
59
60highway["Rapid Transit"] = ""
61highway["Winter"] = ""
62
63attribution = 'Geobase.ca NRN'
64date = ''
65
66
67def main():
68  # Handle arguments
69 
70  usage = "usage: %prog -i NRN_GEOM.gml [-a NRN_ADDR.gml] [-o outfilefile.osm] [--pretty]"
71  parser = OptionParser(usage)
72  parser.add_option("-i", dest="geomfile", help="read data from GEOMFILE")
73  parser.add_option("-a", dest="addrfile", help="read optional data from ADDRFILE")
74  parser.add_option("-o", dest="outputfile", default="geobase.osm", help="store data to OUTPUTFILE") 
75  parser.add_option("--pretty", action="store_true", dest="indent", help="stylize the output file")
76   
77  (options, args) = parser.parse_args()
78
79  parser.check_required("-i")
80 
81  # Do the actual work
82  print "Reading NRN data file '" + options.geomfile + "'"
83 
84  osm = ET.Element("osm", generator='nrn2osm', version='0.5')
85 
86  nrn = ET.parse(options.geomfile)
87 
88  nodeid = -1
89  wayid = -1
90 
91  print "Transforming GML to OSM"
92 
93  for feature in nrn.findall('{http://www.opengis.net/gml}featureMember'):
94    for element in feature.findall(nrn_ns + 'RoadSegment'):
95   
96      way = ET.Element("way", id=str(wayid))
97      wayid -= 1
98
99      way_tags = {}
100   
101      for road in element.findall('*'):
102       
103        if road.text != 'None':
104          if road.tag == nrn_ns + 'nid':
105            way_tags['nrn:nid'] = road.text
106           
107          elif road.tag == nrn_ns + 'roadSegmentId' :
108             way_tags['nrn:roadsegmentid'] = road.text
109           
110          elif road.tag == nrn_ns + 'functionalRoadClass':
111            way_tags['highway'] = highway[road.text]
112           
113          elif road.tag == nrn_ns + 'numberOfLanes' :
114            way_tags['lanes'] = road.text
115           
116          elif road.tag == nrn_ns + 'pavementStatus' :
117            way_tags['surface'] = road.text
118           
119          elif road.tag == nrn_ns + 'routeNameEnglish1' :
120            way_tags['name'] = road.text
121         
122          elif road.tag == nrn_ns + 'routeNameFrench1' :
123            way_tags['name:fr'] = road.text
124           
125          elif road.tag == nrn_ns + 'routeNumber1':
126            way_tags['ref'] = road.text
127         
128          elif road.tag == nrn_ns + 'datasetName':
129            way_tags['nrn:datasetName'] = road.text
130         
131          elif road.tag == nrn_ns + 'structureType':
132            if road.text == 'Bridge' or road.text == 'Bridge Covered' or road.text == 'Bridge moveable' or road.text == 'Bridge unknown':
133              # Found a bridge
134              way_tags['bridge'] = 'yes'
135             
136            elif road.text == 'Tunnel':
137              # Found a tunnel             
138              way_tags['tunnel'] = 'yes'
139         
140        for lineString in road.findall('*/*'):
141          for set in lineString.text.split(' '):
142            coord = set.split(',')
143           
144            # Example node:
145            # <node id='-1' visible='true' lat='50.948611006929525' lon='-114.68740649854398' />         
146            node = ET.Element("node", visible='true', id=str(nodeid), lat=str(coord[1]), lon=str(coord[0]))
147           
148            # Add the node reference to the way
149            # <nd ref='-566' />
150            way.append(ET.Element('nd', ref=str(nodeid)))
151           
152            # Add the source to the node
153            # <tag k='source' v='123' />
154           
155            node.append(ET.Element('tag', k='attribution',v=attribution))
156            node.append(ET.Element('tag', k='source',v='geobase_import_'+date))
157           
158            nodeid -= 1
159           
160            osm.append(node)
161       
162        # Apply the post process rules on the way
163        # ---
164        # These rules will modify fields to fit with the Canadian tagging guidelines. Some rules can be expressed nationally, others, such as highway
165        # types may need to be done on a province by province basis
166     
167        if way_tags.has_key('ref') and way_tags.has_key('name'):
168       
169          if way_tags['nrn:datasetName'] == 'Prince Edward Island' or way_tags['nrn:datasetName'] == 'Newfoundland':
170           
171            if way_tags['ref'] == str(1) and way_tags['name'] == 'TransCanada Highway':
172              way_tags['highway'] = 'trunk'
173           
174
175        if way_tags.has_key('ref'):     
176          if way_tags['nrn:datasetName'] == 'Prince Edward Island' or way_tags['nrn:datasetName'] == 'Newfoundland':
177            if convertStr(way_tags['ref']) > 1 and convertStr(way_tags['ref']) <= 4:
178              way_tags['highway'] = 'primary'
179             
180            if convertStr(way_tags['ref']) > 4 and convertStr(way_tags['ref']) < 100:
181              way_tags['highway'] = 'secondary'
182             
183          """
184          elif way_tags['nrn:datasetName'] == 'Nova Scotia':
185         
186          elif way_tags['nrn:datasetName'] == 'Alberta':
187         
188          elif way_tags['nrn:datasetName'] == 'British Columbia':
189         
190          elif way_tags['nrn:datasetName'] == 'Saskatchewan':
191         
192          elif way_tags['nrn:datasetName'] == 'Manitoba':
193         
194          elif way_tags['nrn:datasetName'] == 'Newbrunswick':
195           
196          elif way_tags['nrn:datasetName'] == 'Quebec':
197         
198          elif way_tags['nrn:datasetName'] == 'Ontario':
199         
200          elif way_tags['nrn:datasetName'] == 'Newbrunswick':
201         
202          elif way_tags['nrn:datasetName'] == 'Yukon':
203         
204          elif way_tags['nrn:datasetName'] == 'Northwest Territories':
205         
206          elif way_tags['nrn:datasetName'] == 'Nunavut':
207         
208          """
209
210     
211      # Turn the dictionary of tags into their xml representation
212      for key,value in way_tags.iteritems():
213        way.append(ET.Element("tag",k=key,v=value))
214     
215      del(way_tags)       
216       
217      way.append(ET.Element("tag", k='attribution', v=attribution))
218      way.append(ET.Element('tag', k='source',v='geobase_import_'+date))
219           
220      osm.append(way)
221   
222  # Format the code by default
223  if options.indent:
224    print "Formatting output"
225    indent(osm)
226 
227  print "Saving to '" + options.outputfile + "'"
228 
229  f = open(options.outputfile, 'w')
230  f.write(ET.tostring(osm))
231
232if __name__ == "__main__":
233    main()
Note: See TracBrowser for help on using the repository browser.