source: subversion/utils/mapnik/osm2pgsl.py @ 2026

Last change on this file since 2026 was 1846, checked in by joerg, 13 years ago

set executable property

  • 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,w
66kt)
67                print sql.encode("UTF-8")
68               
69        elif name == 'tag':
70            tag = self.stack.pop()
71            if len(self.stack) > 0 :
72                if 'type' in self.stack[-1] and ( self.stack[-1]['type'] == 'way' or self.stack[-1]['type'] == 'node') :
73                    self.stack[-1]['tags'][tag[0]] = tag[1]
74               
75        elif name == 'way':
76            way = self.stack.pop()
77            osm_id = way['id']
78            fields = ",".join(["%s" % f[0] for f in exportTags])
79            polygon = False
80            values = []
81            for tag in exportTags:
82                if tag[0] in way['tags']:
83                    if tag[0] == 'landuse' or tag[0] == 'leisure':
84                        polygon = True
85                    values.append("$$%s$$" % way['tags'][tag[0]])
86                else:
87                    values.append("$$$$")
88            values = ",".join(values)
89
90            wkt,status = self.WKT(way,polygon)
91            if status :
92                sql = "insert into %s (osm_id,%s,way) values (%s,%s,GeomFromText('%s',4326));" % (table_name,fields,osm_id,values,w
93kt)
94                print sql.encode("UTF-8")
95            else:
96                for s in way['segs']:
97                    try:
98                        from_node,to_node = segments[s]
99                        wkt = 'LINESTRING(%s %s,%s %s)' % (from_node[0],from_node[1],to_node[0],to_node[1]) 
100                        sql = "insert into %s (osm_id,%s,way) values (%s,%s,GeomFromText('%s',4326));" % (table_name,fields,osm_id,
101values,wkt)
102                        print sql.encode("UTF-8")
103                    except:
104                        pass
105           
106    def WKT(self,way, polygon=False):
107        first = True
108        wkt = ""
109
110        max = len(way['segs']) * len(way['segs'])
111        i = 0
112        while way['segs'] and i < max:
113            id = way['segs'].pop()
114            i+=1
115            if id in segments:
116                from_node,to_node = segments[id]
117                x0 = from_node[0]
118                y0 = from_node[1]
119                x1 = to_node[0]
120                y1 = to_node[1]
121           
122                if first:
123                    first = False
124                    start_x = x0
125                    start_y = y0
126                    end_x = x1
127                    end_y = y1
128                    wkt = '%s %s,%s %s' % (x0,y0,x1,y1)
129                else:
130                    if (start_x == x0) and (start_y == y0) :
131                        start_x = x1
132                        start_y = y1
133                        wkt ='%s %s,' % (x1,y1) + wkt
134                    elif (start_x == x1) and (start_y == y1) :
135                        start_x = x0
136                        start_y = y0
137                        wkt ='%s %s,' % (x0,y0) + wkt
138                    elif (end_x == x0) and (end_y == y0) :
139                        end_x = x1
140                        end_y = y1
141                        wkt += ',%s %s' % (x1,y1)
142                    elif (end_x == x1) and (end_y == y1) :
143                        end_x = x0
144                        end_y = y0
145                        wkt += ',%s %s' % (x0,y0)
146                    else:
147                        way['segs'].insert(0,id)
148           
149        if polygon:
150            wkt = wkt + ",%s %s" % (start_x,start_y)
151            wkt = 'POLYGON ((%s))' % wkt
152        else:
153            wkt = 'LINESTRING (%s)' % wkt
154        if way['segs']:
155            return wkt,False
156        else:
157            return wkt,True
158           
159if __name__ == "__main__":
160    parser = osm2sql(sys.stdout)
161    fields = ",".join(["%s %s" % (tag[0],tag[1]) for tag in exportTags])
162    print "drop table %s ;" % table_name
163    print "create table %s ( osm_id int4,%s );" % (table_name,fields)
164    print "select AddGeometryColumn('%s', 'way', 4326, 'GEOMETRY', 2 );" % table_name
165    print "begin;"
166    xml.sax.parse(sys.stdin,parser)
167    print "commit;"
168    print "vacuum analyze %s;" % table_name
Note: See TracBrowser for help on using the repository browser.