Simple Mapbox Vector Tiles (MVT) server with Flask and PostGIS.
MVT are a simple and conveniant way to share geodata using webmap or GIS software.
For webmap : instead GeoJson file, MVT are loaded on the fly, so you can easly add maplayer with hundreds of geometry. Geometry are generalized in higher zoom.
For GIS : Recents releases of QGIS natively support MVT, which can be used like WFS.
Clone the repo, create a virtual python environment and install requierements
git clone git@github.com:jbdesbas/vectipy.git
cd vectipy
virtualenv -p python3 venv
source venv/bin/activate
pip install -r requirements.txt
Create a .env file with your credentials or export them
export PG_HOST=my_db_host
export PG_PORT=5432
export PG_DATABASE=my_db_name
export PG_USER=my_db_user
export PG_PASSWORD=my_db_password
Enjoy !
python vectipy.py run -p 5000
Use following routes
- http://localhost:5000/ Show availables layers
- http://localhost:5000/MY_LAYER.json TileJSON file
- http://localhost:5000/MY_LAYER/{z}/{x}/{y}.pbf Tiles endpoints
- http://localhost:5000/map/MY_LAYER Layer preview
- http://localhost:5000/map/MY_LAYER.geojson GeoJson file (for download or webmap)
Notes
- Add a geometry index on each layer greatly improve performances (
CREATE INDEX my_layer_geom_3857_idx ON my_layer USING GIST (ST_Transform(geom, 3857))
); - Preview only avaible for constrained geometry type (see https://postgis.net/docs/using_postgis_dbmanagement.html#Manual_Register_Spatial_Column )
- Install gunicorn (
pip install gunicorn
) and usegunicorn vectipy:app
for production
Tables with a geometric column are automatically serverd by Vectipy. I suggest to disable this in config.toml and explicitly configure layers that you want to serve.
You can define Layers or Collections (multi-layers tiles)
[[collection]] #a multi-layers tileset
name = "my_multilayers_tiles" #the collection name, used in tiles url
[[collection.layer]]
name = "first_layer" #layer name (published name, used for style definition)
table_name = "table1" #database table name
minzoom = 14 #OPTIONAL
maxzoom = 20 #OPTIONAL
columns = [ "id", "label"] #OPTIONAL published columns (default : all columns)
geometry_column = "geom" #geometry column (default : geom)
[[collection.layer]]
name = "second_layer"
table_name = "table2"
[[layers]] #a single-layer tileset
table_name = "my_single_layer"
name = "my_table"
- Easy to deploy MVT (pbf) server
- TileJson metadata
- Frontend preview with MapLibre GL
- Serve GeoJSON file
- Cache system
- OGC API Features (WFS 3) server https://www.ogc.org/standards/ogcapi-features