89 lines
2.7 KiB
Python
89 lines
2.7 KiB
Python
import tornado.ioloop
|
|
import tornado.web
|
|
import io
|
|
import os
|
|
|
|
from sqlalchemy import create_engine, inspect
|
|
from sqlalchemy.orm import sessionmaker
|
|
|
|
import mercantile
|
|
import pyproj
|
|
import sys
|
|
import itertools
|
|
|
|
|
|
def getPreparedSql(file):
|
|
with open(file, 'r') as stream:
|
|
return stream.read()
|
|
|
|
|
|
prepared = getPreparedSql("/mapping/mvt/maketile_prep.sql")
|
|
engine = create_engine(
|
|
'postgresql://' + os.getenv('POSTGRES_USER', 'openmaptiles') +
|
|
':' + os.getenv('POSTGRES_PASSWORD', 'openmaptiles') +
|
|
'@' + os.getenv('POSTGRES_HOST', 'postgres') +
|
|
':' + os.getenv('POSTGRES_PORT', '5432') +
|
|
'/' + os.getenv('POSTGRES_DB', 'openmaptiles'))
|
|
inspector = inspect(engine)
|
|
DBSession = sessionmaker(bind=engine)
|
|
session = DBSession()
|
|
session.execute(prepared)
|
|
|
|
|
|
def bounds(zoom, x, y):
|
|
inProj = pyproj.Proj(init='epsg:4326')
|
|
outProj = pyproj.Proj(init='epsg:3857')
|
|
lnglatbbox = mercantile.bounds(x, y, zoom)
|
|
ws = (pyproj.transform(inProj, outProj, lnglatbbox[0], lnglatbbox[1]))
|
|
en = (pyproj.transform(inProj, outProj, lnglatbbox[2], lnglatbbox[3]))
|
|
return {'w': ws[0], 's': ws[1], 'e': en[0], 'n': en[1]}
|
|
|
|
|
|
def replace_tokens(query, s, w, n, e, zoom):
|
|
return (query
|
|
.replace("!bbox!", "ST_MakeBox2D(ST_Point(" + w + ", " + s + "), ST_Point(" + e + ", " + n + "))")
|
|
.replace("!zoom!", zoom)
|
|
.replace("!pixel_width!", "256"))
|
|
|
|
|
|
def get_mvt(zoom, x, y):
|
|
try:
|
|
# Sanitize the inputs
|
|
sani_zoom, sani_x, sani_y = float(zoom), float(x), float(y)
|
|
del zoom, x, y
|
|
except:
|
|
print('suspicious')
|
|
return 1
|
|
|
|
tilebounds = bounds(sani_zoom, sani_x, sani_y)
|
|
s, w, n, e = str(tilebounds['s']), str(tilebounds['w']), str(tilebounds['n']), str(tilebounds['e'])
|
|
final_query = "EXECUTE gettile(!bbox!, !zoom!, !pixel_width!);"
|
|
sent_query = replace_tokens(final_query, s, w, n, e, sani_zoom)
|
|
response = list(session.execute(sent_query))
|
|
print(sent_query)
|
|
layers = filter(None, list(itertools.chain.from_iterable(response)))
|
|
final_tile = b''
|
|
for layer in layers:
|
|
final_tile = final_tile + io.BytesIO(layer).getvalue()
|
|
return final_tile
|
|
|
|
|
|
class GetTile(tornado.web.RequestHandler):
|
|
def get(self, zoom, x, y):
|
|
self.set_header("Content-Type", "application/x-protobuf")
|
|
self.set_header("Content-Disposition", "attachment")
|
|
self.set_header("Access-Control-Allow-Origin", "*")
|
|
response = get_mvt(zoom, x, y)
|
|
self.write(response)
|
|
|
|
|
|
def m():
|
|
if __name__ == "__main__":
|
|
application = tornado.web.Application([(r"/tiles/([0-9]+)/([0-9]+)/([0-9]+).pbf", GetTile)])
|
|
print("Postserve started..")
|
|
application.listen(8080)
|
|
tornado.ioloop.IOLoop.instance().start()
|
|
|
|
|
|
m()
|