source: subversion/applications/rendering/pyrender/OsmMerge.py

Last change on this file was 8750, checked in by ojw, 11 years ago

probably should stop using lat/long as names for these variables, it
only gets confusing

http://wiki.openstreetmap.org/index.php/Talk:Pyrender

File size: 3.8 KB
Line 
1#!/usr/bin/python
2#----------------------------------------------------------------------------
3# Merge multiple OSM files (in memory) and save to another OSM file
4#----------------------------------------------------------------------------
5# Copyright 2008, Oliver White
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19#---------------------------------------------------------------------------
20import codecs
21from parseOsm import *
22from xml.sax.saxutils import quoteattr
23
24def pixelSize(z):
25  """length of x/y change that represents 1 pixel at a given zoom level"""
26  return(1.0 / float(256 * pow(2,z)))
27
28def OsmMerge(dest, z, sources):
29  """Merge multiple OSM files together
30 
31  Usage:
32    OsmMerge('output_filename.osm',
33      ['input_file_1.osm',
34       'input_file_2.osm',
35       'input_file_3.osm'])
36  """
37 
38  ways = {}
39  poi = []
40  node_tags = {}
41  nodes = {}
42 
43  divisor = float(2 ** 31)
44 
45  # Trawl through the source files, putting everything into memory
46  for source in sources:
47    osm = parseOsm(source)
48   
49    for p in osm.poi:
50      node_tags[p['id']] = p['t']
51
52    for id,n in osm.nodes.items():
53      nodes[id] = n
54    for id,w in osm.ways.items():
55      ways[id] = w
56
57  # Store the result as an OSM XML file
58  f=codecs.open(dest, mode='w', encoding='utf-8')
59  f.write('<?xml version="1.0" encoding="UTF-8"?>\n')
60  f.write('<osm version="0.5" generator="OsmMerge">\n')
61 
62  # TODO: Write the nodes
63  if(0):
64          for n,data in nodes.items():
65            (lat,lon) = nodes[n]
66            f.write('<node id="%d" lat="%f" lon="%f">' % (n,lat,lon))
67            tags = node_tags.get(n, None)
68            if(tags):
69              for k,v in tags.items():
70                f.write('\n<tag k=%s v=%s/>' % (quoteattr(k),quoteattr(v)))
71            f.write("</node>\n")
72
73  limit = pixelSize(z) * 2.0
74  limitSq = limit * limit
75  #print "Using limit %e" % limitSq
76 
77  # Detect 'junction' ways
78  usage = {}
79  junctions = {}
80  countNodes = 0
81  for wid,way in ways.items():
82    for n in way['n']:
83      nid = n['id']
84      if(usage.get(nid,0) != 0):
85        junctions[nid] = 1
86      else:
87        usage[nid] = 1
88      countNodes = countNodes + 1
89
90  #print "%d nodes, %d junctions" % (countNodes, len(junctions.keys()))
91
92  countUsed = countNotUsed = 0
93  # Write the ways
94  for id,way in ways.items():
95    f.write('<way id="%d">' % id)
96    for k,v in way['t'].items():
97      f.write('\n<tag k=%s v=%s/>' % (quoteattr(k),quoteattr(v)))
98
99    (lastx,lasty,count) = (0,0,False)
100    for n in way['n']:
101      lat = n['lat']
102      lon = n['lon']
103     
104      storeThisNode = False
105      if(count == 0):
106        storeThisNode = True  # Store 1st node
107      elif(junctions.get(n['id'], 0) == 1):
108        storeThisNode = True  # Store junction nodes
109      else:
110        dx = lon - lastx
111        dy = lat - lasty
112        dd = dx * dx + dy * dy
113        if(dd > limitSq):
114          storeThisNode = True  # Store ever x pixels
115         
116        #print "Dist2 = %f" % dd
117       
118      if(storeThisNode):
119        (lastx,lasty,count) = (lon,lat,count+1)
120     
121        f.write("\n<nd id='%d' x='%1.0f' y='%1.0f'/>" % (n['id'], lon * divisor, lat * divisor))
122        countUsed = countUsed + 1
123      else:
124        countNotUsed = countNotUsed + 1
125    f.write("</way>\n")
126  #print "Used %d, skipped %d" % (countUsed, countNotUsed)
127 
128  # TODO: Write the relations
129
130 
131  f.write("</osm>\n")
132  f.close()
133
Note: See TracBrowser for help on using the repository browser.