Point clouds
NOTE: swisstopo started a new LIDAR data acquisition programme in 2024. Data for the Jura national park are now available and are being used to generate new point-cloud views for the JuraMap.
The focus of the JuraMap point-cloud work is to provide three-dimensional representations that make complex scenes available on the web that are easy to recognize and understand. This is done using swisstopo's high-resolution aerial imagery and its high-accuracy and high spatial density point-cloud data collected by airborne LiDAR. Since official swisstopo LIDAR data files do not natively contain RGB data (the RGB model represents colours by combining red, green, and blue light at varying intensities) it is necessary to use matching aerial images to "colorise" swisstopo point clouds, thereby rendering a life-like, three-dimensional images of Switzerland's Jura Mountains as seen from about 500m above the surface of the Earth. This merging of images and data to colourise point clouds is more accurate and easily implemented than alternatives such as creating point clouds using photographic images or tagging point-cloud features.
A relatively less accurate version of what the JuarMap aims to achive using colourised point clouds is available at geotopo's services.geotopo.ch/lidar/ch site, albeit for the whole of switzerland.
swissSURFACE3D models all natural and man-made objects of the surface of Switzerland in the form of a classified point cloud. Zipped .laz files in the Swiss LV95 coordinate system for square areas can be downloaded for all Switzerland in 2023 and more recently at a significantly higher point density in the Cloud Optimised Point Cloud (.copc) format for the south-western area resulting from a new LIDAR data acquisition programme that started in in 2024.
swissIMAGE is an orthophoto mosaic of digital colour aerial photographs covering the whole of Switzerland with a ground resolution of 10 cm in most areas. Like swissSURFACE3D, swissIMAGE data are divided into small spatial units (essentially areas measuring one kilometre by one kilometre) that can be downloaded in the Cloud Optimized geoTIFF (COG) format.
Processing the swissSURFACE3D and swissIMAGE data to generate a colourised point cloud for each area is carried using PDAL and Entwine Python routines under a Conda open-source package and environment management system on a Ubuntu 22.004 system. A web interface to the point cloud for each area is provided by the JuraMap raster map (raster.juramap.org) using the Potree-Entwine framework pioneered by the US Geographical Service (USGS, see usgs.entwine.io).
Entwine is a data organization library which takes raw, PDAL-readable point-cloud files (such as .las, .laz or .copc) and organizes them into a multi-resolution octree structure known as the EPT ( Entwine Point Tile) format.
Potree is an open-source WebGL-based point-cloud renderer for viewing LiDAR datasets directly in a web browser. As for the USGS interface, selecting the JuraMap point-cloud feature highlights each one kilometre square area. Selecting an area brings up a link to the Potree user interface which displays the area's point cloud (see this area for the village of Saint-Cergue).
The default image shown is a swissSURFACE3D point cloud colourised using the matching swissIMAGE. Clicking the button at the top left of the Potree interface opens the menu to various tools, the most interesting being the "Attribute" section to choose a colorisation style other than "rgba", the default true colours style resulting from colourisation.
In general therefore, our implementation of a JuraMap colourised point cloud web viewer involves setting a Conda environment for PDAL and Entwine to process point-cloud data and a Potree-based interface to the data using the USGS Potree-Entwine framework.
Software
On our Ubuntu 22.04 system, install Mniconda starting with in a terminal:
- wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
Manyguides are available online, the final step being to check the installed version:
- conda --version
Then create a PDAL project environment, for example:
- mkdir /home/user/pdal
- cd /home/user/pdal
- conda create --yes -n pdalenv --channel conda-forge python pdal entwine numpy
Some colourisation routines other than the pdal approach described here require numpy, noting that we have been unable to execute these (notably) owing to mismatched libraries, mainly hdf5 and aws-c-s3.
To check, the Entwine version is given in a terminal by:
- conda list entwine
The Conda environment then needs activating:
- conda activate envpdal
Processing
For the simplest case of processing data for a single area (e.g., the swisstopo area covering the village of Saint-Cergue that is designated 2501-1144), downlaod swissSURFACE3D and swissIMAGE files for the area to a data folder (/home/user/pdal/data/stcergue/2026) and reproject both to EPSG3857, using for example:
- pdal translate data/stcergue/2026/2501-1144_2056_5728.laz data/stcergue/2026/2501-1144_3857.laz -f filters.reprojection --filters.reprojection.in_srs="EPSG:2056" --filters.reprojection.out_srs="EPSG:3857"
Create a colorized .laz file using a PDAL pipeline ("pipeline_colorize.json") to combine the swissIMAGE 2501-1144_3857.tif file and the swissSURFACE3D 2501-1144_3857.laz file:
- pdal pipeline /home/user/pdal/pipeline_colorize.json
where "pipeline_colorize.json" is:
{"pipeline": ["/home/ertert/pdal/data/stcergue/2026/2501-1144_3857.laz",
{"type": "filters.colorization", "raster": "/home/ertert/pdal/data/stcergue/2026/2501-1144_3857.tif"
}, { "type": "filters.expression", "expression": "Red >= 1"
},{ "type": "writers.las","compression": "true","minor_version": "2","dataformat_id": "3",
"filename":"/home/ertert/pdal/data/stcergue/2026/2501-1144_3857_colorized.laz"} ]}
Then convert the colourised .laz to an EPT "2501-1144_3857_colorized_colored" directory with:
- entwine build -c /home/user/pdal/stcergue/config.json
where config.json is:
{"input": "data/stcergue/2026/2501-1144_3857_colorized.laz", "output": "data/stcergue/2026/2501-1144_3857_colorized_colored", "threads": 3, "cacheSize": 2000 }
A lack of memory generally calls for a swap file, so in a terminal:
- sudo fallocate -l 16G /swapfile
- sudo chmod 600 "swapfile
- sudo mkswap /swapfile
- sudo swapon /swapfile
The EPT directory "2501-1144_3857_colorized_colored" will have three directories and the files "ept.json" and "ept-build.json".
The ept.json file is useful because its "boundsConforming" entry "[684632.0,5851143.0,975.0,686105.0,5852621.0,1221.0]" gives the elevation range spanned by the point cloud (975.0 m to 1221.0 m). The "script.js" file described below for the USGS framework to configure the Potree viewer used to view the point cloud needs this elevation range if the viewer's elevation style is to be realistic.
Web interface
The original USGS Potree-Entwine web interface had, like the current interface, a landing page (see hobuinc/usgs-lidar at github) with a map of areas covered by available point-clouds. Clicking on an area opens a popup giving a link to the Potree viewer for the area. The same approach has been adopted for the JuraMap in that clicking a square on the map corresponding to area covered by a point cloud opens a popup with a link to the viewer. This effect is achieved simply by creating a geoJSON point-cloud layer for the raster.juramap.org maplibre-gl.js client using a FeatureCollection json file ("pointclouds.json") that gives details of each point-cloud area (mainly name and geometry).
For the webpage opened on clicking, the USGS bases the page on the hobunic/usgs-lidar "view.html" page where default configuration settings for Potree are largely established in a file called "script.js".with specific settings for a particular area set in "view.html". The equivalent "view.html" webpage used for Potree as exemplified by Potree's github showcase example Lake Tahoe is to use "viewer" as the main instance object ("window.viewer" or "viewer") to configure Potree's 3D rendering canvas, camera position, point budget, EPT octree node loading, and user-interface sidebar elements.
The original, and maintained, USGS approach based on the "script.js" file is perhaps more straigtforward and transparent. The main complication is that some configuration settings that are now set using a viewer instance must be set by editing Potree's potree.js (the current version is 1.8.2). For instance, the potree.js statement "viewer.setMinNodeSize(data.minNodeSize)" must be changed to "MinNodeSize(2)" in order to set the minimum node size as 2. Fortunately these hard-copy edits are fairly rare and cause little trouble.
Not discussed here are the steps needed in order to build Potree.
Updated 4 November 2026