source: subversion/applications/rendering/mapnik/osm2pgsl.py @ 17971

Last change on this file since 17971 was 3128, checked in by spaetz, 13 years ago

fix simple syntax errors (line breaks). Patch courtesy to Darryl (Dshpak)

  • Property svn:executable set to *
File size: 6.3 KB
Line 
1#!/opt/python-2_5/bin/python
2
3import sys,xml.sax
4from xml.sax.handler import ContentHandler
5from cElementTree import Element, SubElement, ElementTree
6from optparse import OptionParser
7
8exportTags = [ ("name","varchar(64)"),
9               ("place","varchar(32)"),
10               ("landuse","varchar(32)"),
11               ("leisure","varchar(32)"),
12               ("waterway","varchar(32)"),
13               ("highway","varchar(32)"),
14               ("amenity","varchar(32)"),
15               ("tourism","varchar(32)"),
16               ("learning","varchar(32)")
17               ]
18segments = {}
19table_name = "planet_osm"
20
21class osm2sql (ContentHandler):
22    def __init__(self,fh):
23        ContentHandler.__init__(self)
24        self.fh = fh
25    def startDocument (self):
26        self.node = {}
27        self.stack = []
28    def startElement(self,name,attr):
29        if name == 'node':
30            self.node[attr["id"]] = (attr["lon"], attr["lat"])
31            self.stack.append({'type':'node','id':attr["id"],'tags':{}})
32        elif name == 'segment':
33            from_node = self.node[attr["from"]]
34            to_node   = self.node[attr["to"]]
35            segments[attr["id"]] = from_node,to_node
36        elif name == 'tag':
37            k = attr['k'].replace(":","_").replace(" ","_")
38            v = attr['v']
39            self.stack.append((k,v))
40        elif name == 'way':
41            self.stack.append({'type':'way','id':attr["id"],'segs': [],'tags':{}})
42        elif name == 'seg':
43            self.stack[-1]['segs'].append(attr["id"])
44           
45    def endElement (self,name):
46        if name == 'segment':
47            pass
48        elif name == 'node':
49            node = self.stack.pop()
50            osm_id = node['id']
51            fields = ",".join(["%s" % f[0] for f in exportTags])
52            values = []
53            count=0
54            for tag in exportTags:
55                if tag[0] in node['tags']:
56                    values.append("$$%s$$" % node['tags'][tag[0]])
57                    count+=1
58                else:
59                    values.append("$$$$")
60               
61            if count > 0: # only create POINT feature if node has some tags
62                values = ",".join(values)
63                #values = values.encode("UTF-8")
64                wkt = 'POINT(%s %s)' % (self.node[osm_id])
65                sql = "insert into %s (osm_id,%s,way) values (%s,%s,GeomFromText('%s',4326));" % (table_name,fields,osm_id,values,wkt)
66                print sql.encode("UTF-8")
67               
68        elif name == 'tag':
69            tag = self.stack.pop()
70            if len(self.stack) > 0 :
71                if 'type' in self.stack[-1] and ( self.stack[-1]['type'] == 'way' or self.stack[-1]['type'] == 'node') :
72                    self.stack[-1]['tags'][tag[0]] = tag[1]
73               
74        elif name == 'way':
75            way = self.stack.pop()
76            osm_id = way['id']
77            fields = ",".join(["%s" % f[0] for f in exportTags])
78            polygon = False
79            values = []
80            for tag in exportTags:
81                if tag[0] in way['tags']:
82                    if tag[0] == 'landuse' or tag[0] == 'leisure':
83                        polygon = True
84                    values.append("$$%s$$" % way['tags'][tag[0]])
85                else:
86                    values.append("$$$$")
87            values = ",".join(values)
88
89            wkt,status = self.WKT(way,polygon)
90            if status :
91                sql = "insert into %s (osm_id,%s,way) values (%s,%s,GeomFromText('%s',4326));" % (table_name,fields,osm_id,values,wkt)
92                print sql.encode("UTF-8")
93            else:
94                for s in way['segs']:
95                    try:
96                        from_node,to_node = segments[s]
97                        wkt = 'LINESTRING(%s %s,%s %s)' % (from_node[0],from_node[1],to_node[0],to_node[1]) 
98                        sql = "insert into %s (osm_id,%s,way) values (%s,%s,GeomFromText('%s',4326));" % (table_name,fields,osm_id,
99values,wkt)
100                        print sql.encode("UTF-8")
101                    except:
102                        pass
103           
104    def WKT(self,way, polygon=False):
105        first = True
106        wkt = ""
107
108        max = len(way['segs']) * len(way['segs'])
109        i = 0
110        while way['segs'] and i < max:
111            id = way['segs'].pop()
112            i+=1
113            if id in segments:
114                from_node,to_node = segments[id]
115                x0 = from_node[0]
116                y0 = from_node[1]
117                x1 = to_node[0]
118                y1 = to_node[1]
119           
120                if first:
121                    first = False
122                    start_x = x0
123                    start_y = y0
124                    end_x = x1
125                    end_y = y1
126                    wkt = '%s %s,%s %s' % (x0,y0,x1,y1)
127                else:
128                    if (start_x == x0) and (start_y == y0) :
129                        start_x = x1
130                        start_y = y1
131                        wkt ='%s %s,' % (x1,y1) + wkt
132                    elif (start_x == x1) and (start_y == y1) :
133                        start_x = x0
134                        start_y = y0
135                        wkt ='%s %s,' % (x0,y0) + wkt
136                    elif (end_x == x0) and (end_y == y0) :
137                        end_x = x1
138                        end_y = y1
139                        wkt += ',%s %s' % (x1,y1)
140                    elif (end_x == x1) and (end_y == y1) :
141                        end_x = x0
142                        end_y = y0
143                        wkt += ',%s %s' % (x0,y0)
144                    else:
145                        way['segs'].insert(0,id)
146           
147        if polygon:
148            wkt = wkt + ",%s %s" % (start_x,start_y)
149            wkt = 'POLYGON ((%s))' % wkt
150        else:
151            wkt = 'LINESTRING (%s)' % wkt
152        if way['segs']:
153            return wkt,False
154        else:
155            return wkt,True
156           
157if __name__ == "__main__":
158    parser = osm2sql(sys.stdout)
159    fields = ",".join(["%s %s" % (tag[0],tag[1]) for tag in exportTags])
160    print "drop table %s ;" % table_name
161    print "create table %s ( osm_id int4,%s );" % (table_name,fields)
162    print "select AddGeometryColumn('%s', 'way', 4326, 'GEOMETRY', 2 );" % table_name
163    print "begin;"
164    xml.sax.parse(sys.stdin,parser)
165    print "commit;"
166    print "vacuum analyze %s;" % table_name
Note: See TracBrowser for help on using the repository browser.