forked from rethinkdb/geojson-streetmaps
/
server.py
95 lines (81 loc) · 3.66 KB
/
server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import argparse
import os
import json
from datetime import datetime
from itertools import islice
import rethinkdb as r
import tornado.web
from more_itertools import chunked
class RethinkDBHandler(tornado.web.RequestHandler):
def initialize(self):
self.conn = r.connect(self.application.settings['host'],
self.application.settings['port'],
db=self.application.settings['db'])
class PointOfInterestHandler(RethinkDBHandler):
def get(self, *args):
self.set_header('Content-Type', 'application/json')
center = r.point(*map(float, args))
selection = r.table('points_of_interest').get_nearest(
center, index='geometry', max_results=20, unit='mi')
start_t = datetime.now()
array = selection.map(lambda row: {
'type': 'Feature',
'geometry': row['doc']['geometry'].to_geojson(),
'properties': row['doc']['properties'].merge(
{'distance': row['dist']}),
}).run(self.conn)
total_t = (datetime.now() - start_t).total_seconds()
print 'POI query took', total_t, 's and provided', len(array), 'results'
self.write(json.dumps(array))
class OSMHandler(RethinkDBHandler):
def write_event(self, data):
self.write('data: {}\n\n'.format(json.dumps(data)))
self.flush()
def get(self, *args):
self.set_header('Content-Type', 'text/event-stream')
north, south, east, west = map(float, args)
start_t = datetime.now()
query_range = r.polygon(
r.point(west, north),
r.point(west, south),
r.point(east, south),
r.point(east, north))
selection = (r.table('streets')
.get_intersecting(query_range, index='geometry'))
initial_t = (datetime.now() - start_t).total_seconds()
cursor = selection.map(r.row['geometry'].to_geojson()).run(self.conn)
size = 0
for chunk in chunked(cursor, 2000):
size += len(chunk)
self.write_event(chunk)
self.write_event('done')
total_t = (datetime.now() - start_t).total_seconds()
print 'street query took', initial_t, 's for the first batch',
print '(', total_t, 's total) and provided', size, 'results.'
def main(port, host, rport, db):
settings = {'host': host, 'port': rport, 'db': db}
print 'Server running on http://localhost:{}'.format(port)
print 'Connected to RethinkDB on {}:{}'.format(host, rport)
routes = [
(r'/osm/(.*?)/(.*?)/(.*?)/(.*?)/?', OSMHandler),
(r'/poi/(.*?)/(.*?)/?', PointOfInterestHandler),
(r'/()$', tornado.web.StaticFileHandler,
{'path': 'static/index.html'}),
(r'/(.+)', tornado.web.StaticFileHandler, {'path': 'static'}),
]
tornado.web.Application(routes, **settings).listen(port)
tornado.ioloop.IOLoop.instance().start()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--port', type=int, default=8090,
help='Port server should run on')
parser.add_argument('--rdbhost', default=os.getenv('RDBHOST', 'localhost'),
help='RethinkDB hostname to connect to')
parser.add_argument('--rdbport', type=int,
default=int(os.getenv('RDBPORT', 28015)),
help='RethinkDB port to connect to')
parser.add_argument('--db', '-d',
default=os.getenv('DB', 'geojson_streetmaps'),
help='Database to use (default: geojson_streetmaps)')
args = parser.parse_args()
main(args.port, args.rdbhost, args.rdbport, args.db)