delta-relief
High-resolution surface analysis with LiDAR data.
See lidar.cubetrek.com for access to the dataset.
Introduction
Airborne LiDAR uses hundreds of thousands of laser pulses per second to generate detailed 3D maps, even through vegetation. With high point densities and 10 cm accuracy, it is among the most effective methods for mapping topography.
Source SwissTopo
The Swiss Federal Office of Topography (Swisstopo) provides a highly precise digital elevation model based on LiDAR data, called swissALTI3D. Buildings and vegetation are removed, revealing the underlying topography.
The data is delivered as a GeoTIFF tiles with 2000px × 2000px resolution representing 1km × 1km areas (resolution of 0.5m). The full list of all tiles is provided here.
LiDAR has some interesting use cases in archaeology (Caspari, 2023), particularly for uncovering man-made structures that are hidden beneath vegetation or subtle terrain changes. It allows archaeologists to identify features such as ancient roads, walls, building foundations, and agricultural terraces that may be invisible to the naked eye or conventional aerial photography.
Goal of this Project
This project aims to improve accessibility to the data in two main steps:
- Visualize the SwissTopo data as images that highlight subtle terrain changes for easier interpretation
- Deploy the data in an interactive, mobile-friendly online map
This data is accessible on https://lidar.cubetrek.com
The online map allows to quickly pan to the current location via GPS and switch between three different map layers (LiDAR, this project; Aerial View and Map View, data from SwissTopo).
Points of Interest
Some examples of interesting features in Switzerland, click the LiDAR image to open the viewer.
Note
Help me extend this list! Send a pull request or mail to: contact@cubetrek.com if you know of any other interesting examples.
Colm La Runga
Remains of a roman camp sitting at an altitude of 2200 m ASL. Likely around 15 BC, marking the start of the Roman occupation of this area of the Alps.
The camp was discovered in 2024, and was partly an inspiration of this project, as LiDAR data was also used to help in the discovery.
Sources:
- Picture source: Kanton Graubünden
- Swiss Info: Remains of Roman camp discovered in eastern Switzerland
- Swiss Info: Swiss Roman battle site reveals hidden secrets of historic clash
Rohanschanze (Rohan's fortification)
Built during the Thirty Years' War (1635) by the French Duke of Rohan. Only the earthwork remains.
Sources:
La Bonneville
Deserted settlement. Founded in the 13th century to attract settlers, destroyed in 1301.
Sources:
- La Bonneville
- Picture source: Arcinfo
- Suggested by u/itchibli on Reddit
Franc Castel
A castle built in the 14th century, destroyed in 1536. Remnants were used as a quarry to build the neighboring farm houses.
Sources:
Chartreuse d'Oujon
Monastery built in 1146, set on fire in 1537 during the Reformation.
Sources:
- Oujon Charterhouse, Wiki
- Picture Tourism Nyon
Kloster Mariaberg
Monastery (nunnery) first time mentioned in 1248, closed after 1259.
Sources:
- Gemeinde Kilchberg Neujahrsblatt
- Kirchenmann Otto hat die Gemeinde Kilchberg geprägt, German
- Suggested by /u/greg_gl on Reddit
Sternenschanze
A fortification used during the Sonderbund War (1847) by the Protestant Confederates against Schwyz (Sonderbund). Built likely earlier (First Villmerger Krieg, 1656). The nearby pond was created later in 1873
See also the Bellenschanze and Hüttnerschanze.
Sources:
- Die zürcherischen Schanzen an der schwyzerischen Grenze, German
- Ein Archäologe spürt historischen Stätten nach, German
- Drawing: Villmergerkriege
- Suggested by /u/N3XT191 on Reddit
Cresta Settlement in Cazis
Bronze Age settlement situated on a hilltop, the settlement was continuously inhabited for approximately 500 to 600 years during the Early to Middle Bronze Age (circa 2000–1300 BCE). Excavations have uncovered multiple layers of occupation, revealing structures such as post-built houses, hearths, and storage pits.
Sources:
Grossholz burial mounds
Burial grounds of the Iron Age (800-450 BCE), another one can be found 1km southwest.
Sources:
Langenthal burial mounds
Burial grounds of the Iron Age (800-450 BCE), also used during the Roman and Early Medieval Ages.
Sources:
Châtel d'Arrufens
Bronze age settlement, 1450 to 1200 BCE.
Sources:
Canal d'Entreroches
During the Thirty Years War Protestant Netherlands wanted to have access to the Mediterranean sea without the dangerous journey around Catholic Spain. The Canal d'Entreroche was the most ambitious part trying to connect (North Sea -> Rhine River -> Aare River) Lake Neuchâtel to Lake Geneva (-> Rhone -> Mediterranean Sea). Construction started in 1638 and stopped ten years later without ever being completed.
The idea became popular again in the 20th Century under the Name "Transhelvetique Canal", but was never further pursued.
Sources:
Narrow-gauge train line "Winkeln - Herisau"
Narrow gauge train track connecting Winkeln and Herisau. Opened in 1875, abandoned in 1913.
Sources:
- Museum Appenzeller Bahnen
- Suggested by u/BezugssystemCH1903 on Reddit
Castle Rotenberg
Wooden castle from the early 13th century, featuring a raised earthed mound (motte castle).
Source:
Technical Details
Visualization of LiDAR data
The figures below are created in the Visualization trials Jupyter Notebook.
To demonstrate how to display subtle terrain changes in the best way, we use two examples: the Rohanschanze on the left illustrates clearly visible earthworks in flat terrain, while the Colm La Runga on the right highlights more subtle features in a mountainous landscape.
The input data consists of absolute elevation values (height above sea level). A basic way to visualize this is as a grayscale gradient-black representing the lowest and white the highest altitude within each tile.
While the fort is visible, the Roman camp gets completely lost in the surrounding mountainous terrain.
In scientific visualizations, elevation data is often rendered using hillshading.
This produces a natural-looking terrain representation, but it requires significant tuning to make subtle features visible, especially in hilly terrain. (I couldn't manage for the Roman camp). So it's not ideal for our purposes.
Our focus is not on absolute elevation but on detecting subtle terrain variations.
To achieve this, we compute the slope at each point: an approximation of the first derivative along both axes.
This yields significantly finer details, and the Roman camp becomes clearly visible (centered in the lower left quadrant).
To enhance subtle variations even further, we apply a non-linear transformation to the slope values: fine gradients are exaggerated while steeper slopes remain mostly unchanged.
This strikes a good balance: broad features remain visible, and fine details become much clearer. In mountainous areas, the output becomes brighter overall, but with some getting used to, more structure can be perceived.
We can also go a step further and run another differentiation (basically a second derivative), in the hope to uncover more details.
However, this primarily amplifies noise and yields no real improvement.
Going back to the first derivative, we can apply a colormap to encode the slope magnitude.
This approach works well in relatively flat regions (e.g. the first example), but becomes visually overwhelming in complex, mountainous terrain, where everything tends to shift towards red.
Hosting the data
mbtileserver provides an easy way to host mbtiles so that they can be used as a map layer in MapLibre JS.
To create the mbtiles file, we
- run the create_geotiff.py script to download the GeoTiffs, convert the data as described above and save it as GeoTiff again
- use GDAL to build the mbtiles file while converting the GeoTIFF from LV95 (the Swiss coordinates system) to Web Mercator (EPSG:3857).
gdalbuildvrt -a_srs EPSG:2056 lv95.vrt calculated/*.tif
gdalwarp -s_srs EPSG:2056 -t_srs EPSG:3857 -tap -tr 0.5 0.5 -r bilinear -co COMPRESS=DEFLATE -co TILED=YES -co BIGTIFF=YES lv95.vrt webmerc.tif
gdal_translate -of MBTILES webmerc.tif lidar.mbtiles
gdaladdo -r average lidar.mbtiles 2 4 8 16
Add an index to the mbtile (sqlite3) file to help mbtileserver get the tiles:
sqlite3 lidar.mbtiles "CREATE UNIQUE INDEX IF NOT EXISTS tiles_xyz_index ON tiles (zoom_level, tile_column, tile_row);"
NGINX is used as a reverse proxy to relay between the client and the mbtileserver and also to host the static index file, that uses MapLibre JS.










































