A static webmap for GRANULAR built with
gridviz. First layer is the
Landscape Attractiveness raster from IIASA
(Zenodo 18618619); the project is
structured so further pan-European gridded layers can be added by dropping
tiles into public/data/ and appending to src/layers.js.
Published at https://iiasa.github.io/granular/.
.
├── index.html # Vite entry point
├── vite.config.js # base path = /granular/ for GH Pages
├── src/
│ ├── main.js # map init, layer wiring, sidebar UI
│ ├── layers.js # layer registry — edit this to add new layers
│ └── style.css
├── public/data/ # tiles (served as-is by Vite → copied to docs/)
├── scripts/
│ ├── tile_raster.py # TIF → EPSG:3035 → gridviz tiled-grid format
│ └── requirements.txt
└── .github/workflows/
└── deploy.yml # build + publish to GitHub Pages
The source raster is ETRS89 / UTM 32N (EPSG:4647) at 1 km. The script
reprojects it to EPSG:3035 (LAEA Europe, the Eurostat standard) and emits a
multi-resolution pyramid — each resolution becomes its own TiledGrid.
uv venv && source .venv/bin/activate
uv pip install -r scripts/requirements.txt
python scripts/tile_raster.py \
--resolutions 1000 2000 5000 10000 \
--format parquet
# → public/data/landscape_attractiveness/{1000m,2000m,5000m,10000m}/Tiles are checked into git (small enough) so the GH Pages workflow doesn't have to re-run the Python pipeline. Re-run the script only when the source dataset changes.
npm install
npm run dev
# open http://127.0.0.1:8765npm run build produces docs/ with the base path pinned to /granular/
(override with VITE_BASE=/ npm run build for a custom domain). docs/ is
committed so GitHub Pages can serve it directly from the branch.
-
Produce tiles with the same pipeline under
public/data/<your-layer>/<res>m/. -
Append an entry to
src/layers.js:{ id: "my_layer", title: "My layer", resolutions: [{ res: 5000, url: "data/my_layer/5000m/" }, ...], column: "value", valueDomain: [0, 100], palette: ["#...", "#..."], unit: "…", }
The sidebar toggle and legend wire up automatically. The url is relative
to the document — Vite serves public/ at the site root, so
data/my_layer/5000m/ resolves correctly in both dev and the GH Pages build.
The .github/workflows/deploy.yml workflow rebuilds docs/ on every push
to main and commits it back. GitHub Pages serves the folder directly.
One-time setup:
- Settings → Pages → Build and deployment → Source: Deploy from a
branch → Branch:
main//docs. - Settings → Actions → General → Workflow permissions: Read and write
(so the workflow can push the rebuilt
docs/back tomain). - Push to
main; the workflow commits the build, and the site goes live athttps://<user>.github.io/<repo>/.
Custom domain? Put it in public/CNAME and build with
VITE_BASE=/ npm run build (or set VITE_BASE as a repo variable).
<iframe
src="https://iiasa.github.io/granular/?embed=1"
title="GRANULAR landscape attractiveness"
width="100%"
height="640"
style="border:0"
loading="lazy"
referrerpolicy="no-referrer-when-downgrade">
</iframe>?embed=1 hides the project chrome (sidebar) so only the map surface is
visible — the host page can provide its own layer controls later by posting
messages to the iframe, or by pointing at a per-layer URL.
- Source: Hofer, M. (IIASA, 2024). Landscape Attractiveness – Europe-wide Prediction. doi:10.5281/zenodo.18618619. CC-BY 4.0.
- Model values are an ordinal 0–6 rating (0 = not very aesthetic, 6 = very naturally aesthetic). NoData = -99 is dropped during tiling.
- CRS for the webmap is EPSG:3035; the basemap is the Eurostat GISCO Positron tileset in the same projection.