{"id":33202093,"url":"https://github.com/mkeller3/FastVector","last_synced_at":"2025-11-21T03:00:50.032Z","repository":{"id":38203891,"uuid":"506452095","full_name":"mkeller3/FastVector","owner":"mkeller3","description":"A PostGIS based Vector Tile server with caching and filtering.","archived":false,"fork":false,"pushed_at":"2022-07-08T21:06:36.000Z","size":125,"stargazers_count":49,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-07-12T22:12:19.184Z","etag":null,"topics":["asyncpg","fastapi","leaflet","mapbox","mapbox-vector-tile","maplibre","postgis","postgres","postgresql","python","tile-server","tiles","vector-tiles"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mkeller3.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-23T00:56:06.000Z","updated_at":"2024-07-05T07:43:55.000Z","dependencies_parsed_at":"2022-08-09T00:00:37.555Z","dependency_job_id":null,"html_url":"https://github.com/mkeller3/FastVector","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mkeller3/FastVector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkeller3%2FFastVector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkeller3%2FFastVector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkeller3%2FFastVector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkeller3%2FFastVector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mkeller3","download_url":"https://codeload.github.com/mkeller3/FastVector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mkeller3%2FFastVector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":285548627,"owners_count":27190487,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-21T02:00:06.175Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asyncpg","fastapi","leaflet","mapbox","mapbox-vector-tile","maplibre","postgis","postgres","postgresql","python","tile-server","tiles","vector-tiles"],"created_at":"2025-11-16T09:00:28.687Z","updated_at":"2025-11-21T03:00:50.022Z","avatar_url":"https://github.com/mkeller3.png","language":"Python","readme":"# FastVector\n\nFastVector is a [PostGIS](https://github.com/postgis/postgis) [vector tiles](https://github.com/mapbox/vector-tile-spec) built for serving large geometric tables. FastVector is written in [Python](https://www.python.org/) using the [FastAPI](https://fastapi.tiangolo.com/) web framework. \n\nFastVector is built with inspriration from [TiMVT](https://github.com/developmentseed/timvt).\n\nIt defers from TiMVT in the fact that it has multi server/database support, cql_filtering, and a fields parameter.\n\n---\n\n**Source Code**: \u003ca href=\"https://github.com/mkeller3/FastVector\" target=\"_blank\"\u003ehttps://github.com/mkeller3/FastVector\u003c/a\u003e\n\n---\n\n## Requirements\n\nFastVector requires PostGIS \u003e= 2.4.0.\n\n## Configuration\n\nIn order for the api to work you will need to edit the `config.py` file with your database connections.\n\nExample\n```python\nDATABASES = {\n    \"data\": {\n        \"host\": \"localhost\", # Hostname of the server\n        \"database\": \"data\", # Name of the database\n        \"username\": \"postgres\", # Name of the user, ideally only SELECT rights\n        \"password\": \"postgres\", # Password of the user\n        \"port\": 5432, # Port number for PostgreSQL\n        \"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.\n        \"max_features_per_tile\": 100000 # Maximum features per tile. This helps with performance for tables with a large number of rows.\n    }\n}\n```\n\n## Usage\n\n### Running Locally\n\nTo run the app locally `uvicorn main:app --reload`\n\n### Production\nBuild Dockerfile into a docker image to deploy to the cloud.\n\n## API\n\n| Method | URL                                                                              | Description                                             |\n| ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------- |\n| `GET`  | `/api/v1/table/tables.json`                                                            | [Tables](#tables)               |\n| `GET`  | `/api/v1/table/{database}/{scheme}/{table}.json`                                 | [Table JSON](#table-json)         |\n| `GET`  | `/api/v1/tiles/{database}/{scheme}/{table}/{z}/{x}/{y}.pbf`                      | [Tiles](#tiles)    |\n| `GET`  | `/api/v1/tiles/{database}/{scheme}/{table}.json`                                  | [Table TileJSON](#table-tile-json) |\n| `DELETE` | `/api/v1/tiles/cache`                                                               | [Delete Cache](#cache-delete)  |\n| `GET`  | `/api/v1/tiles/cache_size`                                                             | [Cache Size](#cache-size) |\n| `GET`  | `/viewer/{database}/{scheme}/{table}`                                            | [Viewer](#viewer)               |\n| `GET`  | `/api/v1/health_check`                                                           | Server health check: returns `200 OK`            |\n\n## Using with Mapbox GL JS\n\n[Mapbox GL JS](https://github.com/mapbox/mapbox-gl-js) is a JavaScript library for interactive, customizable vector maps on the web. It takes map styles that conform to the\n[Mapbox Style Specification](https://www.mapbox.com/mapbox-gl-js/style-spec), applies them to vector tiles that\nconform to the [Mapbox Vector Tile Specification](https://github.com/mapbox/vector-tile-spec), and renders them using\nWebGL.\n\nYou 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](#table-json) it is `{schema_name}.{table_name}` by default.\n\n```js\nmap.addSource('points', {\n  type: 'vector',\n  url: `http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf`\n});\n\nmap.addLayer({\n  'id': 'state_centroids',\n  'type': 'circle',\n  'source': 'state_centroids',\n  'source-layer': 'public.state_centroids',\n  'paint': {\n    'circle-color': 'red'\n  }\n});\n```\n\n\n## Using with MapLibre\n[MapLibre](https://maplibre.org/projects/maplibre-gl-js/) is an Open-source JavaScript library for publishing maps on your websites. \n\n```js\nmap.addSource('state_centroids', {\n  type: 'vector',\n  url: `http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf`\n});\n\nmap.addLayer({\n  'id': 'points',\n  'type': 'circle',\n  'source': 'state_centroids',\n  'source-layer': 'public.state_centroids',\n  'paint': {\n    'circle-color': 'red'\n  }\n});\n```\n\n## Using with Leaflet\n\n[Leaflet](https://github.com/Leaflet/Leaflet) is the leading open-source JavaScript library for mobile-friendly interactive maps.\n\nYou can add vector tiles using [Leaflet.VectorGrid](https://github.com/Leaflet/Leaflet.VectorGrid) plugin. You must initialize a [VectorGrid.Protobuf](https://leaflet.github.io/Leaflet.VectorGrid/vectorgrid-api-docs.html#vectorgrid-protobuf) with a URL template, just like in L.TileLayers. The difference is that you should define the styling for all the features.\n\n```js\nL.vectorGrid\n  .protobuf('http://localhost:8000/api/v1/tiles/data/public/state_centroids/{z}/{x}/{y}.pbf', {\n    vectorTileLayerStyles: {\n      'public.state_centroids': {\n        color: 'red',\n        fill: true\n      }\n    }\n  })\n  .addTo(map);\n```\n\n## Tables\nTables endpoint provides a listing of all the tables available to query as vector tiles.\n\n\nTables endpoint is available at `/api/v1/table/tables.json`\n\n```shell\ncurl http://localhost:8000/api/v1/table/tables.json\n```\n\nExample Response\n```json\n[\n  {\n    \"name\": \"states\",\n    \"schema\": \"public\",\n    \"type\": \"table\",\n    \"id\": \"public.states\",\n    \"database\": \"data\",\n    \"detailurl\": \"http://127.0.0.1:8000/api/v1/table/data/public/states.json\",\n    \"viewerurl\": \"http://127.0.0.1:8000/viewer/data/public/states\"\n  },\n  {},...\n```\n\n## Table JSON\n\nTable endpoint is available at `/api/v1/table/{database}/{scheme}/{table}.json`\n\nFor example, `states` table in `public` schema in `data` database will be available at `/api/v1/table/data/public/states.json`\n\n```shell\ncurl http://localhost:8000/api/v1/table/data/public/states.json\n```\n\nExample Response\n```json\n{\n  \"id\": \"public.states\",\n  \"schema\": \"public\",\n  \"tileurl\": \"http://127.0.0.1:8000/api/v1/tiles/data/public/states/{z}/{x}/{y}.pbf\",\n  \"viewerurl\": \"http://127.0.0.1:8000/viewer/data/public/states\",\n  \"properties\": [\n    {\n      \"name\": \"gid\",\n      \"type\": \"integer\",\n      \"description\": null\n    },\n    {\n      \"name\": \"geom\",\n      \"type\": \"geometry\",\n      \"description\": null\n    },\n    {\n      \"name\": \"state_name\",\n      \"type\": \"character varying\",\n      \"description\": null\n    },\n    {\n      \"name\": \"state_fips\",\n      \"type\": \"character varying\",\n      \"description\": null\n    },\n    {\n      \"name\": \"state_abbr\",\n      \"type\": \"character varying\",\n      \"description\": null\n    },\n    {\n      \"name\": \"population\",\n      \"type\": \"integer\",\n      \"description\": null\n    }\n  ],\n  \"geometrytype\": \"ST_MultiPolygon\",\n  \"type\": \"table\",\n  \"minzoom\": 0,\n  \"maxzoom\": 22,\n  \"bounds\": [\n    -178.2175984,\n    18.9217863,\n    -66.9692709999999,\n    71.406235408712\n  ],\n  \"center\": [\n    -112.96125695842262,\n    45.69082939790446\n  ]\n}\n```\n\n## Tiles\n\nTiles endpoint is available at `/api/v1/tiles/{database}/{scheme}/{table}/{z}/{x}/{y}.pbf`\n\nFor example, `states` table in `public` schema in `data` database will be available at `/api/v1/table/data/public/states/{z}/{x}/{y}.pbf`\n\n### Fields\n\nIf you have a table with a large amount of fields you can limit the amount of fields returned using the fields parameter.\n\n#### Note\n\nIf you use the fields parameter the tile will not be cached on the server.\n\nFor example, if we only want the `state_fips` field.\n\n`/api/v1/table/data/public/states/{z}/{x}/{y}.pbf?fields=state_fips`\n\n### CQL Filtering\n\nCQL filtering is enabled via [pygeofilter](https://pygeofilter.readthedocs.io/en/latest/index.html). This allows you to dynamically filter your tiles database size for larger tiles.\n\nFor example, filter the states layer to only show states with a population greater than 1,000,000.\n\n`/api/v1/table/data/public/states/{z}/{x}/{y}.pbf?cql_filter=population\u003e1000000`\n\n[Geoserver](https://docs.geoserver.org/stable/en/user/tutorials/cql/cql_tutorial.html) has examples of using cql filters.\n\n#### Spatial Filters\n\n| Filters | \n| --- |\n| Intersects |\n| Equals |\n| Disjoint |\n| Touches |\n| Within |\n| Overlaps |\n| Crosses |\n| Contains |\n\n#### Note\n\nIf you use the cql_filter parameter the tile will not be cached on the server.\n\n## Table Tile JSON\n\nTable [TileJSON](https://github.com/mapbox/tilejson-spec) endpoint is available at `/api/v1/tiles/{database}/{scheme}/{table}.json`\n\nFor example, `states` table in `public` schema in `data` database will be available at `/api/v1/tiles/data/public/states.json`\n\n```shell\ncurl http://localhost:8000/api/v1/tiles/data/public/states.json\n```\n\nExample Response\n```json\n{\n  \"tilejson\": \"2.2.0\",\n  \"name\": \"public.states\",\n  \"version\": \"1.0.0\",\n  \"scheme\": \"xyz\",\n  \"tiles\": [\n    \"http://127.0.0.1:8000/api/v1/tiles/data/public/states/{z}/{x}/{y}.pbf\"\n  ],\n  \"viewerurl\": \"http://127.0.0.1:8000/viewer/data/public/states\",\n  \"minzoom\": 0,\n  \"maxzoom\": 22\n}\n```\n\n## Cache Delete\nThe cache delete endpoint allows you to delete any vector tile cache on the server.\n\nThis is a DELETE HTTP method endpoint.\n\nIn your request you have to pass the following.\n\n```json\n{\n  \"database\": \"data\",\n  \"scheme\": \"public\",\n  \"table\": \"states\"\n}\n```\n\n## Cache Size\nCache Size endpoint allows you to determine the size of a vector tile cache for each table.\n\n```shell\ncurl http://localhost:8000/api/v1/api/v1/tiles/cache_size\n```\n\nExample Response\n```json\n[\n  {\n    \"table\": \"data_public_counties\",\n    \"size_in_gigabytes\": 0.004711238\n  },\n  {\n    \"table\": \"data_public_states\",\n    \"size_in_gigabytes\": 0.000034666\n  }\n]\n```\n\n## Viewer\nThe viewer allows to preview a tile dataset in a web map viewer. \n\nFor example, you can view the states table at `/viewer/data/public/states`. It will automatically zoom to the extent of the table.\n\n\n\n![Viewer Image](/images/viewer_demo.png \"Viewer Image\")\n","funding_links":[],"categories":["Servers"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkeller3%2FFastVector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmkeller3%2FFastVector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmkeller3%2FFastVector/lists"}