Hinzufügen einer benutzerdefinierten WebGL-Ebene zu einer Karte

Das Azure Maps Web SDK unterstützt das Erstellen benutzerdefinierter Ebenen mithilfe von WebGL. WebGL basiert auf OpenGL ES und ermöglicht das Rendern von 2D- und 3D-Grafiken in Webbrowsern.

Mithilfe von WebGL können Sie leistungsstarke interaktive Grafiken erstellen, die im Browser in Echtzeit gerendert werden und Szenarien wie Simulationen, Datenvisualisierung, Animationen und 3D-Modellierung unterstützen.

Entwickler können während des Renderns auf den WebGL-Kontext der Karte zugreifen und benutzerdefinierte WebGL-Ebenen für die Integration in andere Bibliotheken wie three.js und deck.gl verwenden, um angereicherte und interaktive Inhalte auf der Karte bereitzustellen.

Hinzufügen einer WebGL-Ebene

Bevor Sie einer Karte eine WebGL-Ebene hinzufügen können, müssen Sie über ein Objekt verfügen, das die WebGLRenderer-Schnittstelle implementiert. Erstellen Sie zunächst eine WebGL-Ebene, indem Sie dem Konstruktor ein id- und ein renderer-Objekt bereitstellen, und fügen Sie die Ebene dann der Karte hinzu, damit sie gerendert wird.

Im folgenden Beispielcode wird veranschaulicht, wie Sie einer Karte eine WebGL-Ebene hinzufügen:

var myRenderer = {
    /**
     * Either "2d" or "3d". Defaults to "2d".
     * - "3d" to use the depth buffer and share it with other layers
     * - "2d" to add a layer with no depth. If you need to use the depth buffer for a "2d"
     *   layer you must use an offscreen framebuffer and the prerender method.
     */
    renderingMode: "2d",

    /**
     * Optional method called when the layer has been added to the Map.
     * This gives the layer a chance to initialize gl resources and register event listeners.
     * @param map The Map this custom layer was just added to.
     * @param gl The gl context for the map.
     */
    onAdd: function (map, gl) {},

    /**
     * Optional method called when the layer has been removed from the Map.
     * This gives the layer a chance to clean up gl resources and event listeners.
     * @param map The Map this custom layer was just added to.
     * @param gl The gl context for the map.
     */
    onRemove: function (map, gl) {},

    /**
     * Optional method called during a render frame to allow a layer to prepare resources
     * or render into a texture.
     *
     * The layer cannot make any assumptions about the current GL state and must bind a framebuffer before rendering.
     *
     * @param gl The map's gl context.
     * @param matrix The map's camera matrix.
     */
    prerender: function (gl, matrix) {},

    /**
     * Required. Called during a render frame allowing the layer to draw into the GL context.
     *
     * The layer can assume blending and depth state is set to allow the layer to
     * properly blend and clip other layers. The layer cannot make any other 
     * assumptions about the current GL state.
     *
     * If the layer needs to render to a texture, it should implement the prerender
     * method to do this and only use the render method for drawing directly into the
     * main framebuffer.
     *
     * The blend function is set to gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
     * This expects colors to be provided in premultiplied alpha form where the r, g and b
     * values are already multiplied by the a value. If you are unable to provide colors in
     * premultiplied form you may want to change the blend function to
     * gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA).
     *
     * @param gl The map's gl context.
     * @param matrix The map's camera matrix.
     */
    render: function (gl, matrix) {}
};
 
//Add the layer to the map.
map.layers.add(new atlas.layer.WebGLLayer("layerId", { renderer: myRenderer }));

Hinweis

Die Klasse WebGLLayer unterstützt die Ebenenoptionen minZoom, maxZoom und visible.

//Add the layer to the map with layer options. 
map.layers.add(new atlas.layer.WebGLLayer("layerId", 
    { 
        renderer: myRenderer, 
        minZoom: 10, 
        maxZoom: 22, 
        visible: true
    }
));

In diesem Beispiel wird ein Dreieck auf der Karte mithilfe einer WebGL-Ebene gerendert.

A screenshot showing a triangle rendered on a map, using a WebGL layer.

Ein voll funktionsfähiges Beispiel mit Quellcode finden Sie in den Azure Maps-Beispielen unter Simple 2D WebGL layer.

Die Kameramatrix der Karte wird verwendet, um sphärische Mercator-Punkte auf gl-Koordinaten zu projizieren. Der Mercator-Punkt [0, 0] stellt die obere linke Ecke und [1, 1] die untere rechte Ecke der Mercator-Welt dar. Wenn renderingMode gleich "3d" ist, ist die Z-Koordinate winkelgetreu. Ein Feld mit identischen X-, Y- und Z-Längen in Mercator-Einheiten würde als Würfel gerendert.

Die MercatorPoint-Klasse verfügt über die statischen Methoden fromPosition, fromPositionsund toFloat32Array, die verwendet werden können, um eine räumliche Position in einen Mercator-Punkt zu konvertieren. Ebenso können die Methoden toPosition und toPositions verwendet werden, um einen Mercator-Punkt auf eine Position zu projizieren.

Rendern eines 3D-Modells

Verwenden Sie eine WebGL-Ebene, um 3D-Modelle zu rendern. Das folgende Beispiel zeigt, wie Sie eine glTF-Datei laden und auf der Karte mithilfe von three.js rendern.

Sie müssen die folgenden Skriptdateien hinzufügen.

<script src="https://unpkg.com/three@latest/build/three.min.js"></script>
<script src="https://unpkg.com/three@latest/examples/js/loaders/GLTFLoader.js"></script>

In diesem Beispiel wird ein animierter 3D-Papagei auf der Karte gerendert.

A screenshot showing an animated 3D parrot on the map.

Ein voll funktionsfähiges Beispiel mit Quellcode finden Sie in den Azure Maps-Beispielen unter Three custom WebGL layer.

Die Funktion onAdd lädt eine .glb-Datei in den Arbeitsspeicher und instanziiert three.js-Objekte wie Kamera, Szene, Licht und THREE.WebGLRenderer.

Die Funktion render berechnet die Projektionsmatrix der Kamera und rendert das Modell in der Szene.

Tipp

  • Um eine kontinuierliche und reibungslose Animation zu erstellen, können Sie das Neuzeichnen eines einzelnen Frames auslösen, indem Sie map.triggerRepaint() in der Funktion render aufrufen.
  • Um Antialiasing zu aktivieren, legen Sie beim Erstellen der Karte antialias einfach auf true als eine der Formatvorlagenoptionen fest.

Rendern eines 3D-Modells mithilfe von babylon.js

babylon.js ist eine der führenden WebGL-basierten Grafik-Engines. Das folgende Beispiel zeigt, wie Sie eine GLTF-Datei laden und mithilfe von babylon.js auf der Karte rendern.

Sie müssen die folgenden Skriptdateien hinzufügen.

<script src="https://cdn.babylonjs.com/babylon.js"></script> 
<script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script> 

In diesem Beispiel wird ein Satellitenturm auf der Karte gerendert.

Die Funktion onAdd instanziiert eine BABYLON-Engine und eine Szene. Anschließend wird eine .gltf-Datei mithilfe von BABYLON.SceneLoader geladen.

Die Funktion render berechnet die Projektionsmatrix der Kamera und rendert das Modell in der Szene.

A screenshot showing an example of rendering a 3D model using babylon.js.

Ein voll funktionsfähiges Beispiel mit Quellcode finden Sie in den Azure Maps-Beispielen unter Babylon custom WebGL layer.

Rendern einer deck.gl-Ebene

Eine WebGL-Ebene kann zum Rendern von Ebenen aus der deck.gl-Bibliothek verwendet werden. Das folgende Beispiel veranschaulicht die Datenvisualisierung der Migrationsströme in Nordamerika von County zu County innerhalb eines bestimmten Zeitraums.

Sie müssen die folgende Skriptdatei hinzufügen.

<script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script> 

Definieren Sie eine Ebenenklasse, die atlas.layer.WebGLLayer erweitert.

class DeckGLLayer extends atlas.layer.WebGLLayer { 

    constructor(options) { 
        super(options.id); 

        //Create an instance of deck.gl layer 
        this._mbLayer = new deck.MapboxLayer(options); 

        //Create a renderer 
        const deckGLRenderer = { 
            renderingMode: "3d", 
            onAdd: (map, gl) => { 
               this._mbLayer.onAdd?.(map["map"], gl); 
            }, 
            onRemove: (map, gl) => { 
                this._mbLayer.onRemove?.(map["map"], gl); 
            }, 
            prerender: (gl, matrix) => { 
                this._mbLayer.prerender?.(gl, matrix); 
            }, 
            render: (gl, matrix) => { 
                this._mbLayer.render(gl, matrix); 
            } 
        }; 
        this.setOptions({ renderer: deckGLRenderer }); 
    } 
} 

In diesem Beispiel wird eine Bogenebene mit der deck.gl-Bibliothek gerendert.

A screenshot showing an arc-layer from the Deck G L library.

Ein voll funktionsfähiges Beispiel mit Quellcode finden Sie in den Azure Maps-Beispielen unter Deck GL custom WebGL layer.

Nächste Schritte

Erfahren Sie mehr zu den in diesem Artikel verwendeten Klassen und Methoden: