This guide walks you through running UrbanViable on your own machine. By the end you will have the ETL pipeline producing a normalised GeoJSON for Galicia, an optional MBTiles file served by TileServer GL, and the React frontend live atDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/danizd/urbanviable/llms.txt
Use this file to discover all available pages before exploring further.
http://localhost:5173.
Prerequisites
Make sure the following tools are installed before you begin:- Python 3.11+ with
geopandas,pandas,shapely, andosmiumavailable (install viapip install -r etl/requirements.txt) - Node.js 18+ (the frontend uses Vite 6 and React 18)
- Docker (optional) — only needed if you want to run TileServer GL for the full vector-tile stack
- Tippecanoe — only needed to regenerate the
.mbtilesfile from the processed GeoJSON
In development mode the frontend loads
galicia_scouting.geojson directly
from the frontend/public/ directory using a standard fetch() call.
No tileserver is required to run the app locally. Docker and Tippecanoe
are only needed when you want to reproduce the full production tile pipeline
or run the two-container Docker stack.Steps
Clone the repository and set up your environment
Clone the repository and copy the example environment file:Open
For local development
.env and review the values. The file contains the following variables:| Variable | Default | Description |
|---|---|---|
DOMAIN | tu-dominio.com | Production domain name |
ENVIRONMENT | production | Deployment environment |
CORS_ORIGIN | https://tu-dominio.com | Allowed CORS origin for TileServer GL |
REACT_APP_TILE_URL | https://tu-dominio.com/tiles | Tile endpoint the frontend fetches from |
REACT_APP_DATA_STATUS_URL | https://tu-dominio.com/api/status | URL for the last_update.json data-status manifest |
REACT_APP_LAYER_NAME | secciones | MapLibre layer name for census section polygons |
REACT_APP_SOURCE_NAME | galicia-scouting | TileServer GL tileset key |
REACT_APP_TILE_URL is overridden automatically by
start.bat (set to /tiles) so the frontend proxies tile requests to the
local TileServer GL container.Run the ETL pipeline
The ETL script downloads raw data from CNIG, INE, OSM, and Catastro,
reprojects and joins everything on the 10-digit Output:
The script also writes
CUSEC census key, applies
Min-Max normalisation, and writes the result to disk.etl/data/processed/galicia_scouting.geojsonThis GeoJSON contains one feature per Galician census section (~3,800
features) with the following columns:| Column | Type | Description |
|---|---|---|
cusec | string | 10-digit census section code |
renta_norm | float [0,1] | Normalised mean net household income |
densidad_norm | float [0,1] | Normalised population density |
jovenes_norm | float [0,1] | Normalised share of population under 20 |
mayores_norm | float [0,1] | Normalised share of population over 64 |
actividad_norm | float [0,1] | Normalised POI density (log-scaled) |
uso_comercial_norm | float [0,1] | Normalised commercial/industrial building ratio |
antiguedad_norm | float [0,1] | Normalised mean building age (newer = higher) |
renta_abs | float | Raw mean net household income (€) |
poblacion_abs | int | Raw population count |
actividad_abs | int | Raw POI count |
etl/data/processed/last_update.json with a
timestamp and data-vintage metadata displayed by the frontend.Generate vector tiles (optional — needed for Docker stack only)
If you want to run the full Docker production stack or test tile serving
locally, convert the GeoJSON to an MBTiles file with Tippecanoe:Output:
tiles_data/galicia_scouting.mbtilesThe script calls Tippecanoe with zoom levels 6–14 and packages all features
into a single layer named secciones. The resulting file is typically
15–40 MB. TileServer GL will serve this file as .pbf tiles under
/data/galicia-scouting/{z}/{x}/{y}.pbf.Copy the generated GeoJSON into frontend/public/ so the dev server can
serve it directly:Start the application
Choose between the lightweight frontend dev server (no Docker needed) or
the full two-container Docker stack.The Vite dev server starts at This starts two containers:
Option A — Frontend dev server only (recommended for development)
http://localhost:5173. It loads
galicia_scouting.geojson directly from frontend/public/ — no tileserver
process required.Option B — Full Docker stack (production-equivalent)
Make sure you have built the frontend first (npm run build inside
frontend/) and that tiles_data/galicia_scouting.mbtiles exists. Then:| Service | URL | Description |
|---|---|---|
urbanviable-tiles | http://localhost:8080 | TileServer GL — serves .pbf vector tiles |
urbanviable-web | http://localhost:3002 | Nginx — serves the React production build and proxies /tiles/ to TileServer GL |
What you should see
After completing the steps above:- Frontend dev server — open
http://localhost:5173in your browser. The map of Galicia loads with all census sections rendered in grey (all slider weights default to their initial values fromvariables.js). Move any slider to see the heatmap update in real time. - TileServer GL (Docker only) —
http://localhost:8080/data/galicia-scouting.jsonreturns the tileset metadata JSON, confirming the.mbtilesfile is loaded correctly. - Click a census section — a tooltip appears showing the section code (
CUSEC), mean income, and population. The sidebar reflects the weighted score for that section.
Next steps
Architecture
Understand the two-container Docker setup and the full data flow from ETL
output to GPU-rendered heatmap.
ETL Overview
Deep dive into every transformation step, the normalisation logic, and how
to update data sources.