Skip to content

Commit a6dd7cf

Browse files
committed
Use MongoDB's 1.9 multi-location document indexing support to index ways.
1 parent 0d8857c commit a6dd7cf

File tree

2 files changed

+52
-33
lines changed

2 files changed

+52
-33
lines changed

insert_osm_data.py

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,12 @@ def __init__(self, client):
1616
self.records = []
1717
self.record = {}
1818
self.client = client
19-
self.client.osm.nodes.ensure_index([('loc', pymongo.GEO2D),
20-
('id', pymongo.ASCENDING),
21-
('version', pymongo.DESCENDING)])
19+
self.client.osm.nodes.ensure_index([('loc', pymongo.GEO2D)])
2220
self.client.osm.nodes.ensure_index([('id', pymongo.ASCENDING),
2321
('version', pymongo.DESCENDING)])
2422
self.client.osm.ways.ensure_index([('id', pymongo.ASCENDING),
2523
('version', pymongo.DESCENDING)])
24+
self.client.osm.ways.ensure_index([('loc', pymongo.GEO2D)])
2625
self.client.osm.relations.ensure_index([('id', pymongo.ASCENDING),
2726
('version', pymongo.DESCENDING)])
2827
def fillDefault(self, attrs):
@@ -58,6 +57,11 @@ def startElement(self, name, attrs):
5857
k = k.replace('.', ',,')
5958
self.record['tags'][k] = attrs['v']
6059
elif name == 'way':
60+
# Insert remaining nodes
61+
if len(self.records) > 0:
62+
self.client.osm.nodes.insert(self.records)
63+
self.records = []
64+
6165
self.fillDefault(attrs)
6266
self.record['nodes'] = []
6367
elif name == 'relation':
@@ -66,16 +70,6 @@ def startElement(self, name, attrs):
6670
elif name == 'nd':
6771
ref = long(attrs['ref'])
6872
self.record['nodes'].append(ref)
69-
70-
nodes2ways = self.client.osm.nodes.find_one({ 'id' : ref })
71-
if nodes2ways:
72-
if 'ways' not in nodes2ways:
73-
nodes2ways['ways'] = []
74-
nodes2ways['ways'].append(self.record['id'])
75-
self.client.osm.nodes.save(nodes2ways)
76-
else:
77-
print "Node %d ref'd by way %d not in file." % \
78-
(ref, self.record['id'])
7973
elif name == 'member':
8074
ref = long(attrs['ref'])
8175
member = {'type': attrs['type'],
@@ -108,7 +102,12 @@ def endElement(self, name):
108102
self.records = []
109103
self.record = {}
110104
elif name == 'way':
111-
self.client.osm.ways.save(self.record)
105+
nodes = self.client.osm.nodes.find({ 'id': { '$in': self.record['nodes'] } }, { 'loc': 1, '_id': 0 })
106+
self.record['loc'] = []
107+
for node in nodes:
108+
self.record['loc'].append(node['loc'])
109+
110+
self.client.osm.ways.insert(self.record, safe=True)
112111
self.record = {}
113112
elif name == 'relation':
114113
self.client.osm.relations.save(self.record)

map_server.py

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,24 @@ def getNodesInBounds(self, box):
1515

1616
return nodes
1717

18+
def getWaysInBounds(self, box):
19+
cursor = self.client.osm.ways.find({'loc' : { '$within' : { '$box' : box } } }, { 'loc': 0 })
20+
ways = []
21+
22+
for row in cursor:
23+
ways.append(row)
24+
25+
return ways
26+
27+
1828
def getNodesFromWays(self, ways):
19-
nodeIds = set()
29+
nodeIds = set()
2030

2131
for way in ways:
2232
for nodeId in way['nodes']:
2333
nodeIds.add(nodeId)
2434

25-
nodes = []
26-
for nodeId in nodeIds:
27-
node = self.client.osm.nodes.find_one({'id' : nodeId})
28-
if node:
29-
nodes.append(node)
30-
else:
31-
print "Error. couldn't find node id %d." % nodeId
35+
nodes = self.client.osm.nodes.find({'id': {'$in': list(nodeIds)} })
3236

3337
return nodes
3438

@@ -118,20 +122,34 @@ def getRelationById(self, id):
118122
def getBbox(self, bbox):
119123
import time, sys
120124

121-
sys.stderr.write("<!-- Start %s -->\n" % time.time())
125+
start = time.time()
126+
122127
nodes = self.getNodesInBounds(bbox)
123-
sys.stderr.write("<!-- Get nodes %s -->\n" % time.time())
124-
ways = self.getWaysFromNodes(nodes)
125-
sys.stderr.write("<!-- Get ways %s -->\n" % time.time())
128+
129+
timeA = time.time()
130+
sys.stderr.write("<!-- Get nodes in bbox %s -->\n" % (timeA - start))
131+
132+
ways = self.getWaysInBounds(bbox)
133+
134+
timeB = time.time()
135+
sys.stderr.write("<!-- Get ways in bbox %s -->\n" % (timeB - timeA))
126136

127137
wayNodes = self.getNodesFromWays(ways)
138+
139+
timeC = time.time()
140+
sys.stderr.write("<!-- Get nodes from ways %s -->\n" % (timeC - timeB))
141+
128142
for n in wayNodes:
129143
if n['id'] not in nodes:
130144
nodes.append(n)
131-
sys.stderr.write("<!-- Get nodes from ways %s -->\n" % time.time())
145+
146+
timeD = time.time()
147+
sys.stderr.write("<!-- Collate nodes from ways %s -->\n" % (timeD - timeC))
132148

133149
relations = self.getRelationsFromWays(ways)
134-
sys.stderr.write("<!-- Get relations %s -->\n" % time.time())
150+
151+
timeE = time.time()
152+
sys.stderr.write("<!-- Get relations %s -->\n" % (timeE - timeD))
135153

136154
doc = {'bounds': {'minlat': bbox[0][0],
137155
'minlon': bbox[0][1],
@@ -275,13 +293,15 @@ def bareApi(request):
275293
(r'^api$', bareApi))
276294

277295
if __name__ == '__main__':
278-
"""
279296
import time, sys
280-
bbox = [[46.784,-92.3746],[46.8197,-92.3159]]
297+
#bbox = [[46.784,-92.3746],[46.8197,-92.3159]]
298+
bbox = [[39.2674,-75.5644],[39.2839,-75.5349]]
281299
api = OsmApi()
282300
data = api.getBbox(bbox)
283301

284302
outputter = OsmXmlOutput()
285-
outputter.write(data)
286-
sys.stderr.write("<!-- XML output %s -->\n" % time.time())
287-
"""
303+
start = time.time()
304+
outfile = open(sys.argv[1], 'w')
305+
outfile.write(outputter.toXml(data))
306+
outfile.close()
307+
sys.stderr.write("<!-- XML output %s -->\n" % (time.time() - start))

0 commit comments

Comments
 (0)