Skip to content

A PostGIS based Vector Tile server with caching and filtering.

License

Notifications You must be signed in to change notification settings

mkeller3/FastVector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FastVector

FastVector is a PostGIS vector tiles built for serving large geometric tables. FastVector is written in Python using the FastAPI web framework.

FastVector is built with inspriration from TiMVT.

It defers from TiMVT in the fact that it has multi server/database support, cql_filtering, and a fields parameter.


Source Code: https://github.com/mkeller3/FastVector


Requirements

FastVector requires PostGIS >= 2.4.0.

Configuration

In order for the api to work you will need to edit the config.py file with your database connections.

Example

DATABASES = {
    "data": {
        "host": "localhost", # Hostname of the server
        "database": "data", # Name of the database
        "username": "postgres", # Name of the user, ideally only SELECT rights
        "password": "postgres", # Password of the user
        "port": 5432, # Port number for PostgreSQL
        "cache_age_in_seconds": 6000, # Number of seconds for tile to be cache in clients browser. You can set to zero if you do not want any caching.
        "max_features_per_tile": 100000 # Maximum features per tile. This helps with performance for tables with a large number of rows.
    }
}

Usage

Running Locally

To run the app locally uvicorn main:app --reload

Production

Build Dockerfile into a docker image to deploy to the cloud.

API

Method URL Description
GET /api/v1/table/tables.json Tables
GET /api/v1/table/{database}/{scheme}/{table}.json Table JSON
GET /api/v1/tiles/{database}/{scheme}/{table}/{z}/{x}/{y}.pbf Tiles
GET /api/v1/tiles/{database}/{scheme}/{table}.json Table TileJSON
DELETE /api/v1/tiles/cache Delete Cache
GET /api/v1/tiles/cache_size Cache Size
GET /viewer/{database}/{scheme}/{table} Viewer
GET /api/v1/health_check Server health check: returns 200 OK

Using with Mapbox GL JS

Mapbox GL JS is a JavaScript library for interactive, customizable vector maps on the web. It takes map styles that conform to the Mapbox Style Specification, applies them to vector tiles that conform to the Mapbox Vector Tile Specification, and renders them using WebGL.

You can add a layer to the map and specify TileJSON endpoint as a vector source URL. You should also specify a source-layer property. For Table JSON it is {schema_name}.{table_name} by default.

map.addSource('points', {
  type: 'vector',
  url: `http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf`
});

map.addLayer({
  'id': 'state_centroids',
  'type': 'circle',
  'source': 'state_centroids',
  'source-layer': 'public.state_centroids',
  'paint': {
    'circle-color': 'red'
  }
});

Using with MapLibre

MapLibre is an Open-source JavaScript library for publishing maps on your websites.

map.addSource('state_centroids', {
  type: 'vector',
  url: `http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf`
});

map.addLayer({
  'id': 'points',
  'type': 'circle',
  'source': 'state_centroids',
  'source-layer': 'public.state_centroids',
  'paint': {
    'circle-color': 'red'
  }
});

Using with Leaflet

Leaflet is the leading open-source JavaScript library for mobile-friendly interactive maps.

You can add vector tiles using Leaflet.VectorGrid plugin. You must initialize a VectorGrid.Protobuf with a URL template, just like in L.TileLayers. The difference is that you should define the styling for all the features.

L.vectorGrid
  .protobuf('http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf', {
    vectorTileLayerStyles: {
      'public.state_centroids': {
        color: 'red',
        fill: true
      }
    }
  })
  .addTo(map);

Tables

Tables endpoint provides a listing of all the tables available to query as vector tiles.

Tables endpoint is available at /api/v1/table/tables.json

curl http://localhost:8000/api/v1/table/tables.json

Example Response

[
  {
    "name": "states",
    "schema": "public",
    "type": "table",
    "id": "public.states",
    "database": "data",
    "detailurl": "http://127.0.0.1:8000/api/v1/table/data/public/states.json",
    "viewerurl": "http://127.0.0.1:8000/viewer/data/public/states"
  },
  {},...

Table JSON

Table endpoint is available at /api/v1/table/{database}/{scheme}/{table}.json

For example, states table in public schema in data database will be available at /api/v1/table/data/public/states.json

curl http://localhost:8000/api/v1/table/data/public/states.json

Example Response

{
  "id": "public.states",
  "schema": "public",
  "tileurl": "http://127.0.0.1:8000/api/v1/tiles/data/public/states/{z}/{x}/{y}.pbf",
  "viewerurl": "http://127.0.0.1:8000/viewer/data/public/states",
  "properties": [
    {
      "name": "gid",
      "type": "integer",
      "description": null
    },
    {
      "name": "geom",
      "type": "geometry",
      "description": null
    },
    {
      "name": "state_name",
      "type": "character varying",
      "description": null
    },
    {
      "name": "state_fips",
      "type": "character varying",
      "description": null
    },
    {
      "name": "state_abbr",
      "type": "character varying",
      "description": null
    },
    {
      "name": "population",
      "type": "integer",
      "description": null
    }
  ],
  "geometrytype": "ST_MultiPolygon",
  "type": "table",
  "minzoom": 0,
  "maxzoom": 22,
  "bounds": [
    -178.2175984,
    18.9217863,
    -66.9692709999999,
    71.406235408712
  ],
  "center": [
    -112.96125695842262,
    45.69082939790446
  ]
}

Tiles

Tiles endpoint is available at /api/v1/tiles/{database}/{scheme}/{table}/{z}/{x}/{y}.pbf

For example, states table in public schema in data database will be available at /api/v1/table/data/public/states/{z}/{x}/{y}.pbf

Fields

If you have a table with a large amount of fields you can limit the amount of fields returned using the fields parameter.

Note

If you use the fields parameter the tile will not be cached on the server.

For example, if we only want the state_fips field.

/api/v1/table/data/public/states/{z}/{x}/{y}.pbf?fields=state_fips

CQL Filtering

CQL filtering is enabled via pygeofilter. This allows you to dynamically filter your tiles database size for larger tiles.

For example, filter the states layer to only show states with a population greater than 1,000,000.

/api/v1/table/data/public/states/{z}/{x}/{y}.pbf?cql_filter=population>1000000

Geoserver has examples of using cql filters.

Spatial Filters

Filters
Intersects
Equals
Disjoint
Touches
Within
Overlaps
Crosses
Contains

Note

If you use the cql_filter parameter the tile will not be cached on the server.

Table Tile JSON

Table TileJSON endpoint is available at /api/v1/tiles/{database}/{scheme}/{table}.json

For example, states table in public schema in data database will be available at /api/v1/tiles/data/public/states.json

curl http://localhost:8000/api/v1/tiles/data/public/states.json

Example Response

{
  "tilejson": "2.2.0",
  "name": "public.states",
  "version": "1.0.0",
  "scheme": "xyz",
  "tiles": [
    "http://127.0.0.1:8000/api/v1/tiles/data/public/states/{z}/{x}/{y}.pbf"
  ],
  "viewerurl": "http://127.0.0.1:8000/viewer/data/public/states",
  "minzoom": 0,
  "maxzoom": 22
}

Cache Delete

The cache delete endpoint allows you to delete any vector tile cache on the server.

This is a DELETE HTTP method endpoint.

In your request you have to pass the following.

{
  "database": "data",
  "scheme": "public",
  "table": "states"
}

Cache Size

Cache Size endpoint allows you to determine the size of a vector tile cache for each table.

curl http://localhost:8000/api/v1/api/v1/tiles/cache_size

Example Response

[
  {
    "table": "data_public_counties",
    "size_in_gigabytes": 0.004711238
  },
  {
    "table": "data_public_states",
    "size_in_gigabytes": 0.000034666
  }
]

Viewer

The viewer allows to preview a tile dataset in a web map viewer.

For example, you can view the states table at /viewer/data/public/states. It will automatically zoom to the extent of the table.

Viewer Image