HORAYZON
Package to efficiently compute terrain parameters (like horizon, sky view factor, topographic openness, slope angle/aspect) from high-resolution digital elevation model (DEM) data. The package also allows to compute shadow maps and correction factors for downwelling direct shortwave radiation for specific sun positions.
Install / Use
/learn @ChristianSteger/HORAYZONREADME
HORAYZON
Package to efficiently compute terrain parameters (like horizon, sky view factor, topographic openness, slope angle/aspect) from high-resolution digital elevation model (DEM) data. The package also allows to compute shadow maps and correction factors for downwelling direct shortwave radiation for specific sun positions. Horizon computation is based on the high-performance ray-tracing library Intel© Embree. Calculations are parallelised with Threading Building Blocks (C++ code).
When you use HORAYZON, please cite:
Steger, C. R., Steger, B. and Schär, C. (2022): HORAYZON v1.2: an efficient and flexible ray-tracing algorithm to compute horizon and sky view factor, Geosci. Model Dev., 15, 6817–6840, https://doi.org/10.5194/gmd-15-6817-2022
and
Please refer to the sections Known issues and Support and collaboration in case you encounter any issues with HORAYZON.
The animation below illustrates the method applied in HORAYZON to find the terrain horizon for individual azimuth directions. Note that for performance reasons, HORAYZON determines the horizon for the first azimuth direction with a binary search (in contrast to the animation).

Package dependencies
HORAYZON depends on multiple external libraries and packages. The essential ones are listed below under Core dependencies. Further dependencies are needed to run the examples (Base dependencies for examples). The examples horizon/gridded_curved_DEM_masked.py, horizon/gridded_planar_DEM_2m.py and shadow/gridded_curved_DEM_NASADEM.py require more complex dependencies, which are listed under All dependencies for examples.
Core dependencies
- Intel Embree and Threading Building Blocks (TBB)
- Python packages: Cython, NumPy, SciPy, GeographicLib, tqdm, requests, xarray
Base dependencies for examples
- Python packages: netCDF4, Matplotlib, Pillow, Skyfield, pyproj, IPython
All dependencies for examples (masking and high-resolution DEM examples; GDAL dependency)
- Python packages: Shapely, fiona, scikit-image, Rasterio, Trimesh
- heightmap meshing utility (hmm)
Installation
HORAYZON has been tested with Python 3.13.3 (Linux) and Python 3.13.3 (Mac OS X). It is recommended to install dependencies via Conda, which covers all dependencies except hmm. Alternatively, HORAYZON can also be installed without Conda (by e.g. using pip to install Python packages). Installation via Conda can be accomplished as follows for different platforms:
Linux / Mac OS X
Create an appropriate Conda environment
Core dependencies
conda create -n horayzon_core -c conda-forge embree tbb-devel cython setuptools numpy scipy geographiclib tqdm requests xarray
Base dependencies for examples
conda create -n horayzon_base -c conda-forge embree tbb-devel cython setuptools numpy scipy geographiclib tqdm requests xarray netcdf4 matplotlib pillow skyfield pyproj ipython
All dependencies for examples (masking and high-resolution DEM examples; GDAL dependency)
conda create -n horayzon_all -c conda-forge embree tbb-devel cython setuptools numpy scipy geographiclib tqdm requests xarray netcdf4 matplotlib pillow skyfield pyproj ipython shapely fiona scikit-image rasterio trimesh
and activate this environment. The HORAYZON package can then be installed with:
git clone https://github.com/ChristianSteger/HORAYZON.git
cd HORAYZON
python -m pip install .
Windows
The installation under Windows has not yet been tested.
Optional installation of hmm
hmm depends on glm, which can also be installed via Conda
conda install -c conda-forge glm
Alternatively, glm can also be built manually from source. hmm can then be downloaded with
git clone https://github.com/fogleman/hmm.git
cd hmm
The following two lines in hmm's Makefile might have to be adapted to (the include directory in the first line is valid in case glm was installed with Conda):
COMPILE_FLAGS = -std=c++11 -flto -O3 -Wall -Wextra -Wno-sign-compare -march=native -lGL -lglut -lGLEW -I<path to directory 'include' of conda environment>
INSTALL_PREFIX = <binary install path>
Finally, hmm can be installed with
make
make install
Installation without Conda
HORAYZON can also be built without Conda but this requires some additional manual steps. If not already available, the following two external libraries Intel Embree and Threading Building Blocks (TBB) have to be installed. This can be done either via a package manager (APT, MacPorts, etc.) or by manually building them from source. Afterwards, the required Python packages have to be installed (for instance with pip) and the HORAYZON package can be downloaded:
git clone https://github.com/ChristianSteger/HORAYZON.git
cd HORAYZON
The setup file setup_manual.py must then be adapted to specify the include and library paths for the external libraries and to select a compiler to build HORAYZON. Finally, the HORAYZON package can be installed with:
mv setup_manual.py setup.py
python -m pip install .
Usage
The usage of the packages is best illustrated by means of examples, which can either be run in a Python IDE (like PyCharm or Spyder) or in the terminal. To run the examples, the path path_out must be adapted in the example script to a location that provides enough disk space. For the example horizon/gridded_planar_DEM_2m.py, the path to the hmm executable (hmm_ex) has to be additionally adapted. All input DEM or auxiliary data required for running the examples is downloaded automatically. When HORAYZON tries to download auxiliary data for the first time, a local path for the data has to be provided by the user. This path is saved in the text file path_aux_data.txt, which is stored in the directory to which the HORAYZON package was installed. In case this path is unknown, it can be found by running
import horayzon
print(horayzon.__file__)
in Python. If the auxiliary data is later on moved manually to a new directory, the path in path_aux_data.txt has to be adapted accordingly.
Examples: Terrain parameters (slope, horizon and sky view factor)
Two terrain horizon functions are available, horizon_gridded() and horizon_locations(). The former function allows to compute horizon for gridded input while the latter allows to compute horizon for arbitrary selected locations. The second function can optionally output the distance to the horizon. The following five examples are provided:
- horizon/gridded_curved_DEM.py: Compute topographic parameters from SRTM (geodetic coordinates, ~90 m resolution) for a ~50x50 km example region in the European Alps. Earth's surface curvature is considered. Plot output of this script is shown below.

- horizon/gridded_planar_DEM.py: Compute topographic parameters from swisstopo DHM25 (map projection, 25 m resolution) for a ~25x40 km example region in Switzerland. Earth's surface curvature is neglected.
- horizon/locations_curved_DEM.py: Compute topographic parameters (additionally distance to horizon) from SRTM (geodetic coordinates, ~90 m resolution) for 11 locations in Switzerland. Earth's surface curvature is considered. Plot output of this script for one location is shown below.

- horizon/gridded_curved_DEM_masked.py: Compute topographic parameters from SRTM (geodetic coordinates, ~90 m resolution) for South Georgia in the South Atlantic Ocean. Earth's surface curvature is considered. DEM grid cells, which are at least 20 km apart from land, are masked to speed-up horizon computation.
- horizon/gridded_planar_DEM_2m.py: Compute gridded topographic parameters from swissALTI3D (map projection, 2 m resolution) for a 3x3 km example region in Switzerland. Earth's surface curvature is neglected. The outer DEM domain is simplified and represented by a triangulated irregular network (TIN) to reduce the large memory footprint of the DEM data.
A remark on sky view factor and related parameters<br/> The term sky view factor (SVF) is defined ambiguously in literature. In Zakšek et al. (2011), it refers to the solid angle of the (celestial) hemisphere. We call this parameter visible sky fraction and its computation is performed with the function topo_param.visible_sky_fraction(). In applications related to radiation, the SVF is typically defined as the fraction of sky radiation received at a certain location in case of isotropic sky radiation (see e.g. Helbig et al., 2009). This parameter is called sky view factor in our application and its computation is performed with the function topo_param.sky_view_factor(). Additionally, the positive topographic openness (Yokoyama et al., 2002) can be computed with the function topo_param.topographic_openness().
Examples: Shadow map and shortwave correction factor
The module shadow allows to compute shadow maps and correction factors for downwelling direct shortwave radiation for arbitrary terrains and sun positions. This module
