Metadata-Version: 2.4
Name: geobridge
Version: 0.1.5
Summary: Python bridge between Copernicus Data Stores (C3S, CAMS, CEMS) and mainstream GIS operations
Project-URL: Homepage, https://github.com/ECMWFCode4Earth/GeoBridge
Project-URL: Repository, https://github.com/ECMWFCode4Earth/GeoBridge
Project-URL: Issues, https://github.com/ECMWFCode4Earth/GeoBridge/issues
Project-URL: Documentation, https://geobridge.readthedocs.io
Author: Kostas Fokeas and Ilias Machairas
License-Expression: MIT
License-File: LICENSE
Keywords: CAMS,CEMS,ERA5,GIS,WMTS,climate,copernicus,earth-observation,geotiff,zarr
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Atmospheric Science
Classifier: Topic :: Scientific/Engineering :: GIS
Requires-Python: >=3.10
Requires-Dist: pyyaml>=6.0
Provides-Extra: dev
Requires-Dist: build; extra == 'dev'
Requires-Dist: cfgrib>=0.9.10; extra == 'dev'
Requires-Dist: dask>=2023.1; extra == 'dev'
Requires-Dist: fsspec>=2023.1; extra == 'dev'
Requires-Dist: mypy>=1.8; extra == 'dev'
Requires-Dist: numpy>=1.24; extra == 'dev'
Requires-Dist: owslib>=0.28; extra == 'dev'
Requires-Dist: pyproj>=3.5; extra == 'dev'
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
Requires-Dist: pytest>=7.4; extra == 'dev'
Requires-Dist: rasterio>=1.3; extra == 'dev'
Requires-Dist: responses>=0.23; extra == 'dev'
Requires-Dist: rioxarray>=0.14; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Requires-Dist: types-pyyaml; extra == 'dev'
Requires-Dist: types-requests; extra == 'dev'
Requires-Dist: xarray>=2023.1; extra == 'dev'
Requires-Dist: zarr>=2.16; extra == 'dev'
Provides-Extra: docs
Requires-Dist: sphinx-autodoc-typehints>=1.25; extra == 'docs'
Requires-Dist: sphinx-rtd-theme>=2.0; extra == 'docs'
Requires-Dist: sphinx>=7.0; extra == 'docs'
Provides-Extra: full
Requires-Dist: cfgrib>=0.9.10; extra == 'full'
Requires-Dist: dask>=2023.1; extra == 'full'
Requires-Dist: fsspec>=2023.1; extra == 'full'
Requires-Dist: numpy>=1.24; extra == 'full'
Requires-Dist: owslib>=0.28; extra == 'full'
Requires-Dist: pyproj>=3.5; extra == 'full'
Requires-Dist: rasterio>=1.3; extra == 'full'
Requires-Dist: rioxarray>=0.14; extra == 'full'
Requires-Dist: xarray>=2023.1; extra == 'full'
Requires-Dist: zarr>=2.16; extra == 'full'
Provides-Extra: zarr
Requires-Dist: dask>=2023.1; extra == 'zarr'
Requires-Dist: fsspec>=2023.1; extra == 'zarr'
Requires-Dist: numpy>=1.24; extra == 'zarr'
Requires-Dist: rasterio>=1.3; extra == 'zarr'
Requires-Dist: rioxarray>=0.14; extra == 'zarr'
Requires-Dist: xarray>=2023.1; extra == 'zarr'
Requires-Dist: zarr>=2.16; extra == 'zarr'
Description-Content-Type: text/markdown

# GeoBridge

**Python library that bridges Copernicus Data Stores into mainstream GIS workflows.**

GeoBridge removes the technical friction GIS users face when working with
Copernicus climate, atmosphere, and emergency data. It resolves dataset
discovery, authentication, and access-method differences into a single
ergonomic API that produces analysis-ready Cloud Optimized GeoTIFFs.

The library is the foundation for the project's QGIS plugin.

---

## What it does

- **Discovery.** `gb.discover()` lists every dataset in the Copernicus
  catalogue with filters for keyword, service, variable, bounding box, and
  time range — all from a locally bundled snapshot, no network needed.
- **Authentication.** A single `gb.authenticate()` call handles credential
  resolution for the new ARCO bearer-token model.
- **Extraction — ARCO path.** `gb.zarr_to_geotiff()` pulls a spatial / temporal
  subset from the ARCO Zarr Data Lake and writes it as a Cloud Optimized
  GeoTIFF, ready for QGIS or ArcGIS.
- **Extraction — CDS API path.** `gb.cds_to_geotiff()` submits a download job
  through the standard CDS API for datasets that are not yet in the ARCO lake,
  converts the result to GeoTIFF, and streams it to disk.
- **WMTS.** `gb.wmts_layer()` returns a ready-to-use WMTS layer object for
  live tile streaming inside QGIS or Leaflet.
- **Form schema.** `gb.fetch_form()` and `gb.fetch_constraints()` retrieve the
  server-side parameter form for any dataset so your UI can build validated
  request widgets. `gb.valid_variables_for_product_type()` filters the variable
  list to what the selected product type actually supports.
- **Styling.** `gb.to_qgis_style()` generate
  calibrated colour ramps for known Copernicus variables.
- **Fusion.** `gb.fuse()` co-registers multiple layers onto a common grid
  for joint analysis (e.g. heat + air quality).
- **Semantics.** `gb.semantic_search()` resolves user themes like
  "urban heat island" or "wildfire risk" into concrete dataset and
  workflow recommendations. `gb.list_themes()` and `gb.list_use_cases()`
  enumerate the built-in vocabulary.

---

## How to run it

### Prerequisites

- **Python 3.10 or newer.** GeoBridge does not support older Python.
- **A free Copernicus account.** Register at
  https://cds.climate.copernicus.eu and copy your personal access token
  from your profile page.
- **macOS, Linux, or Windows with WSL2.** Native Windows may work but is
  not tested.

### Step 1 — Create a clean environment

A separate environment avoids dependency conflicts with anything else you
have installed. With Conda (recommended because some geospatial libraries
need compiled C bindings that pip alone struggles with):

```bash
conda create -n geobridge python=3.11 -y
conda activate geobridge
```

Or with `venv`:

```bash
python3.11 -m venv ~/.venvs/geobridge
source ~/.venvs/geobridge/bin/activate
```

### Step 2 — Install the geospatial stack

If you used Conda, install the heavy native dependencies through
conda-forge first:

```bash
conda install -c conda-forge rasterio rioxarray zarr fsspec httpio dask -y
```

This avoids the most common build failures (GDAL, PROJ, libtiff).

### Step 3 — Install GeoBridge

GeoBridge is published on PyPI: https://pypi.org/project/geobridge/

```bash
pip install "geobridge[full]"
```

The `[full]` extra adds everything: xarray/rasterio/zarr for
`zarr_to_geotiff()`, plus OWSLib (WMTS) and cfgrib (GRIB support). Use
`geobridge[zarr]` instead if you only need the ARCO extraction path, or
plain `pip install geobridge` for the lightweight core (`discover()`,
`wmts_layer()`, `to_qgis_style()`, and the semantic search functions all
work with only `pyyaml`, the sole hard runtime dependency — no extra
needed).

If you're contributing to GeoBridge itself, install from a clone in
editable mode instead so your local edits take effect immediately:

```bash
git clone https://github.com/ECMWFCode4Earth/GeoBridge
cd geobridge
pip install -e ".[dev]"
```

### Step 4 — Configure your credentials

Create `~/.cdsapirc` with your personal access token:

```
key: YOUR-CDS-API-KEY-HERE
```

Then protect the file so other users on the machine cannot read it:

```bash
chmod 600 ~/.cdsapirc
```

Alternatively, export your key as an environment variable instead of
writing it to a file:

```bash
export CDS_API_KEY=YOUR-CDS-API-KEY-HERE
```

---

## Repository layout

```
geobridge/                              ← repository root
├── README.md                           ← this file
├── LICENSE                             ← MIT
├── pyproject.toml                      ← installable Python package
├── smoke_test.py                       ← offline smoke test (9 stages)
│
├── geobridge/                          ← Python package
│   ├── __init__.py                     ← public API exports
│   ├── auth.py                         ← bearer-token authentication
│   ├── modules/
│   │   ├── discover.py                 ← catalogue discovery
│   │   ├── extract.py                  ← ARCO Zarr → GeoTIFF
│   │   ├── cds_download.py             ← CDS API → GeoTIFF (non-ARCO datasets)
│   │   ├── wmts.py                     ← WMTS layer
│   │   ├── form.py                     ← dataset form schema & constraints
│   │   ├── style.py                    ← QGIS QML export
│   │   └── fuse.py                     ← multi-layer co-registration
│   └── semantic/
│       ├── engine.py                   ← rule-based query resolver
│       ├── vocabulary.yaml             ← themes and use cases
│       ├── arco_overrides.yaml         ← Zarr URLs and variable aliases
│       ├── arco_snapshot.yaml          ← ARCO catalogue snapshot (generated)
│       └── cds_snapshot.yaml           ← STAC catalogue snapshot (generated)
│
├── scripts/
│   ├── refresh_catalogue.py            ← maintainer-side CDS STAC refresh
│   └── refresh_arco_catalogue.py       ← maintainer-side ARCO snapshot refresh
│
├── examples/
│   ├── athens_urban_heat.py            ← end-to-end ERA5 demo
│   ├── example_utci.py                 ← UTCI thermal comfort demo
│   ├── examplepm2.5.py                 ← CAMS PM2.5 air quality demo
│   └── ...                             ← additional live-test scripts
│
└── tests/
    ├── test_auth.py
    └── unit/                           ← pytest unit tests
        ├── test_discover.py
        ├── test_auth.py
        ├── test_extract.py
        ├── test_style.py
        ├── test_semantic.py
        └── test_wmts.py
```

---

## Maintainer workflow

### Refreshing catalogue snapshots

The `cds_snapshot.yaml` and `arco_snapshot.yaml` files are regenerated
periodically from the live ECMWF catalogues. End users never run these
scripts; they get the snapshots bundled with whatever GeoBridge version
they install.

To refresh the CDS STAC snapshot (maintainers only):

```bash
python scripts/refresh_catalogue.py --limit 5 --output /tmp/test.yaml   # quick test
python scripts/refresh_catalogue.py                                      # full run
git diff geobridge/semantic/cds_snapshot.yaml
git add geobridge/semantic/cds_snapshot.yaml
git commit -m "Refresh CDS catalogue snapshot"
```

To refresh the ARCO snapshot:

```bash
python scripts/refresh_arco_catalogue.py
git add geobridge/semantic/arco_snapshot.yaml
git commit -m "Refresh ARCO catalogue snapshot"
```

### Adding a new ARCO dataset

1. Visit the dataset page on https://cds.climate.copernicus.eu and open
   the "Analysis ready data" tab.
2. Copy the Zarr URLs (typically there are two: `time_chunked` and
   `geo_chunked`).
3. Verify each URL responds with a 200 status:

   ```bash
   curl -I -H "Authorization: Bearer $CDS_API_KEY" "https://.../.zmetadata"
   ```

4. Add an entry to `geobridge/semantic/arco_overrides.yaml` following the
   schema of existing entries.
5. Add the variable aliases (CDS long-form name → ARCO short-form name)
   by inspecting the Zarr store with `xarray.open_zarr()` and listing
   `ds.data_vars`.

---

## License

MIT. See `LICENSE`.

---

## Acknowledgements
