Ce projet vise à encapsuler une suite SDK WebGIS complète et réutilisable, enrichie de fonctionnalités, à partir du moteur 3D open-source Cesium. Nous aborderons la logique d'encapsulation principale, l'implémentation du code clé, l'abstraction des fonctionnalités SIG courantes, ainsi que le développement de composants UI basés sur ce SDK. Les dépôts sont disponibles sur GitHub et le package NPM.
Cet article détaille la création du premier module de notre SDK : Arc3DLab.Viewer. Ce composant vise à simplifier l'initialisation de Cesium en offrant une configuration par défaut adaptée aux développeurs, notamment pour la région chinoise, tout en permettant une personnalisation aisée.
Objectifs du Viewer personnalisé
Bien que puissant, le composant Cesium.Viewer natif présente des inconvénients pour une utilisation immédiate dans certains contextes :
- Présence de nombreux contrôles UI par défaut (animation, timeline, etc.).
- Vue initiale globale, nécessitant une adaptation pour cibler des régions spécifiques comme la Chine.
- Gestion explicite des clés d'accès (tokens) Cesium Ion.
- Difficulté à masquer les informations de copyright par défaut.
Notre solution consiste à hériter de Cesium.Viewer, à modifier son comportement par défaut et à l'encapsuler dans notre propre classe.
Définition des Interfaces (TypeScript)
Dans le fichier src/types/index.ts, nous définissons les options de configuration pour notre Viewer amélioré. Nous étendons les options natives de Cesium pour conserver toute leur flexibilité tout en ajoutant nos propres propriétés spécifiques.
// src/types/index.ts
import type { Viewer as CesiumViewer } from "cesium";
/**
* Options de configuration pour notre classe Viewer.
* @interface CustomViewerOptions
* @extends Cesium.Viewer.ConstructorOptions
*/
export interface CustomViewerOptions extends CesiumViewer.ConstructorOptions {
/** Clé d'accès par défaut pour Cesium Ion. */
defaultIonKey?: string;
/** Indique si le compteur d'images par seconde (FPS) doit être affiché. */
showFps?: boolean;
/** Active le mode de contrôle interactif inspiré de Mapbox (molette pour zoomer, clic droit pour faire pivoter). */
enableMapboxControl?: boolean;
}
Création de la classe Viewer
Le fichier src/core/Viewer.ts héberge notre classe Viewer personnalisée. Nous configurons des paramètres par défaut pour simplifier l'initialisation et le comportement.
// src/core/Viewer.ts
import * as Cesium from "cesium";
import type { CustomViewerOptions } from "../types";
// Supposons que BaseLayer.DefaultImagerySource existe et fournit une source d'imagerie par défaut.
// import { BaseLayer } from "./BaseLayer";
// Définition d'un rectangle par défaut centré sur la Chine.
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = new Cesium.Rectangle(
Cesium.Math.toRadians(70), // Bordure Ouest (longitude)
Cesium.Math.toRadians(-15), // Bordure Sud (latitude)
Cesium.Math.toRadians(140), // Bordure Est
Cesium.Math.toRadians(80) // Bordure Nord
);
export class CustomViewer extends Cesium.Viewer {
constructor(containerId: string | HTMLElement, public options?: CustomViewerOptions) {
const defaultOptions: Cesium.Viewer.ConstructorOptions = {
// Désactivation des contrôles UI par défaut
animation: false,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
timeline: false,
baseLayerPicker: false,
navigationHelpButton: false,
vrButton: false,
selectionIndicator: false,
// Optimisations de performance et de rendu
sceneMode: Cesium.SceneMode.SCENE3D,
scene3DOnly: true,
shouldAnimate: true,
orderIndependentTranslucency: true,
shadows: false,
// Optimisation du contexte WebGL
contextOptions: {
webgl: {
antialias: true,
alpha: true,
powerPreference: "high-performance",
failIfMajorPerformanceCaveat: true,
preserveDrawingBuffer: false,
},
requestWebgl1: false,
},
// Utilisation d'une imagerie de base par défaut (si disponible)
// baseLayer: BaseLayer.DefaultImagerySource,
// Fusion avec les options fournies par l'utilisateur
...options,
};
super(containerId, defaultOptions);
this.initializeBaseConfiguration();
}
private initializeBaseConfiguration(): void {
// 1. Configuration du token Cesium Ion.
Cesium.Ion.defaultAccessToken = this.options?.defaultIonKey || "VOTRE_TOKEN_PAR_DEFAUT";
// 2. Activation de la détection de profondeur du globe (évite la visualisation d'objets souterrains).
this.scene.globe.depthTestAgainstTerrain = true;
// 3. Réglage de la vitesse de simulation à la normale.
this.clock.multiplier = 1;
// 4. Désactivation de la détection de collision pour la caméra (évite de traverser le terrain).
this.scene.screenSpaceCameraController.enableCollisionDetection = true;
// 5. Masquage des informations de copyright Cesium.
// Note: Assurez-vous de respecter les conditions d'utilisation de Cesium.
if (this.cesiumWidget.creditContainer) {
(this.cesiumWidget.creditContainer as any).style.display = "none";
}
// 6. Adaptation aux écrans haute résolution.
this.resolutionScale = window.devicePixelRatio;
// 7. Activation du mode de contrôle Mapbox si spécifié.
if (this.options?.enableMapboxControl) {
this.scene.screenSpaceCameraController.zoomEventTypes = [
Cesium.CameraEventType.WHEEL,
Cesium.CameraEventType.MIDDLE_DRAG,
Cesium.CameraEventType.PINCH,
];
this.scene.screenSpaceCameraController.tiltEventTypes = [
Cesium.CameraEventType.RIGHT_DRAG,
Cesium.CameraEventType.PINCH,
{ eventType: Cesium.CameraEventType.RIGHT_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL },
{ eventType: Cesium.CameraEventType.MIDDLE_DRAG, modifier: Cesium.KeyboardEventModifier.CTRL },
];
}
// 8. Affichage du compteur FPS si spécifié.
this.scene.debugShowFramesPerSecond = this.options?.showFps || false;
}
}
Note : Le masquage du copyright doit être effectué dans le respect des licences d'utilisation.
Exportation du Module
Dans le fichier src/index.ts, nous exportons notre classe personnalisée pour la rendre accessible à l'extérieur du module.
// src/index.ts
export { CustomViewer } from "./core/Viewer";
// D'autres exportations seront ajoutées ici ultérieurement.
Utilisation
Après compilation (par exemple, avec npm run build), vous pouvez intégrer le CustomViewer dans votre application. Voici un exemple dans un fichier HTML :
<!-- demo-html/index.html -->
<div id="map-container" style="width:100%;height:100vh;"></div>
<script type="module">
import { CustomViewer } from '../dist/arc3dlab.esm.js'; // Ajustez le chemin selon votre structure
const viewer = new CustomViewer('map-container', {
showFps: true,
enableMapboxControl: true,
defaultIonKey: 'VOTRE_CLE_CESIUM_ION'
});
</script>
En chargeant cette page, un globe 3D centré sur la Chine, sans contrôles superflus et avec les options de performance activées, sera affiché.
Perspectives
Cette classe CustomViewer constitue la première brique de notre SDK. Les évolutions futures incluront des méthodes pour la gestion des ressources (destroy()), des raccourcis pour la navigation (flyToChina()), et potentiellement la prise en charge de données hors ligne.
Vos suggestions sont les bienvenues sur GitHub pour contribuer à l'amélioration de ce projet.