The vector tile schema is the formal contract between the Python ETL pipeline and the MapLibre GL JS frontend. Every census section feature published inDocumentation 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.
galicia_scouting.mbtiles must expose exactly these 11 properties — no more, no fewer. The ETL (process_data.py) is responsible for computing and writing them; the frontend reads them directly from the tile at render time via GPU expressions. If a column is missing or misnamed, MapLibre silently treats it as undefined (numerically 0), which produces a flat gray map with no visible error.
Schema
Ten-digit census section code. Format:
CCPP(2) + MMM(3) + DDD(3) + SS(2).CC— province code:15(A Coruña),27(Lugo),32(Ourense),36(Pontevedra)PP— combined with CC to form the 2-digit NUTS provinceMMM— municipality code (3 digits, zero-padded)DDD— district code (3 digits, zero-padded)SS— section number within the district (2 digits)
1500101001 → A Coruña, municipality 001, district 001, section 01.Min-Max normalized net mean household income, computed over all ~3,800 Galician census sections. Source: INE Atlas de Renta. Used by the GPU scoring expression.
Net mean household income in euros (non-normalized absolute value). Example:
24500. Displayed in the section tooltip; not used in GPU scoring.Normalized population density (inhabitants per km²), computed over all sections in Galicia using Min-Max normalization. Area in km² is calculated in ETRS89 (EPSG:25830) before reprojection.
Normalized percentage of the section’s population aged under 20. Source: IGE population indicators by census section.
Normalized percentage of the section’s population aged over 64. Source: IGE population indicators by census section.
Total number of inhabitants in the census section. Example:
3200. Displayed in the tooltip; not used in GPU scoring.Log-normalized commercial activity density — the number of OSM commercial establishments per km², passed through
log(1 + x) before Min-Max normalization. See Scoring Formula for the full normalization rationale. Source: OpenStreetMap Galicia (Geofabrik).Raw count of commercial establishments (OSM POIs: shops, restaurants, offices, services) within the census section. Example:
45. Displayed in the tooltip as 45 estab.Normalized ratio of buildings with commercial or office use (
5_retail, 4_office, 3_industrial in Catastro coding) to total buildings in the section. Source: Catastro Vectorial, building layer, currentUse field.Normalized building modernity — higher values indicate newer building stock. Computed as
minmax_norm(mean_construction_year) applied directly to the mean construction year, so sections with more recently built stock score higher. Source: Catastro Vectorial, FECHAALTA / beginning field.Naming Conventions
Two consistent suffixes are used throughout the schema:| Suffix | Meaning | Range | Used by |
|---|---|---|---|
_norm | Min-Max (or log) normalized value, dimensionless | [0.0, 1.0] | GPU scoring expression, MapLibre interpolation |
_abs | Absolute value in its natural unit (€, inhabitants, establishments) | Unbounded | Tooltip display only |
_norm columns satisfy this requirement: they are pre-computed at ETL time for the entire Galicia dataset, so the GPU never needs to know the original scale of any variable. The _abs columns exist purely for human-readable display in the sidebar tooltip.
Example Feature Properties
The following JSON object is what MapLibre exposes to paint expressions and click event handlers for a single census section feature:.pbf tile binary at tile-generation time by Tippecanoe. They are not fetched from a server on demand — they travel with the tile and are decoded in the browser.
MVP data availability: In the minimum viable product, OSM and Catastro data may not be processed. In that case,
actividad_norm, actividad_abs, uso_comercial_norm, and antiguedad_norm are set to 0.0 / 0 for all sections. Their sliders remain visible and functional in the UI, but moving them produces no visual variation in the map because every section scores equally on those dimensions. Full variation becomes visible once those ETL phases are run and the .mbtiles file is regenerated.Post-ETL Quality Assertions
The following checks are executed insidevalidate_output() at the end of process_data.py, before Tippecanoe is invoked to generate the .mbtiles file. The pipeline raises a ValueError and aborts if any check fails.
< 1500 threshold is a conservative floor that catches catastrophically failed runs (e.g., a geometry filter that silently drops all sections) without blocking partial runs where not all provinces are available. The zero-percentage diagnostic described in the specs is informational: a high proportion of zeros is expected for OSM/Catastro columns in MVP mode, but unexpected for renta_norm or densidad_norm.