générer un cache 'terrain' depuis un MNT et l'utiliser comme relief dans cesium/mapstore2

154 views
Skip to first unread message

Landry Breuil

unread,
Feb 13, 2023, 8:29:59 AM2/13/23
to georchestra-dev
Hello,

je pensais avoir déjà fait un retour sur la liste, mais je ne retrouve
rien dans les archives.. donc j'ai du oublier.

cas d'utilisation: avoir un 'beau' relief dans la vue 3d de mapstore.

par défaut dans ms2-georchestra on utilise le terrainProvider avec un
type 'ellipsoid' cf
https://github.com/georchestra/datadir/blob/master/mapstore/configs/localConfig.json#L33
mais avec ça, le globe est une boule, c'est pas très beau. Y'a des
sources de terrain 'libres' mais pas super bien définies.

pour avoir bien mieux, on peut utiliser un cache pyramidé (même principe
que le WMTS) de terrain de type 'cesium' crée depuis un MNT - ici
uniquement sur la région AURA, c'est la config du viewer cesium sur
https://ids.craig.fr/mapstore/, et j'ai moins de 12Go de cache sur la
région entière avec 17 niveaux de zoom (200Go avec le niveau 18 depuis
le rge alti 1m):

"terrainProvider": {
"type": "cesium",
"url": "https://3d.craig.fr/terrain",
"requestVertexNormals": true
}

pour générer ce cache, j'ai bidouillé pas mal mais assez rapidement j'ai
eu qqch de probant en utilisant un fork de ctb-tile (ctb pour
cesium-terrain-builder) supportant 'quantized mesh', cf
https://www.linkedin.com/pulse/fast-cesium-terrain-rendering-new-quantized-mesh-output-alvaro-huarte/
https://github.com/tum-gis/cesium-terrain-builder-docker et/ou
https://github.com/ahuarte47/cesium-terrain-builder/tree/master-quantized-mesh

requestvertexnormals c'est pour avoir de l'ombrage, il faut utiliser
l'option -N de ctb-tile (-N, --vertex-normals Write 'Oct-Encoded
Per-Vertex Normals' for Terrain Lighting, only for `Mesh` format)

en gros les étapes:
- faire (avec gdalwarp ou gdal_translate) un gros tif monobande en
EPSG:4326 avec son MNT (on peut utiliser un VRT en source mais ca sera
bien plus lent)

gdalwarp -s_srs epsg:2154 -t_srs epsg:4326 -r bilinear -of GTiff
/data/wxs/mnt/ign/bdalti/BDALTIV2_25M.tiff
/data/wxs/mnt/ign/bdalti/BDALTIV2_25M_4326.tiff

- faire un premier ctb-tile pour générer les tuiles

ctb-tile -f Mesh -C -N -c 4 -o /tmp/cache -s 14 -e 11
/data/wxs/mnt/ign/bdalti/BDALTIV2_25M_4326.tiff

- faire un 2e ctb-tile avec -l pour générer le 'layer.json' qui sera lu
par cesium (en gros c'est l'index du dallage, cf
https://3d.craig.fr/terrain/layer.json)

ctb-tile -f Mesh -C -N -c 4 -l -o /tmp/cache -s 14 -e 11
/data/wxs/mnt/ign/bdalti/BDALTIV2_25M_4326.tiff

(-e/-s servent eventuellement a limiter le nb de zooms qu'on veut
générer, ici je vous montre juste l'exemple du nv 11 a 13 avec du 25m)

pour la source de données, j'ai fait diverses expériences avec la bd
alti a 25m, puis le rge alti a 5m, et le rge alti a 1m. la bd alti 25m
suffit largement pour les nvx de zoom jusqu'a 13 inclus (on peut meme
prendre du 75m au dessus du niveau 10), de 14 a 18 le rge alti 5m fait
le taf, et si on veut être encore plus fin/précis il faut passer au rge
alti 1m sinon on a de moches effets de crénelage sur du 5m. On peut
certainement faire avec plus fin, mais c'est mieux d'avoir des données
homogènes sur une zone (ie pas faire du composite de resolutions
diverses pour un niveau de zoom donné..)

Si on utilise plusieurs sources de données pour générer un seul cache de
terrain unique il faut bien penser a 'merger' les différents layer.json
générés.

enfin coller le cache et le layer.json qqpart sur un serveur web, ne pas
oublier de les servir avec le header gzip pour la compression (les
tuiles terrain sont compressées en interne), avec nginx j'ai:

location ~ /3d/terrain.*terrain {
add_header Content-Encoding gzip;
}

pour que ça marche dans mapstore, aussi ajouter le hostname de la ou son
hébergées les tuiles dans la liste 'useCors'. Avec ça, on devrait avoir
un vrai relief bien plus beau - regarder dans la console réseau et
vérifier que les .terrain sont fetchés au fur a mesure qu'on se déplace
dans la vue 3d :)

En espérant que ça serve !

--
Landry Breuil
Responsable Informatique
04 44 05 12 42

----------------------------------------------------------------------------
Centre Régional Auvergne-Rhône-Alpes de l'Information Géographique
Hôtel de région
59 Boulevard Léon Jouhaux - CS 90706
63050 Clermont-Ferrand Cedex 2

https://www.craig.fr <https://www.craig.fr> - @GipCraig

----------------------------------------------------------------------------
> Support utilisateurs (tous les jours ouvrés de 8H30 à 12H30) : 09 72
62 25 31

Catherine Morales

unread,
Feb 13, 2023, 9:11:30 AM2/13/23
to georchestra-dev
Merci Landry.
On va regarder, ça va sûrement nous servir.
On essaye déjà de monter le WMS d'élévation terrain mais on a des soucis. Le MNT source doit il être en 4326 ?
Chez nous il est en 3948 et je pensais qu'en forçant la projection dans geoserver cela fonctionnerait mais on a écran noir ... je pense qu'on a des soucis de projection.

Landry Breuil

unread,
Feb 13, 2023, 9:27:54 AM2/13/23
to georche...@googlegroups.com
On 13/02/2023 15:11, Catherine Morales wrote:
> Merci Landry.
> On va regarder, ça va sûrement nous servir.
> On essaye déjà de monter le WMS d'élévation terrain mais on a des
> soucis. Le MNT source doit il être en 4326 ?

la couche WMS d'elevation donne des résultats pas terribles, ça massacre
pas mal le serveur - enfin chez moi mapserver suivait mais ça génère
*beaucoup* de petites requêtes - pareil avec une bdalti dans geoserver.

> Chez nous il est en 3948 et je pensais qu'en forçant la projection dans
> geoserver cela fonctionnerait mais on a écran noir ... je pense qu'on a
> des soucis de projection.

dans mon cas quand j'utilisais la couche wms d'elevation, la donnée
était nativement en 2154 (avec le viewer dans sa projection par défaut,
donc pas 2154), mais pouvait être requetée dans d'autres projections.

Je viens de reprendre mes logs wms de 2021 quand j'ai déployé la 3d avec
mapserver en BIL, et à l'époque à priori mapstore/cesium faisait des
requêtes de 65px de coté, en projection CRS:84:

bbox=5.581054687500006,33.7060546875,11.293945312500012,39.4189453125&crs=CRS:84&srs=
CRS:84&format=image/bil&width=65&height=65

dans tous les cas, la console réseau du navigateur doit permettre de
voir quelles requêtes wms sont faites par cesium.

Florent Gravin

unread,
Feb 20, 2023, 4:57:01 AM2/20/23
to georche...@googlegroups.com
Merci Landry,

Je vais tester ta recette, peut-être (surement dans la nouvelle doc), serait-il opportun de centraliser ces bonnes pratiques ou recettes qqpart ?

BTW quand je vais sur https://ids.craig.fr/mapstore/ et que je clique sur 3D, ça charge le globe puis le fond est tout blanc, en gros page blanche (chrome et FF), je dois changer le background pour qu'il s'affiche et voir qqch, bug ou feature ?

Merci
Bonne journée

--
--
projet: http://www.georchestra.org/

---
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes georchestra-dev.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse georchestra-d...@googlegroups.com.
Cette discussion peut être lue sur le Web à l'adresse https://groups.google.com/d/msgid/georchestra-dev/f2c602de-744b-aa66-339f-595c4462f178%40craig.fr.


--
camptocamp
INNOVATIVE SOLUTIONS
BY OPEN SOURCE EXPERTS

Florent Gravin
Technical Leader - Architect

Landry Breuil

unread,
Feb 20, 2023, 5:41:37 AM2/20/23
to georche...@googlegroups.com
On 20/02/2023 10:56, Florent Gravin wrote:
> Merci Landry,
>
> Je vais tester ta recette, peut-être (surement dans la nouvelle doc),
> serait-il opportun de centraliser ces bonnes pratiques ou recettes qqpart ?

Certainement, doc administrateur mapstore ? En ce qui me concerne, faire
un post sur une liste de diffusion prend moins de temps, et m'assure que
les personnes intéressées le trouveront.. a la base c'était pour
répondre a une demande de catherine :)

> BTW quand je vais sur https://ids.craig.fr/mapstore/
> <https://ids.craig.fr/mapstore/> et que je clique sur 3D, ça charge le
> globe puis le fond est tout blanc, en gros page blanche (chrome et FF),
> je dois changer le background pour qu'il s'affiche et voir qqch, bug ou
> feature ?

je sais pas si c'est un bug cesium ou mapstore, mais oui je vois la même
chose (et depuis toujours), et j'ai le même comportement en master de
ms2-geor, mais pas sur les démos mapstore. Bref, un bug à remonter ?
--
Landry Breuil
Responsable Informatique

----------------------------------------------------------------------------
Centre Régional Auvergne-Rhône-Alpes de l'Information Géographique
Hôtel de Région de Clermont-Ferrand
59 boulevard Léon Jouhaux - CS 90 706
63050 Clermont-Ferrand
04 44 05 12 42

https://www.craig.fr - @GipCraig
----------------------------------------------------------------------------
Le support est accessible tous les jours ouvrés de 8:30 à 12:30 au 09 72
62 25 31

Florent Gravin

unread,
Jul 20, 2023, 9:27:29 AM7/20/23
to georche...@googlegroups.com
Hi there,

I have tried the pipeline and it's working fine, thanks Landry.
I don't know what is the status of the documentation user group started during the code sprint, but if it can help, here is the wrap up of the commands that I've used, (one of the docker images you mentioned for the tile generation is not working as expected).

That said, there is an interesting project that might produce a better result, but I haven't tested it yet.

--
# download file
relief.tif

# convert to 4326 bilinear
gdalwarp -s_srs epsg:2154 -t_srs epsg:4326 -r bilinear -of GTiff relief.tif relief_4326.tif

# generate terrain tiles from docker image
docker run -it --name ctb -v $(pwd):/data   tumgis/ctb-quantized-mesh
ctb-tile -f Mesh -C -N -c 4 -o /data/cache -s 16 -e 0 /data/relief_4326.tif
ctb-tile -f Mesh -C -N -c 4 -l -o /data/cache -s 16 -e 0 /data/relief_4326.tif

# serve tiles from nginx
docker run -p8001:80 -v $(pwd)/cache:/usr/share/nginx/html:ro -v $(pwd)/nginx.conf:/etc/nginx/conf.d/default.conf:ro nginx:stable-alpine3.17-slim

# with nginx.conf
server {
        listen       80;
        listen  [::]:80;
        server_name  localhost;

        root   /usr/share/nginx/html;

        server_tokens off;

        location ~ /.*terrain {
          add_header Content-Encoding gzip;
          add_header Access-Control-Allow-Origin *;
        }

        location ~ /layer.json {
          add_header Access-Control-Allow-Origin *;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /usr/share/nginx/html;
        }
}


--
--
projet: http://www.georchestra.org/

---
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes georchestra-dev.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse georchestra-d...@googlegroups.com.


--
camptocamp
INNOVATIVE SOLUTIONS
BY OPEN SOURCE EXPERTS

Florent Gravin
Head of Technology Geospatial

Nicolas Rochard

unread,
Jul 25, 2023, 3:17:23 AM7/25/23
to georchestra-dev
Hi all,

A first documentation prototype was drafted based on Landry method and advice.
Test was successfully on sample data. (a french department)
But need to be improve on large dataset as not working "out the box" for an entire region Hauts-de-France.
Got RAM issue during processing when trying convert DTM 1m for all zoom level.
I need to find best practice and set correct zoom level depending of data resolution by mixing different resolution : RGE BDAlti 1m, RGEBDAlti 5m
Need also improve draft documentation to explain how merge different json index tiles files.
For demo instance, we will probably have to deal with BDAlti 25m.

I will test new method you've provide, many thanks for sharing that.

Nicolas.

Nicolas Rochard

unread,
Aug 23, 2023, 5:15:57 AM8/23/23
to georchestra-dev
I've tested "geodan method".
It should avoid performance issue on large dataset when cesium terrain builder crash because too much thread / memory are affected
But :
- it's not working with a unique large TIFF (example a tiff files from RGEAlti1m on Hauts-de-France region)
- if it process tif tiles in a directory, it reproject and fill nodata tiles by tiles. It should generate some overlap or hole and nodata filled near tiles boundaries could be incorrect

From my point of view, we should stay on Landry's method and I will add step to follow on documentation with extra section containing precautions on hardware ressources to affect.
(will have more free time end of September to do that)

Nicolas
Message has been deleted

Pierre Laulhe

unread,
May 28, 2024, 5:33:23 AMMay 28
to georchestra-dev
Hi Nicolas,

I hope you're well.

Could you please provide feedback on your experience over the past year regarding this subject? Specifically, what actions did you take in Haut-de-France?

Thanks in advance for your insights.

Best regards,

Nicolas Rochard

unread,
Jun 4, 2024, 8:55:32 AMJun 4
to georchestra-dev
Dear Pierre,

Sorry for the delay.

I finally applied the method recommended by Landry. It deserves to be automated, similar to what "GeoDan" did.
I haven't had time to contribute into the geOrchestra official documentation yet (maybe during the code sprint in Lille), but here are some notes that might help you.

# Good Practices for Generating 3D Terrain Mesh Quantized Tiles

## Sources

https://groups.google.com/g/georchestra-dev/c/P3Dct3hTQdY/m/CHVCzo7fAwAJ

## Prerequisites

https://github.com/ahuarte47/cesium-terrain-builder/tree/master-quantized-mesh
https://github.com/tum-gis/cesium-terrain-builder-docker
Docker Image: /tumgis/ctb-quantized-mesh:alpine
Use the Alpine TAG, otherwise it won't work.

## Method

1. Download BDAlti
2. Index the tiles into a VRT
3. Mosaic, output a tif
4. Reproject the mosaic to WGS84
4.bis (optional) If there are some holes : fill them.
5. Create quantized-mesh with ctb-tile 
6. Generate the mesh tile index
7. Configure the web server serving the tiles to return a gzip header when calling *.terrain data
8. Configure the 3D tile call in MapStore

## Terrain Cache for Cesium

1. wget -i <text file containing the departments of RGEALti>.txt
2. gdalbuildvrt My_DEM.vrt DEM_Folder/*.asc -addalpha -a_srs EPSG:2154
3. gdal_translate My_DEM.vrt My-DEM.tif -of GTiff -co RESAMPLING=BILINEAR -co COMPRESS=DEFLATE -co PREDICTOR=2 -co ZLEVEL=9 -co NUM_THREADS=70 -co BIGTIFF=YES
4. gdalwarp My_DEM.tif My_DEM_WGS84.tif -s_srs EPSG:2154 -t_srs EPSG:4326 -multi -of GTiff -co RESAMPLING=BILINEAR -co COMPRESS=DEFLATE -co PREDICTOR=2 -co ZLEVEL=9 -co NUM_THREADS=70 -co BIGTIFF=YES
4b. use https://gdal.org/programs/gdal_fillnodata.html is needed.
5. ctb-tile -f Mesh -C -N -c 25 -r bilinear -o /data/cache/ -s 18 -e 0 /data/My_DEM_WGS84.tif
-l to generate the 'layer.json' that will be read by cesium (basically it's the index of the mesh tiles)
6. ctb-tile -f Mesh -C -N -c 25 -r bilinear -l -o /data/cache/ -s 18 -e 0 /data/My_DEM_WGS84.tif

CTB TILE Variables
-e/-s can be used to limit the number of zoom levels to be generated, here I'm showing an example of levels 11 to 13 with 25m
-N for shading with lighting
-- Without specifying -s or -e, it generates by default from level 0 to 16

# It is imperative to mix RGE Alti5 and RGE Alti1m, otherwise there will be a memory problem to generate the 3D tiles
# Generation of RGE Alti5m tiles
ctb-tile -f Mesh -C -N -c 20 -r bilinear -o cache/ -s 10 -e 0 RGEALTI_2-0_5M_ASC_WGS84-IGN_HDF.tif
# Generation of RGE Alti5m tile index
ctb-tile -f Mesh -C -N -c 20 -r bilinear -l -o cache/ -s 10 -e 0 RGEALTI_2-0_5M_ASC_WGS84-IGN_HDF.tif
# Generation of RGE Alti1m tiles
ctb-tile -f Mesh -C -N -c 50 -r bilinear -o cache/ -s 18 -e 11 RGEALTI_MNT_1M_ASC_LAMB93_IGN69_HDF_4326.tif
# Generation of RGE Alti1m tile index
ctb-tile -f Mesh -C -N -c 50 -r bilinear -l -o cache/ -s 18 -e 11 RGEALTI_MNT_1M_ASC_LAMB93_IGN69_HDF_4326.tif
```

## Preview

### Web Server

1. Configure access path (root, autoindex). Nesting of possible location configs and indicate the response header is indeed of type gzip

Example under nginx

```json
    location / {
        root /usr/share/nginx/html/;
        autoindex on;
        location ~ /cache/.*terrain {
            add_header Content-Encoding gzip;
        }
    }
```

### MapStore 2

2. On the MapStore2 side:
In the localConfig.json, defaultMapOptions section, for the "cesium" type, change the terrainprovider from ellipsoid to:

```json
"terrainProvider": {"type":"cesium",
"url":"http://localhost:8080/cache/",
"requestVertexNormals": true
}
```

Landry Breuil

unread,
Jun 4, 2024, 9:29:13 AMJun 4
to georche...@googlegroups.com
On 28/05/2024 11:33, Pierre Laulhe wrote:
> Hi Nicolas,
>
> I hope you're well.
>
> Could you please provide feedback on your experience over the past year
> regarding this subject? Specifically, what actions did you take in Haut-
> de-France?

or just come to geocom where there'll be a presentation on this topic :)

cf thread https://groups.google.com/g/georchestra/c/y7ILtjbR14o for
recent works about it.

--
Landry Breuil
Responsable Informatique
04 44 05 12 42

----------------------------------------------------------------------------
Centre Régional Auvergne-Rhône-Alpes de l'Information Géographique
Hôtel de région
59 Boulevard Léon Jouhaux - CS 90706
63050 Clermont-Ferrand Cedex 2

https://www.craig.fr <https://www.craig.fr> - @GipCraig

----------------------------------------------------------------------------
> Support utilisateurs (tous les jours ouvrés de 8H30 à 12H30) : 09 72
62 25 31

Pierre Laulhe

unread,
Jun 5, 2024, 4:16:41 AMJun 5
to georche...@googlegroups.com
Hi Landry,

Thank you for the information and the invitation. Unfortunately, I won't be able to attend Geocom this year. However, I will follow the presentation closely.

Thanks again and see you soon,

--
--
projet: http://www.georchestra.org/

---
Vous recevez ce message, car vous êtes abonné au groupe Google Groupes georchestra-dev.
Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse georchestra-d...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages