L'initialisation manuelle des fonds de carte et du terrain dans Cesium peut être laborieuse, en praticulier pour des sources courantes comme Tianditu. Cet article présente comment encapsuler ces configurations dans un module réutilisable pour simplifier le processus.
Objectifs des couches supportées
Les développeurs utilisent fréquemment plusieurs types de fonds de carte et de terrain :
- Image unique (hors ligne ou scénarios simples)
- Imagerie et carte des rues ArcGIS On line
- Imagerie, vecteurs et annotations Tianditu (avec jeton)
- Terrain global officiel de Cesium
- Terrain TMS personnalisé (déployé localement)
Notre module BaseLayer fournira des préconfigurations pour ces scénarios.
Étape 1 : Fonction utilitaire pour Tianditu
Créons d'abord un générateur de configurations pour les services WMTS de Tianditu. Cela évite de concaténer manuellement les URL.
// src/utils/imagery/GenerateurOptionsImage.ts
import { CLE_TDT } from "../def/Defaut"
/**
* Génère les options de service WMTS pour Tianditu
* @param type Type de couche : 'img' (imagerie), 'vec' (vecteur), 'cva' (annotation vecteur), 'cia' (annotation imagerie)
* @param cle Clé de développeur Tianditu
*/
export function genererOptionsTdt(
type: "img" | "vec" | "cva" | "cia",
cle = CLE_TDT
) {
const baseUrl = `https://{s}.tianditu.gov.cn/${type}_w/wmts`
const parametres = new URLSearchParams({
SERVICE: "WMTS",
REQUEST: "GetTile",
VERSION: "1.0.0",
LAYER: type,
STYLE: "default",
TILEMATRIXSET: "w",
FORMAT: "tiles",
tk: cle,
}).toString()
return {
url: `${baseUrl}?${parametres}&TILECOL={TileCol}&TILEROW={TileRow}&TILEMATRIX={TileMatrix}`,
layer: type,
style: "default",
format: "tiles",
tileMatrixSetID: "w",
maximumLevel: 18,
subdomains: ["t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7"],
token: cle,
}
}
Étape 2 : Implémentation du module BaseLayer
Créons maintenant le module principal qui expose les différentes couches préconfigurées.
// src/core/couches/BaseLayer.ts
import {
ImageryLayer,
SingleTileImageryProvider,
ArcGisMapServerImageryProvider,
WebMapTileServiceImageryProvider,
createWorldTerrainAsync,
Terrain,
CesiumTerrainProvider,
} from "cesium"
import imageGlobe from "src/static/image-globe"
import { genererOptionsTdt } from "src/utils/imagery/GenerateurOptionsImage"
const CouchesBase = {
/**
* Couche d'imagerie par défaut (image unique pour le mode hors ligne)
*/
get imagerieSimple() {
return ImageryLayer.fromProviderAsync(
SingleTileImageryProvider.fromUrl(imageGlobe),
{}
)
},
/**
* Couche de carte des rues ArcGIS
*/
get imagerieArcgis() {
return ImageryLayer.fromProviderAsync(
ArcGisMapServerImageryProvider.fromUrl(
"https://services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer"
),
{}
)
},
/**
* Couche d'imagerie Tianditu
*/
get imagerieTdt() {
const config = genererOptionsTdt("img")
return ImageryLayer.fromProviderAsync(
Promise.resolve(new WebMapTileServiceImageryProvider(config)),
{}
)
},
/**
* Couche de vecteurs Tianditu
*/
get vecteursTdt() {
const config = genererOptionsTdt("vec")
return ImageryLayer.fromProviderAsync(
Promise.resolve(new WebMapTileServiceImageryProvider(config)),
{}
)
},
/**
* Terrain global Cesium avec masque d'eau et normales
*/
get terrainGlobal() {
const fournisseur = createWorldTerrainAsync({
requestWaterMask: true,
requestVertexNormals: true,
})
return new Terrain(fournisseur)
},
/**
* Charge un terrain TMS personnalisé
* @param url Racine du service de terrain, par exemple "http://localhost:8080/terrain/"
*/
chargerTerrain(url: string): Terrain {
return new Terrain(CesiumTerrainProvider.fromUrl(url))
},
}
export default CouchesBase
Étape 3 : Export du module
Ajoutez l'export dans le fichier principal de l'SDK.
// src/index.ts
export { Viewer } from "./core/Viewer"
export { default as CouchesBase } from "./core/couches/BaseLayer"
// ... autres exports
Étape 4 : Test local avec changement de fond de carte
Voici un exemple HTML pour tester le basculement entre différentes couches de base.
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Test des couches de base</title>
<script src="./Cesium/Cesium.js"></script>
<link rel="stylesheet" href="./Cesium/Widgets/widgets.css">
<script src="./lib/mon-sdk.umd.js"></script>
<script src="./assets/dat.gui.min.js"></script>
<style>
#conteneur { width: 100%; height: 100%; margin: 0; padding: 0; }
#interface { position: absolute; top: 10px; left: 10px; z-index: 100; }
</style>
</head>
<body>
<div id="conteneur"></div>
<div id="interface"></div>
<script>
const visualiseur = new MonSDK.Viewer("conteneur", {
afficherFPS: true,
})
const parametres = { "fond-carte": 0 }
const gui = new dat.GUI({ autoPlace: false })
document.getElementById("interface").appendChild(gui.domElement)
const selecteur = gui.add(parametres, "fond-carte", {
"Image unique": 0,
"Tianditu Imagerie": 1,
"Tianditu Vecteur": 2,
"ArcGIS Rues": 3,
})
selecteur.onChange((valeur) => {
const couches = MonSDK.CouchesBase
const options = {
0: couches.imagerieSimple,
1: couches.imagerieTdt,
2: couches.vecteursTdt,
3: couches.imagerieArcgis,
}
const nouvelleCouche = options[valeur]
visualiseur.imageryLayers.add(nouvelleCouche)
visualiseur.baseImagery = nouvelleCouche
})
</script>
</body>
</html>
Ce code permet de changer dynamiquement le fond de carte via une interface graphique, sans nécessiter de configuration manuelle des URL.