问题
I'm trying to create vector tiles from a PostgreSQL database and serve them via flask to a Leaflet map. I've followed this medium.com article which got me nearly all the way.
However, when i open the page with the Leaflet map on it I get the following in the browser console:
index.js:191 Uncaught Error: Unimplemented type: 4 at Pbf.skip (index.js:191) at Pbf.readFields (index.js:41) at new VectorTile$1 (vectortile.js:8) at FileReader. (Leaflet.VectorGrid.Protobuf.js:124)
to create the tiles I use the below:
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
query = """SELECT ST_AsMVT(tile) FROM (SELECT id, 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 "TimeZone (LineGridExp)") AS tile"""
cursor = db.connection.cursor()
cursor.execute(query,(xmin,ymin,xmax,ymax))
tile = str(cursor.fetchone()[0])
cursor.close()
return tile
@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
To add tiles to leaflet i use:
var url = "http://localhost:5000/tiles/{z}/{x}/{y}"
var mapillaryLayer = L.vectorGrid.protobuf(url).addTo(mymap);
The python end receives GET from the client and doesn't throw any errors. However I'm not sure about the SQL query and detecting empty tiles or whether the query is simply wrong.
Any help would be greatly appreciated.
Tom
回答1:
It was all a matter of the query not returning data and also returning as Bytes and not str:
def get_tile(z,x,y):
xmin, ymin = tile_ul(x, y, z)
xmax, ymax = tile_ul(x + 1, y + 1, z)
query = """SELECT ST_AsMVT(tile) FROM (
SELECT id, ST_AsMVTGeom(geom, ST_MakeEnvelope( %s, %s, %s, %s ,4326), 4096, 256, false ) geom
FROM reproject ) as tile"""
cursor = db.connection.cursor()
cursor.execute(query,(xmin,ymin,xmax,ymax))
tile = bytes(cursor.fetchone()[0])
cursor.close()
return tile
来源:https://stackoverflow.com/questions/60765560/postgresql-st-asmvt-to-vectortiles-to-leaflet-layer