3D Karo Oluşturucu ile çalışma

Gerçekçi 3D Parçalar OGC standart glTF biçimi Yani OGC 3D Kartlar özelliklerini destekleyen herhangi bir oluşturucuyu kullanarak daha da iyi hale getirebilirsiniz. Örneğin, Sezyum 3D görselleştirmeler oluşturmak için temel bir açık kaynak kitaplıktır.

CesiumJS ile çalışın

CesiumJS, web'de 3D görselleştirme için açık kaynak bir JavaScript kitaplığıdır. CesiumJS'yi kullanma hakkında daha fazla bilgi için bkz. CezumJS hakkında bilgi edinin.

Kullanıcı denetimleri

CesiumJS karo oluşturucuda standart bir kullanıcı denetimi grubu bulunur.

İşlem Açıklama
Görünümü yatay kaydır Sol tıkla ve sürüklemek
Yakınlaştırma görünümü Sağ tıkla ve fare tekerleğini sürükleyin veya kaydırın
Görünümü döndür Ctrl + sol/sağ tıklama ve sürükleme veya orta tıklama ve sürüklemek

En iyi uygulamalar

CesiumJS 3D yüklemesini azaltmak için uygulayabileceğiniz çeşitli yaklaşımlar vardır kez. Örneğin:

  • Oluşturma HTML'nize aşağıdaki ifadeyi ekleyerek eşzamanlı istekleri etkinleştirin:

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

    REQUEST_COUNT değeri ne kadar yüksek olursa karolar yüklendi. Ancak, REQUEST_COUNT ile Chrome tarayıcıda yükleme yaparken saldırıya uğrarsanız ve önbellek devre dışı bırakılırsa bilinen bir Chrome sorunu. Çoğu kullanım alanında optimum değer için 18 üzerinden REQUEST_COUNT önerilir bazı yolları da görmüştük.

  • Ayrıntı düzeylerini atlama özelliğini etkinleştir. Daha fazla bilgi için bkz. Sezyum sorunu.

Veri ilişkilendirmelerini düzgün şekilde görüntülediğinizden emin olmak için showCreditsOnScreen: true Daha fazla bilgi için bkz. Politikalar.

Oluşturma metrikleri

Kare hızını bulmak için kameranın saniyede kaç defa requestAnimationFrame yöntemi çağrılır.

Kare gecikmesinin nasıl hesaplandığını görmek için PerformanceDisplay sınıfını kullanır.

CesiumJS oluşturucu örnekleri

CesiumJS oluşturucuyu Map Tiles API'nin 3D Parçacıkları ile birlikte kullanmak için sağlayabilirsiniz.

Basit örnek

Aşağıdaki örnek, CesiumJS oluşturucuyu başlatır ve ardından kök parça kümesi.

<!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>

requestRenderMode hakkında daha fazla bilgi için bkz. İstek oluşturma modunu etkinleştirme.

HTML sayfası burada gösterildiği gibi oluşturulur.

Places API entegrasyonu

CesiumJS'yi Yerler API'si tıklayın. Otomatik tamamlama widget'ını kullanarak bir görüntü olacaktır. Bu örnekte, Places Autocomplete API'yi kullanır. sağlayan bu talimatları uygulayarak, ve Google Ads tarafından etkinleştirilen Maps JavaScript API'yi bu talimatları uygulayın.

<!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>

Dönen drone görünümü

Karo grubu aracılığıyla animasyon oluşturacak şekilde kamerayı kontrol edebilirsiniz. Şununla birleştirildiğinde: Places API ve Elevation API'sini birleştiriyor. Bu animasyon, uçuş, drone, drone veya drone uçağı ile yapılır.

Bu kod örneği, sizi bu tarayıcıda seçtiğiniz yerin Otomatik tamamlama widget'ı.

<!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>

Çoklu çizgiler ve etiketler çizme

Bu kod örneğinde, bir haritaya çoklu çizgi ve etiketlerin nasıl ekleneceği gösterilmektedir. Şunları yapabilirsiniz: arabayla ve yaya yol tariflerini göstermek için haritaya çoklu çizgiler ekleyin veya araba ya da yürüyüş sürelerini hesaplamada işe yarar. Ayrıca transkriptinizi özellikleri alabilirsiniz.

Kullanıcıları bir mahallede özel olarak seçilmiş bir tura götürebilir ya da satışta olan komşu mülklere göz atabilir, bu mülklere 3D panolar gibi nesnelerden sahneye konacaktır.

Bir geziyi özetleyebilir, görüntülediğiniz özellikleri listeleyebilir, sanal nesnelerde kullanabilirsiniz.

<!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>

Kamera yörüngesi

Sezyumda kamerayı önemli bir yerin etrafında döndürebilirsiniz ve bu, bina çarpışması var. Alternatif olarak, binaları şeffaf yapabilirsiniz ne zaman hareket ettiğini gösterir.

Önce kamerayı bir noktaya kilitleyin, ardından yörünge oluşturarak öğenizi sergileyebilirsiniz. Bu işlemi kameranın lookAtTransform fonksiyonunu bir etkinlik işleyiciyle gösterin.

// 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);
});

Kamerayı kontrol etme hakkında daha fazla bilgi için bkz. bkz. Kamerayı denetleme

Cesium for Unreal ile çalışın

Cesium for Unreal eklentisini 3D Tiles API ile kullanmak için aşağıdaki adımları uygulayın: bölümüne göz atın.

  1. Cesium for Unreal eklentisini yükleyin.

  2. Yeni bir Unreal projesi oluşturun.

  3. Google Fotogerçekçi 3D Parçalar API'sine bağlanın.

    1. Sezyum'u seçerek Cezyum penceresini açın > Sezyum'u tıklayın.

    2. Boş 3D Karo Parça Seti'ni seçin.

    3. World Outliner'da, bu bağlantıyı seçerek Ayrıntılar panelini açın: Cesium3DTileset'e gidin.

    4. Kaynak alanını Cezyum İyon'dan URL'den olarak değiştirin.

    5. URL'yi Google 3D Tiles URL'sine ayarlayın.

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. İlişkilendirmeleri düzgün bir şekilde görüntülemek için Kredileri Ekranda Göster seçeneğini etkinleştirin.
  4. Bu, dünyayı yükler. Herhangi bir EnlBoy'a geçmek için Anahat panelindeki CesiumGeoreference öğesini seçin ve ardından Ayrıntılar panelindeki Kaynak Enlem/Boylam/Yükseklik.

Unity için Cesium ile çalışın

Unity için Cesium ile fotogerçekçi karolar kullanmak istiyorsanız aşağıdaki adımları uygulayın.

  1. Yeni bir Unity projesi oluşturun.

  2. Paket Yöneticisi bölümüne yeni bir Scoped Registry ekleyin (Düzenleyici > Proje Ayarları aracılığıyla).

    • Ad: Sezyum

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

    • Kapsamlar: com.cesium.unity

  3. Unity paketi için Cesium'u yükleyin.

  4. Google Photoreal 3D Tiles API'ye bağlanın.

    1. Sezyum'u seçerek Cezyum penceresini açın > Sezyum'u tıklayın.

    2. Boş 3D Karo Parça Seti'ni tıklayın.

    3. Sol taraftaki panelde, Kaynak altındaki Öğe Grubu Kaynağı seçeneğinde URL ile seçeneğini belirleyin (Cezyum Ion'dan yerine).

    4. URL'yi Google 3D Tiles URL'sine ayarlayın.

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. İlişkilendirmeleri düzgün bir şekilde görüntülemek için Kredileri Ekranda Göster seçeneğini etkinleştirin.
  5. Bu, dünyayı yükler. Herhangi bir EnlBoy'a geçmek için Scene Hierarchy (Sahne Hierarşisi) içinde CesiumGeoreference öğesini seçin ve ardından İnceleyici'deki Kaynak Enlem/Boylam/Yükseklik.

Deck.gl ile çalışma

deck.gl WebGL destekli web sitesi, yüksek performans için açık kaynaklı bir JavaScript çerçevesidir büyük ölçekli veri görselleştirmeleri sunar.

İlişkilendirme

copyright alanı için asset öğesini tıklayabilir ve oluşturulan görünümde görüntüleyebilirsiniz. Örneğin, daha fazla bilgi için Görüntülü reklam ağı veri ilişkilendirmeleri.

Dec.gl oluşturucu örnekleri

Basit örnek

Aşağıdaki örnek, Dec.gl oluşturucuyu başlatır ve ardından bir yeri yükler. elde etmenize yardımcı olur. Kodunuzda YOUR_API_KEY yerine gerçek API anahtarı.

<!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>

Google Fotogerçekçi 3D Karolar üzerinde 2D katmanları görselleştirin

Deck.gl TerrainExtension aksi takdirde 2D verileri 3D bir yüzeyde oluşturur. Örneğin, her bir ekip üyesinin Fotogerçekçi 3D Karo Geometrisinin üzerindeki bir bina ayak izinin GeoJSON'u.

Aşağıdaki örnekte, bir bina katmanı poligonlarla görselleştirilmiştir Gerçekçi 3D Parçalar yüzeyine uyarlanır.

<!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>