Last active
July 23, 2024 14:42
-
-
Save giohappy/9b4768ce0dbf92d74b36e615cb12bfa4 to your computer and use it in GitHub Desktop.
OL + Flask + PostGIS for MVT rendering
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
from __future__ import unicode_literals | |
import os | |
import shutil | |
import math | |
import psycopg2 | |
from flask import Flask, render_template, make_response | |
app = Flask(__name__) | |
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) | |
CACHE_DIR = os.path.join(BASE_DIR,'cache') | |
def tile_ul(x, y, z): | |
n = 2.0 ** z | |
lon_deg = x / n * 360.0 - 180.0 | |
lat_rad = math.atan(math.sinh(math.pi * (1 - 2 * y / n))) | |
lat_deg = math.degrees(lat_rad) | |
return lon_deg,lat_deg | |
def get_tile(z,x,y): | |
xmin,ymin = tile_ul(x, y, z) | |
xmax,ymax = tile_ul(x + 1, y + 1, z) | |
tile = None | |
tilefolder = "{}/{}/{}".format(CACHE_DIR,z,x) | |
tilepath = "{}/{}.pbf".format(tilefolder,y) | |
if not os.path.exists(tilepath): | |
conn = psycopg2.connect('dbname=geo24 user=geo password=geo host=localhost') | |
cur = conn.cursor() | |
query = "SELECT ST_AsMVT(tile) FROM (SELECT id, name, ST_AsMVTGeom(geom, ST_Makebox2d(ST_transform(ST_SetSrid(ST_MakePoint(%s,%s),4326),3857),ST_transform(ST_SetSrid(ST_MakePoint(%s,%s),4326),3857)), 4096, 0, false) AS geom FROM admin_areas) AS tile" | |
cur.execute(query,(xmin,ymin,xmax,ymax)) | |
tile = str(cur.fetchone()[0]) | |
if not os.path.exists(tilefolder): | |
os.makedirs(tilefolder) | |
with open(tilepath, 'wb') as f: | |
f.write(tile) | |
f.close() | |
cur.close() | |
conn.close() | |
else: | |
tile = open(tilepath, 'rb').read() | |
return tile | |
@app.route('/') | |
def index(): | |
return render_template('index.html') | |
@app.route('/tiles') | |
@app.route('/tiles/<int:z>/<int:x>/<int:y>', methods=['GET']) | |
def tiles(z=0, x=0, y=0): | |
tile = get_tile(z, x, y) | |
response = make_response(tile) | |
response.headers['Content-Type'] = "application/octet-stream" | |
return response | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes, changing to bytes worked for me.