Mit einem 3D-Kachel-Renderer arbeiten

Fotorealistische 3D-Kacheln befinden sich OGC-Standard-glTF-Format Das heißt, Sie können jeden Renderer verwenden, der die OGC-3D-Kacheln-Spezifikation unterstützt, um für Ihre 3D-Visualisierungen. Beispiel: Cesium ist eine grundlegende Open-Source-Bibliothek zum Rendern von 3D-Visualisierungen.

Mit CesiumJS arbeiten

CesiumJS ist eine Open-Source-JavaScript-Bibliothek für die 3D-Visualisierung im Web. Weitere Informationen zur Verwendung von CesiumJS finden Sie unter CesiumJS

Nutzersteuerung

Der CesiumJS-Kachel-Renderer verfügt über einen Standardsatz von Nutzersteuerelementen.

Aktion Beschreibung
Schwenken Linksklick und Ziehen
Zoomansicht Rechtsklick & mit dem Mausrad ziehen oder scrollen
Ansicht drehen Strg + Links-/Rechtsklick & oder mit der mittleren Maustaste klicken und Ziehen

Best Practices

Es gibt mehrere Ansätze, um die Ladezeiten von CesiumJS 3D zu verringern. Mal. Beispiel:

  • Aktivieren Sie gleichzeitige Anfragen, indem Sie dem Rendering-HTML die folgende Anweisung hinzufügen:

    Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = <REQUEST_COUNT>
    

    Je höher der Wert für REQUEST_COUNT, desto schneller Kacheln geladen. Beim Laden in einem Chrome-Browser mit REQUEST_COUNT größer als 10 und der Cache deaktiviert ist, stoßen Sie möglicherweise auf eine bekannte Problem mit Chrome. Für die meisten Anwendungsfälle empfehlen wir einen REQUEST_COUNT von 18 für eine optimale die Leistung.

  • Überspringen von Detailebenen aktivieren Weitere Informationen finden Sie hier: Cesium-Problem:

Damit Quellenangaben richtig dargestellt werden, aktivieren Sie showCreditsOnScreen: true Weitere Informationen finden Sie unter Richtlinien:

Rendering-Messwerte

Um die Framerate zu ermitteln, requestAnimationFrame aufgerufen wird.

Wie die Frame-Latenz berechnet wird, sehen Sie in der PerformanceDisplay .

Beispiele für den CesiumJS-Renderer

Sie können den CesiumJS-Renderer mit den 3D-Kacheln der Map Tiles API verwenden, indem Sie mit der URL des Stamm-Kachelsatzes.

Einfaches Beispiel

Im folgenden Beispiel wird der CesiumJS-Renderer initialisiert und dann der Stamm der Kachelsatz.

<!DOCTYPE html>
<head>
  <meta charset="utf-8">
  <title>CesiumJS 3D Tiles Simple Demo</title>
  <script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script>
  <link href="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
  <div id="cesiumContainer"></div>
  <script>

    // Enable simultaneous requests.
    Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = 18;

    // Create the viewer.
    const viewer = new Cesium.Viewer('cesiumContainer', {
      imageryProvider: false,
      baseLayerPicker: false,
      geocoder: false,
      globe: false,
      // https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/#enabling-request-render-mode
      requestRenderMode: true,
    });

    // Add 3D Tiles tileset.
    const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
      url: "https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY",
      // This property is needed to appropriately display attributions
      // as required.
      showCreditsOnScreen: true,
    }));
  </script>
</body>

Informationen zu requestRenderMode finden Sie unter Renderingmodus für Anfragen aktivieren.

Die HTML-Seite wird wie hier gezeigt gerendert.

Integration der Places API

Sie können CesiumJS mit dem Places API um weitere Informationen abzurufen. Mit dem Widget für die automatische Vervollständigung können Sie Darstellungsbereich von Orten. In diesem Beispiel wird die Places Autocomplete API verwendet. die durch folgen Sie dieser Anleitung, und der Maps JavaScript API, die durch mithilfe dieser Anleitung.

<!DOCTYPE html>
<head>
 <meta charset="utf-8" />
 <title>CesiumJS 3D Tiles Places API Integration Demo</title>
 <script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script>
 <link href="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
 <label for="pacViewPlace">Go to a place: </label>
 <input
   type="text"
   id="pacViewPlace"
   name="pacViewPlace"
   placeholder="Enter a location..."
   style="width: 300px"
 />
 <div id="cesiumContainer"></div>
 <script>
   // Enable simultaneous requests.
   Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = 18;

   // Create the viewer.
   const viewer = new Cesium.Viewer("cesiumContainer", {
     imageryProvider: false,
     baseLayerPicker: false,
     requestRenderMode: true,
     geocoder: false,
     globe: false,
   });

   // Add 3D Tiles tileset.
   const tileset = viewer.scene.primitives.add(
     new Cesium.Cesium3DTileset({
       url: "https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY",
       // This property is required to display attributions as required.
       showCreditsOnScreen: true,
     })
   );

   const zoomToViewport = (viewport) => {
     viewer.entities.add({
       polyline: {
         positions: Cesium.Cartesian3.fromDegreesArray([
           viewport.getNorthEast().lng(), viewport.getNorthEast().lat(),
           viewport.getSouthWest().lng(), viewport.getNorthEast().lat(),
           viewport.getSouthWest().lng(), viewport.getSouthWest().lat(),
           viewport.getNorthEast().lng(), viewport.getSouthWest().lat(),
           viewport.getNorthEast().lng(), viewport.getNorthEast().lat(),
         ]),
         width: 10,
         clampToGround: true,
         material: Cesium.Color.RED,
       },
     });
     viewer.flyTo(viewer.entities);
   };

   function initAutocomplete() {
     const autocomplete = new google.maps.places.Autocomplete(
       document.getElementById("pacViewPlace"),
       {
         fields: [
           "geometry",
           "name",
         ],
       }
     );
     autocomplete.addListener("place_changed", () => {
       viewer.entities.removeAll();
       const place = autocomplete.getPlace();
       if (!place.geometry || !place.geometry.viewport) {
         window.alert("No viewport for input: " + place.name);
         return;
       }
       zoomToViewport(place.geometry.viewport);
     });
   }
 </script>
 <script
   async=""
   src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initAutocomplete"
 ></script>
</body>

Drehen der Drohnenansicht

Sie können die Kamera für eine Animation über den Kachelsatz steuern. In Kombination mit Places API und Elevation API enthält, simuliert diese Animation eine interaktive Drohnen-Überflug eines beliebigen POI.

Mit diesem Codebeispiel werden Sie an die Stelle geführt, die Sie in der Widget für die automatische Vervollständigung.

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <title>CesiumJS 3D Tiles Rotating Drone View Demo</title>
  <script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script>
  <link href="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
  <label for="pacViewPlace">Go to a place: </label>
  <input type="text" id="pacViewPlace" name="pacViewPlace" placeholder="Enter a location..." style="width: 300px" />
  <div id="cesiumContainer"></div>
  <script>
    // Enable simultaneous requests.
    Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = 18;

    // Create the viewer and remove unneeded options.
    const viewer = new Cesium.Viewer("cesiumContainer", {
      imageryProvider: false,
      baseLayerPicker: false,
      homeButton: false,
      fullscreenButton: false,
      navigationHelpButton: false,
      vrButton: false,
      sceneModePicker: false,
      geocoder: false,
      globe: false,
      infobox: false,
      selectionIndicator: false,
      timeline: false,
      projectionPicker: false,
      clockViewModel: null,
      animation: false,
      requestRenderMode: true,
    });

    // Add 3D Tile set.
    const tileset = viewer.scene.primitives.add(
      new Cesium.Cesium3DTileset({
        url: "https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY",
        // This property is required to display attributions.
        showCreditsOnScreen: true,
      })
    );

    // Point the camera at a location and elevation, at a viewport-appropriate distance.
    function pointCameraAt(location, viewport, elevation) {
      const distance = Cesium.Cartesian3.distance(
        Cesium.Cartesian3.fromDegrees(
          viewport.getSouthWest().lng(), viewport.getSouthWest().lat(), elevation),
        Cesium.Cartesian3.fromDegrees(
          viewport.getNorthEast().lng(), viewport.getNorthEast().lat(), elevation)
      ) / 2;
      const target = new Cesium.Cartesian3.fromDegrees(location.lng(), location.lat(), elevation);
      const pitch = -Math.PI / 4;
      const heading = 0;
      viewer.camera.lookAt(target, new Cesium.HeadingPitchRange(heading, pitch, distance));
    }

    // Rotate the camera around a location and elevation, at a viewport-appropriate distance.
    let unsubscribe = null;
    function rotateCameraAround(location, viewport, elevation) {
      if(unsubscribe) unsubscribe();
      pointCameraAt(location, viewport, elevation);
      unsubscribe = viewer.clock.onTick.addEventListener(() => {
        viewer.camera.rotate(Cesium.Cartesian3.UNIT_Z);
      });
    }

    function initAutocomplete() {
      const autocomplete = new google.maps.places.Autocomplete(
        document.getElementById("pacViewPlace"), {
          fields: [
            "geometry",
            "name",
          ],
        }
      );
      
      autocomplete.addListener("place_changed", async () => {
        const place = autocomplete.getPlace();
        
        if (!(place.geometry && place.geometry.viewport && place.geometry.location)) {
          window.alert(`Insufficient geometry data for place: ${place.name}`);
          return;
        }
        // Get place elevation using the ElevationService.
        const elevatorService = new google.maps.ElevationService();
        const elevationResponse =  await elevatorService.getElevationForLocations({
          locations: [place.geometry.location],
        });

        if(!(elevationResponse.results && elevationResponse.results.length)){
          window.alert(`Insufficient elevation data for place: ${place.name}`);
          return;
        }
        const elevation = elevationResponse.results[0].elevation || 10;

        rotateCameraAround(
          place.geometry.location,
          place.geometry.viewport,
          elevation
        );
      });
    }
  </script>
  <script async src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initAutocomplete"></script>
</body>

Polylinien und Beschriftungen zeichnen

In diesem Codebeispiel wird gezeigt, wie Polylinien und Labels zu einer Karte hinzugefügt werden. Sie können Polylinien zu einer Karte hinzufügen, um Auto- und Fußgängerrouten anzuzeigen oder Grundstücksgrenzen oder zur Berechnung der Auto- und Fußgängerdauer. Sie können auch ohne die Szene zu rendern.

Sie können Nutzende auf eine kuratierte Tour durch ein Viertel mitnehmen oder benachbarte Immobilien, die derzeit im Angebot sind. Sie können 3D-Animationen wie etwa Plakatwände.

Sie können eine Reise zusammenfassen, diese Details in virtuellen Objekten.

<!DOCTYPE html>
<head>
  <meta charset="utf-8" />
  <title>CesiumJS 3D Tiles Polyline and Label Demo</title>
  <script src="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Cesium.js"></script>
  <link 
    href="https://ajax.googleapis.com/ajax/libs/cesiumjs/1.105/Build/Cesium/Widgets/widgets.css"
    rel="stylesheet"
  />
</head>
<body>
  <div id="cesiumContainer"></div>
  <script>
    // Enable simultaneous requests.
    Cesium.RequestScheduler.requestsByServer["tile.googleapis.com:443"] = 18;

    // Create the viewer.
    const viewer = new Cesium.Viewer("cesiumContainer", {
      imageryProvider: false,
      baseLayerPicker: false,
      requestRenderMode: true,
      geocoder: false,
      globe: false,
    });

    // Add 3D Tiles tileset.
    const tileset = viewer.scene.primitives.add(
      new Cesium.Cesium3DTileset({
        url: "https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY",

        // This property is required to display attributions as required.
        showCreditsOnScreen: true,
      })
    );

    // Draws a circle at the position, and a line from the previous position.
    const drawPointAndLine = (position, prevPosition) => {
      viewer.entities.removeAll();
      if (prevPosition) {
        viewer.entities.add({
          polyline: {
            positions: [prevPosition, position],
            width: 3,
            material: Cesium.Color.WHITE,
            clampToGround: true,
            classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
          },
        });
      }
      viewer.entities.add({
        position: position,
        ellipsoid: {
          radii: new Cesium.Cartesian3(1, 1, 1),
          material: Cesium.Color.RED,
        },
      });
    };

    // Compute, draw, and display the position's height relative to the previous position.
    var prevPosition;
    const processHeights = (newPosition) => {
      drawPointAndLine(newPosition, prevPosition);

      const newHeight = Cesium.Cartographic.fromCartesian(newPosition).height;
      let labelText = "Current altitude (meters above sea level):\n\t" + newHeight;
      if (prevPosition) {
        const prevHeight =
          Cesium.Cartographic.fromCartesian(prevPosition).height;
        labelText += "\nHeight from previous point (meters):\n\t" + Math.abs(newHeight - prevHeight);
      }
      viewer.entities.add({
        position: newPosition,
        label: {
          text: labelText,
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
          pixelOffset: new Cesium.Cartesian2(0, -10),
          showBackground: true,
          verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
        }
      });

      prevPosition = newPosition;
    };

    const handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
    handler.setInputAction(function (event) {
      const earthPosition = viewer.scene.pickPosition(event.position);
      if (Cesium.defined(earthPosition)) {
        processHeights(earthPosition);
      }
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  </script>
</body>

Umlaufbahn der Kamera

In Césium können Sie die Kamera um einen POI drehen, mit Gebäuden kollidieren. Alternativ können Sie Gebäude transparent machen wenn die Kamera sich durch sie bewegt.

Fixieren Sie die Kamera zunächst auf einem Punkt und erstellen Sie dann eine Kameraumlaufbahn, Ihr Asset zu präsentieren. Verwenden Sie dazu die lookAtTransform mit einem Ereignis-Listener auf, wie in diesem Codebeispiel gezeigt.

// Lock the camera onto a point.
const center = Cesium.Cartesian3.fromRadians(
  2.4213211833389243,
  0.6171926869414084,
  3626.0426275055174
);

const transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

viewer.scene.camera.lookAtTransform(
  transform,
  new Cesium.HeadingPitchRange(0, -Math.PI / 8, 2900)
);

// Orbit around this point.
viewer.clock.onTick.addEventListener(function (clock) {
  viewer.scene.camera.rotateRight(0.005);
});

Weitere Informationen zur Steuerung der Kamera findest du unter Kamera steuern

Mit Cesium for Unreal arbeiten

So verwenden Sie das Plug-in „Cesium for Unreal“ mit der 3D Tiles API weiter unten.

  1. Installieren Sie das Plug-in „Cesium for Unreal“.

  2. Erstellen Sie ein neues Unreal-Projekt.

  3. Stellen Sie eine Verbindung zur Google PhotoRealistische 3D Tiles API her.

    1. Öffnen Sie das Cesium-Fenster, indem Sie Cesium auswählen. Cesium aus.

    2. Wählen Sie Leerer 3D-Kachelsatz aus.

    3. Öffnen Sie in World Outliner das Steuerfeld Details mit dieser Option. Cesium3DTileset:

    4. Ändern Sie die Quelle von From Cesium Ion in From URL.

    5. Legen Sie die URL der Google 3D-Kacheln als URL fest.

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. Aktiviere die Option Guthabenpunkte auf dem Bildschirm anzeigen, damit Quellenangaben richtig angezeigt werden.
  4. Das lädt die ganze Welt. Um zu einer beliebigen LatLng zu springen, wählen Sie CesiumGeoreference im Bereich Gliederungseditor und bearbeiten Sie dann den Breite/Länge/Höhe des Absprungs im Bereich Details.

Mit Cesium for Unity arbeiten

So verwenden Sie fotorealistische Kacheln mit Cesium for Unity:

  1. Erstellen Sie ein neues Unity-Projekt.

  2. Fügen Sie im Abschnitt „Paketmanager“ eine neue begrenzte Registry hinzu (über Editor > Projekteinstellungen).

    • Name: Cäsium

    • URL: https://unity.pkg.cesium.com

    • Geltungsbereich(e): com.cesium.unity

  3. Installieren Sie das Cesium for Unity-Paket.

  4. Stellen Sie eine Verbindung zur Google PhotoRealistische 3D Tiles API her.

    1. Öffnen Sie das Cesium-Fenster, indem Sie Cesium auswählen. Cesium aus.

    2. Klicken Sie auf Leerer 3D-Kachelsatz.

    3. Gehen Sie im linken Bereich in der Option Tileset Source (Kachelsatz-Quelle) unter Source (Quelle) so vor: Wählen Sie Per URL (anstelle von „From Cesium-Ion“) aus.

    4. Geben Sie als URL die URL der Google 3D-Kacheln an.

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. Aktiviere die Option Guthabenpunkte auf dem Bildschirm anzeigen, damit Quellenangaben richtig angezeigt werden.
  5. Das lädt die ganze Welt. Um zu einer beliebigen LatLng zu springen, wählen Sie CesiumGeoreference-Element in der Szenenhierarchie hinzu und bearbeiten Sie dann das Element Breitengrad/Längengrad/Höhe des Ausgangsorts im Inspector.

Mit deck.gl arbeiten

deck.gl basiert auf WebGL, einem Open-Source-JavaScript-Framework für Datenvisualisierungen im großen Maßstab.

Attribution

Für eine korrekte Darstellung von Datenattributionen müssen die copyright extrahiert werden. aus der gltf-asset-Datei der Kacheln und dann in der gerenderten Ansicht angezeigt. Für finden Sie unter Attributionen von Displaydaten:

Beispiele für deck.gl-Renderer

Einfaches Beispiel

Im folgenden Beispiel wird der deck.gl-Renderer initialisiert und dann ein Ort geladen. in 3D. Ersetzen Sie in Ihrem Code YOUR_API_KEY durch Ihren des eigentlichen API-Schlüssels.

<!DOCTYPE html>
<html>
 <head>
   <title>deck.gl Photorealistic 3D Tiles example</title>
   <script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
   <style>
     body { margin: 0; padding: 0;}
     #map { position: absolute; top: 0;bottom: 0;width: 100%;}
     #credits { position: absolute; bottom: 0; right: 0; padding: 2px; font-size: 15px; color: white;
        text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;}
   </style>
 </head>

 <body>
   <div id="map"></div>
   <div id="credits"></div>
   <script>
     const GOOGLE_API_KEY = YOUR_API_KEY;
     const TILESET_URL = `https://tile.googleapis.com/v1/3dtiles/root.json`;
     const creditsElement = document.getElementById('credits');
     new deck.DeckGL({
       container: 'map',
       initialViewState: {
         latitude: 50.0890,
         longitude: 14.4196,
         zoom: 16,
         bearing: 90,
         pitch: 60,
         height: 200
       },
       controller: {minZoom: 8},
       layers: [
         new deck.Tile3DLayer({
           id: 'google-3d-tiles',
           data: TILESET_URL,
           loadOptions: {
            fetch: {
              headers: {
                'X-GOOG-API-KEY': GOOGLE_API_KEY
              }
            }
          },
           onTilesetLoad: tileset3d => {
             tileset3d.options.onTraversalComplete = selectedTiles => {
               const credits = new Set();
               selectedTiles.forEach(tile => {
                 const {copyright} = tile.content.gltf.asset;
                 copyright.split(';').forEach(credits.add, credits);
                 creditsElement.innerHTML = [...credits].join('; ');
               });
               return selectedTiles;
             }
           }
         })
       ]
     });
   </script>
 </body>
</html>

2D-Ebenen über fotorealistische 3D-Kacheln von Google visualisieren

deck.gl TerrainExtension rendert andernfalls 2D-Daten auf einer 3D-Oberfläche. Sie können beispielsweise GeoJSON eines Gebäudegrundrisses auf der Geometrie der fotorealistischen 3D-Kacheln

Im folgenden Beispiel wird eine Ebene von Gebäuden mithilfe von Polygonen dargestellt. an die Oberfläche der fotorealistischen 3D-Kacheln angepasst.

<!DOCTYPE html>
<html>
 <head>
   <title>Google 3D tiles example</title>
   <script src="https://unpkg.com/deck.gl@latest/dist.min.js"></script>
   <style>
     body { margin: 0; padding: 0;}
     #map { position: absolute; top: 0;bottom: 0;width: 100%;}
     #credits { position: absolute; bottom: 0; right: 0; padding: 2px; font-size: 15px; color: white;
        text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;}
   </style>
 </head>

 <body>
   <div id="map"></div>
   <div id="credits"></div>
   <script>
     const GOOGLE_API_KEY = YOUR_API_KEY;
     const TILESET_URL = `https://tile.googleapis.com/v1/3dtiles/root.json`;
     const BUILDINGS_URL = 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/google-3d-tiles/buildings.geojson'
     const creditsElement = document.getElementById('credits');
     const deckgl = new deck.DeckGL({
       container: 'map',
       initialViewState: {
         latitude: 50.0890,
         longitude: 14.4196,
         zoom: 16,
         bearing: 90,
         pitch: 60,
         height: 200
       },
       controller: true,
       layers: [
         new deck.Tile3DLayer({
           id: 'google-3d-tiles',
           data: TILESET_URL,
           loadOptions: {
            fetch: {
              headers: {
                'X-GOOG-API-KEY': GOOGLE_API_KEY
              }
            }
          },
          onTilesetLoad: tileset3d => {
             tileset3d.options.onTraversalComplete = selectedTiles => {
               const credits = new Set();
               selectedTiles.forEach(tile => {
                 const {copyright} = tile.content.gltf.asset;
                 copyright.split(';').forEach(credits.add, credits);
                 creditsElement.innerHTML = [...credits].join('; ');
               });
               return selectedTiles;
             }
           },
           operation: 'terrain+draw'
         }),
         new deck.GeoJsonLayer({
           id: 'buildings',
           // This dataset is created by CARTO, using other Open Datasets available. More info at: https://3dtiles.carto.com/#about.
           data: 'https://raw.githubusercontent.com/visgl/deck.gl-data/master/examples/google-3d-tiles/buildings.geojson',
           stroked: false,
           filled: true,
           getFillColor: ({properties}) => {
             const {tpp} = properties;
             // quantiles break
             if (tpp < 0.6249)
               return [254, 246, 181]
             else if (tpp < 0.6780)
               return [255, 194, 133]
             else if (tpp < 0.8594)
               return [250, 138, 118]
             return [225, 83, 131]
           },
           opacity: 0.2,
           extensions: [new deck._TerrainExtension()]
         })
       ]
     });
   </script>
 </body>
</html>