Metadata-Version: 2.4
Name: openrelief
Version: 0.1.0
Summary: Red-shaded terrain relief (the Red Relief Image Map / RRIM technique) from Digital Elevation Models, with parallel CPU and optional GPU acceleration.
Author-email: Naveen <nvnsudharsan@gmail.com>
License: MIT
Project-URL: Homepage, https://github.com/nvnsudharsan/openrelief
Project-URL: Repository, https://github.com/nvnsudharsan/openrelief
Project-URL: Issues, https://github.com/nvnsudharsan/openrelief/issues
Keywords: red relief,RRIM,DEM,topographic openness,terrain,hillshade,lidar,GIS,raster,visualization
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: GIS
Classifier: Topic :: Scientific/Engineering :: Visualization
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy>=1.21
Requires-Dist: rasterio>=1.3
Requires-Dist: scipy>=1.7
Requires-Dist: joblib>=1.4
Requires-Dist: Pillow>=9.0
Provides-Extra: gpu
Requires-Dist: cupy-cuda12x; extra == "gpu"
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Dynamic: license-file

# openrelief — red-shaded terrain relief from DEMs

`openrelief` turns any Digital Elevation Model into a **red-shaded relief image**
that combines topographic slope with positive/negative **topographic openness** —
the visualization widely known as the *Red Relief Image Map* (RRIM). Give it a
DEM (or a folder/glob of DEM tiles) and it produces a seamless georeferenced RGB
GeoTIFF plus a PNG preview.

> **Note on naming and IP.** This is an independent, open-source reimplementation
> of a published method. The package is intentionally named `openrelief` and
> avoids the *RRIM* / *Red Relief Image Map* trademarks as branding. The RRIM
> method was developed and patented by Asia Air Survey Co., Ltd.; those patents
> appear to have expired, but you should verify this yourself before publishing
> or commercializing. See [NOTICE](NOTICE) for attribution, citation, trademark
> and patent details, and [LICENSE](LICENSE) for the code license.

* **Any DEM** rasterio can read: GeoTIFF, USGS `.dem`, ERDAS `.img`, ArcInfo
  `.asc`, `.bil/.flt`, SRTM `.hgt`, `.vrt`, … — CRS, no-data, pixel size and
  elevation unit are all read from the file, nothing is hard-coded.
* **Seamless mosaics** — multiple tiles are stitched through an in-memory VRT and
  processed in overlapping windows (a halo equal to the openness radius), so
  there are no seams at tile boundaries.
* **Parallel** across windows on the CPU (joblib) and **GPU-accelerated**
  automatically when [CuPy](https://cupy.dev) + a CUDA device are present.
* **Fully tunable** — every visual knob (openness radius, slope clip, gammas,
  blend opacity, …) is exposed, with defaults matching the classic look.

---

## How the image is built

For every cell the package computes:

1. **Slope** (degrees) → red saturation. Flat = white `(255,255,255)`, steep =
   pure red `(255,0,0)`.
2. **Topographic openness** (Yokoyama et al., 2002) in `--directions` azimuths
   out to `--radius` pixels: positive openness (high on ridges) and negative
   openness (high in valleys).
3. **Differential openness** `(positive − negative) / 2` → brightness. Ridges
   render light, valleys dark — this gives the floating-3D relief.
4. The grey openness layer is **multiply-blended** onto the red slope layer at
   `--opacity` (0.5 by default). Method reference: Chiba, Kaneta & Suzuki (2008).

Horizontal distances are converted to **ground metres** automatically (linear
unit for projected CRSs; degrees→metres at the scene latitude for geographic
CRSs), so the relief is geometrically correct for any projection. If your
elevation unit differs from the horizontal unit, set `--z-factor` (e.g. `0.3048`
for feet-Z over metre-XY).

---

## Install

```bash
pip install -e .            # from this folder
```

Core deps: `numpy`, `rasterio`, `scipy`, `joblib`, `Pillow`.

**GPU (optional):** install the CuPy wheel for your CUDA toolkit, e.g.

```bash
pip install cupy-cuda12x        # CUDA 12.x   (or cupy-cuda11x)
```

When CuPy and a GPU are present the GPU is used automatically. Check with:

```bash
openrelief --check-gpu
```

---

## Command line

```bash
# Single DEM
openrelief dem.tif -o relief.tif

# A whole folder of tiles -> one seamless mosaic + preview
openrelief /path/to/dems/ -o area_relief.tif

# A glob, tuned for flat terrain, forced GPU
openrelief "tiles/*.dem" -o relief.tif --slope-max 15 --openness-range 12 --radius 40 --gpu
```

Useful options (`openrelief -h` for all):

| Option | Meaning | Default |
|---|---|---|
| `--radius` | openness search length (px) | 30 |
| `--directions` | azimuths sampled (4/8/16) | 8 |
| `--openness-range` | diff-openness deg → black..white | 30 |
| `--slope-max` | slope deg → full red | 50 |
| `--slope-gamma` / `--openness-gamma` | tone curves | 1.0 |
| `--opacity` | openness layer blend (0..1) | 0.5 |
| `--z-factor` | elevation→ground unit multiplier | 1.0 |
| `--window` | processing window (px) | 2048 |
| `--jobs` | CPU workers (-1 = all cores) | -1 |
| `--auto-window` | size windows from the core count | off |
| `--tiles-per-core` | with `--auto-window`, tiles/core (1 = one tile per processor) | 4 |
| `--gpu` / `--cpu` | force a backend | auto |
| `--compress` | deflate/lzw/zstd/none | deflate |
| `--no-preview` / `--preview-size` | PNG quick-look | on / 4000 |

**Tuning tip:** flatter terrain wants smaller `--slope-max` and
`--openness-range` (more contrast); rugged terrain wants larger values. A larger
`--radius` broadens the relief but costs ~linearly more compute.

---

## Python API

```python
from openrelief import ReliefConfig, relief_from_dems, relief_array

# High-level: DEM(s) -> GeoTIFF + PNG
relief_from_dems("tiles/", "out.tif",
                 ReliefConfig(openness_radius=40, slope_max=20))

# Low-level: a NumPy elevation array -> (3, H, W) uint8 relief
import numpy as np
rgb = relief_array(dem_array, res_x=1.0, res_y=1.0,
                   cfg=ReliefConfig(openness_radius=24))
```

`ReliefConfig` carries every parameter above; `use_gpu=None/True/False` controls
the backend. You can also force a backend globally with the
`OPENRELIEF_BACKEND=cpu|gpu` environment variable.

---

## How it scales

Cost is roughly `O(8 · radius · pixels)`. The raster is split into independent
`--window`-sized tiles with a `radius`-pixel halo:

* **CPU:** windows are distributed over processes with joblib and streamed to the
  output as they finish, so memory stays bounded regardless of mosaic size. By
  default there are more windows than cores so a freed worker immediately picks
  up the next one (dynamic load balancing). `--auto-window` instead sizes the
  windows from the core count: `--tiles-per-core 1` gives one tile per
  processor (simplest, but prone to stragglers and high per-worker memory),
  while the default of 4 keeps every core fed. The pixels produced are identical
  either way — only the scheduling changes.
* **GPU:** windows are streamed to the device sequentially; the per-window size
  keeps GPU memory in check while still giving a large speed-up.

Output GeoTIFFs are tiled and compressed (`BIGTIFF=IF_SAFER`), so very large
mosaics are handled gracefully. Empty windows in a sparse mosaic are skipped.

---

## Attribution & citation

This package reimplements published methods. Please credit the original authors;
full details and references are in [NOTICE](NOTICE).

* Chiba, T., Kaneta, S., & Suzuki, Y. (2008). *Red relief image map: new
  visualization method for three-dimensional data.* ISPRS Archives,
  XXXVII(B2), 1071–1076.
* Yokoyama, R., Shirasawa, M., & Pike, R. J. (2002). *Visualizing topography by
  openness.* PE&RS 68(3), 257–265.
* Asia Air Survey — https://www.rrim.jp/en/

## License

Source code: MIT (see [LICENSE](LICENSE)). The MIT license covers this code only
and is not a patent grant; see [NOTICE](NOTICE) for the intellectual-property
note.
