Skip to content

Repository files navigation

TerraSelect

License: Apache 2.0 Python 3.11+

TerraSelect is a modular geospatial site-suitability scorer. It overlays public EU datasets (land cover, terrain, power infrastructure, water bodies, regional R&D, protected areas, internet exchanges, …) onto a grid of candidate cells, scores each layer independently with a customizable rule, and combines the layers into a single suitability surface that you can explore interactively.

It was originally built to study where AI Gigafactories could plausibly land in Europe — see the accompanying blog post: "AI Gigafactories: Europe's €20B Race and the Site Selection Challenge".

What's in here

  • Streamlit explorer — interactive map; pick layers, adjust weights, click cells for score breakdowns.
  • CLI — batch generation of per-layer score grids (.gpkg); grid combination.
  • 15+ loaders — one Python file per data source, each with its own scoring rule (distance decay, attribute weighting, normalisation). Add a new one by subclassing Loader.
  • Docker — one image bundles app + dependencies; data is mounted at runtime so you don't rebuild for data updates.

Quick start

git clone https://github.com/nicofirst1/terraselect.git
cd terraselect
poetry install

You now have the code but no data. See the Data section for what to download.

Data

TerraSelect does not bundle the upstream datasets. Each loader either downloads its dataset on first use or expects you to place the raw file at a configured path under data_mount/.

The canonical list of sources, licenses, download URLs, and required attributions lives in ATTRIBUTION.md.

Pre-built score grids

Re-downloading every upstream dataset and running build-grid for every layer × map is several hours of work. Pre-built bundles are published as GitHub Releases — the latest is v0.1.0-data. Each bundle ships 19 of the 23 layers (the ai_gigafactories* proposal layers and ixp_proximity are omitted for licensing reasons; regenerate locally if needed).

# Pick the map you want — germany is smallest and quickest to try
curl -LO https://github.com/nicofirst1/terraselect/releases/download/v0.1.0-data/terraselect-grids-germany-v0.1.0.tar.zst
tar -xf terraselect-grids-germany-v0.1.0.tar.zst
rsync -av terraselect-grids-germany-v0.1.0/data_mount/ data_mount/

Bundle sizes: germany ~11 MB, eu ~11 MB, eu_highres ~240 MB. The Streamlit reader prefers .parquet and falls back to .gpkg, so pre-built and locally-computed layers can coexist in the same data_mount/.

The bundles are a Collective Database — each layer retains its upstream license, with share-alike (ODbL) attaching only to the OSM-derived transmissionlines layer. See the bundle's MANIFEST.md for the full per-layer license matrix.

AI Gigafactory proposals (not bundled)

The ai_gigafactories* loaders read candidate-site coordinates from a CSV that is not redistributed with TerraSelect — the underlying list was compiled by a journalist and shared on the condition that it not be re-published. To enable these layers, supply your own CSV at data_mount/proposals/gigafactory_proposals.csv with columns name,lat,lon,exact. See the docstring in src/terraselect/loaders/giga_factories_proposals.py and the corresponding row in ATTRIBUTION.md for the source citation. If the CSV is absent the rest of TerraSelect runs normally without those layers.

Usage

Interactive Streamlit app

poetry run streamlit run src/terraselect/app/main.py

Then open http://localhost:8501. The app expects pre-computed .gpkg score grids under data_mount/score_grid/ (see next section).

Build score grids

Generate one score grid per layer per map extent. The result is cached as a GeoPackage under data_mount/score_grid/<layer>_<map>.gpkg and consumed by the Streamlit app.

poetry run terraselect build-grid --layer universities --map germany
poetry run terraselect build-grid --layer powerplants_all --map eu

Run poetry run terraselect --help to list every command. Available layer names are the keys of ALL_AVAILABLE_LAYERS in src/terraselect/loaders/__init__.py.

Combine grids

poetry run terraselect combine-grids grid1.gpkg grid2.gpkg --grid-alphas 0.7,0.3

Docker

Pre-built multi-arch images (linux/amd64, linux/arm64) are published to GitHub Container Registry on every tagged release and on every push to main (as :edge):

docker run -p 8501:8501 --rm \
    -v /absolute/path/to/your/data_mount:/app/data_mount \
    ghcr.io/nicofirst1/terraselect:latest

Or build the image locally:

docker build -t terraselect-app .
docker run -p 8501:8501 --rm \
    -v /absolute/path/to/your/data_mount:/app/data_mount \
    terraselect-app

Open http://localhost:8501. The container reads .gpkg files from the bind-mounted directory, so updating a grid on the host means restarting the container — no rebuild needed. Override the in-container data path with -e TERRASELECT_DATA_PATH=/custom/path.

Project structure

src/terraselect/
├── app/         Streamlit application (main.py is the entry point)
├── cli.py       CLI command definitions (entry point: `terraselect`)
├── core/        Grid definitions, loader base class, score breakdown
├── loaders/     One module per data source; subclass Loader to add new ones
├── evaluation/  Offline analysis pipelines (gigafactory comparison, predictors)
├── main.py      Library facade: ALL_AVAILABLE_LAYERS, run_build_grid, …
├── utils/       Checkpoint manager, grid combining, normalisation helpers
└── visualization/  Folium / matplotlib helpers (legacy build-viz output)
resources/streamlit/   Per-layer markdown descriptions shown in the sidebar
hpc/                   SLURM submission template (Barnard cluster example)
data_mount/            Runtime data — gitignored; not in the public repo
documents/             Design notes and the original gigafactory case study

Contributing

Issues and PRs welcome. Two areas where help is especially useful:

  1. New loaders — adding a public EU dataset that improves the suitability signal (e.g., excess grid capacity, fibre backhaul, water rights). Use loaders/universities.py as a template.
  2. License-respecting data bundles — re-publishing pre-built score grids under licenses compatible with the upstream sources (see ATTRIBUTION.md).

License

Code: Apache License 2.0 — see LICENSE. Data: each upstream source carries its own license — see ATTRIBUTION.md.

About

Modular EU geospatial site-suitability scorer for AI Gigafactories — Streamlit + CLI, 15+ public-dataset loaders

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages