108 lines
3.6 KiB
Markdown
108 lines
3.6 KiB
Markdown
# RF Propagation API
|
|
|
|
HTTP API for radio visibility, terrain profiles, Fresnel/LOS checks, link budget,
|
|
viewshed, and coverage calculations.
|
|
|
|
This repository follows `SPEC.md`. The first implementation pass creates the full
|
|
service skeleton, pure RF/math kernels, and Copernicus DEM sampling. Integrations
|
|
that require PostGIS data, pycraf, ITM/P.1812, landcover/canopy rasters, or
|
|
external viewshed binaries are exposed through stable interfaces and return
|
|
explicit "not implemented" responses until the corresponding data pipeline is
|
|
connected.
|
|
|
|
## Layout
|
|
|
|
- `api/` - FastAPI service, core calculations, service orchestration, tests.
|
|
- `scripts/` - data bootstrap/import entry points.
|
|
- `data/` - mounted data volume for DEM, landcover, and canopy rasters.
|
|
- `docker-compose.yml` - local stack with API, worker, Redis, PostGIS, optional tiler.
|
|
- `API.md` - current HTTP endpoints, examples, and implementation status.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
docker compose up --build api redis postgis
|
|
```
|
|
|
|
The API is served at `http://localhost:${API_PORT:-5603}`, with OpenAPI docs at `/docs`.
|
|
|
|
## DEM Bootstrap
|
|
|
|
Download Copernicus DEM GLO-30 COG tiles for Saint Petersburg and Leningrad Oblast:
|
|
|
|
```bash
|
|
python scripts/bootstrap_dem.py --bbox 27.3,58.4,35.8,61.4 --output-dir data/dem
|
|
docker compose restart api worker
|
|
```
|
|
|
|
The API samples all `.tif`/`.tiff` files under `DEM_PATH` recursively. In Docker,
|
|
the default `DEM_PATH=/data/dem` points to the mounted `./data/dem` directory.
|
|
|
|
## Buildings Bootstrap
|
|
|
|
Download an OSM PBF extract and import building polygons into PostGIS:
|
|
|
|
```bash
|
|
mkdir -p data/osm
|
|
wget -O data/osm/northwestern-fed-district-latest.osm.pbf \
|
|
https://download.geofabrik.de/russia/northwestern-fed-district-latest.osm.pbf
|
|
sh scripts/load_buildings.sh data/osm/northwestern-fed-district-latest.osm.pbf
|
|
docker compose restart api worker
|
|
```
|
|
|
|
The script builds a local `radio-osm2pgsql:latest` image from
|
|
`scripts/Dockerfile.osm2pgsql` on first run. It imports the PBF through standard
|
|
`osm2pgsql` tables, then normalizes `planet_osm_polygon` into the API `buildings`
|
|
table with `db/sql/normalize_buildings.sql`.
|
|
|
|
The import writes a `buildings` table with `geom`, `height_m`, `levels`,
|
|
`building_type`, and `source`. Heights come from `height`, then
|
|
`building:levels * 3.0`, then an estimated default by building type.
|
|
|
|
Check the API:
|
|
|
|
```bash
|
|
curl -s -X POST http://localhost:5603/api/v1/buildings/query \
|
|
-H 'Content-Type: application/json' \
|
|
-d '{"bbox":[30.30,59.93,30.33,59.95]}' | jq '.features | length'
|
|
```
|
|
|
|
Check data availability and run a minimal integration smoke test:
|
|
|
|
```bash
|
|
curl -s http://localhost:5603/api/v1/status/data | jq
|
|
API_BASE=http://localhost:5603 sh scripts/smoke_api.sh
|
|
```
|
|
|
|
## Landcover And Canopy
|
|
|
|
Place ESA WorldCover GeoTIFF/COG files under `data/landcover` and optional canopy
|
|
height GeoTIFF/COG files under `data/canopy`, then restart the API:
|
|
|
|
```bash
|
|
python scripts/bootstrap_landcover.py --bbox 27.3,58.4,35.8,61.4 --landcover-dir data/landcover
|
|
docker compose restart api worker
|
|
```
|
|
|
|
Or download manually into `data/landcover` and `data/canopy`.
|
|
|
|
The `/api/v1/landcover/path` endpoint samples all `.tif`/`.tiff` files under
|
|
`LANDCOVER_PATH` recursively. Canopy data is optional; when it is missing,
|
|
`canopy_height_m` is returned as `null`.
|
|
|
|
When WorldCover is available, `/api/v1/link/budget` and `/api/v1/terrain/los`
|
|
can include P.833 vegetation attenuation. Tune the coefficients with
|
|
`P833_GAMMA_DB_PER_M` and `P833_MAX_ATTENUATION_DB` in `.env`.
|
|
|
|
For local Python development:
|
|
|
|
```bash
|
|
cd api
|
|
python -m venv .venv
|
|
source .venv/bin/activate
|
|
pip install -e ".[dev]"
|
|
python -m pytest
|
|
python -m ruff check .
|
|
```
|