ใช้งานตัวแสดงผลการ์ด 3 มิติ

ชิ้นส่วนแผนที่ 3 มิติแบบสมจริงอยู่ในรูปแบบ glTF มาตรฐาน OGC ซึ่งหมายความว่าคุณสามารถใช้โปรแกรมแสดงผลใดก็ได้ที่รองรับข้อกำหนดของชิ้นส่วนแผนที่ 3 มิติ OGC เพื่อสร้างภาพ 3 มิติ เช่น Cesium เป็นไลบรารีโอเพนซอร์สพื้นฐานสำหรับการเรนเดอร์ภาพ 3 มิติ

ทำงานร่วมกับ CesiumJS

CesiumJS เป็นไลบรารี JavaScript แบบโอเพนซอร์สสําหรับการแสดงภาพ 3 มิติบนเว็บ ดูข้อมูลเพิ่มเติมเกี่ยวกับการใช้ CesiumJS ได้ที่ดูข้อมูลเกี่ยวกับ CesiumJS

การควบคุมของผู้ใช้

โปรแกรมแสดงผลไทล์ CesiumJS มีชุดการควบคุมมาตรฐานสำหรับผู้ใช้

การดำเนินการ คำอธิบาย
เลื่อนมุมมอง คลิกซ้ายแล้วลาก
มุมมองการซูม คลิกขวาแล้วลาก หรือเลื่อนล้อเมาส์
หมุนมุมมอง Ctrl + คลิกซ้าย/ขวาและลาก หรือคลิกกลางและลาก

แนวทางปฏิบัติแนะนำ

คุณลดเวลาในการโหลด CesiumJS 3D ได้หลายวิธี เช่น

  • เปิดใช้คำขอพร้อมกันโดยเพิ่มคำสั่งต่อไปนี้ลงใน HTML ที่แสดงผล

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

    ยิ่ง REQUEST_COUNT สูงเท่าใด ไทล์ก็จะโหลดเร็วขึ้นเท่านั้น อย่างไรก็ตาม เมื่อโหลดในเบราว์เซอร์ Chrome ที่มี REQUEST_COUNT มากกว่า 10 และปิดใช้แคช คุณอาจพบปัญหา Chrome ที่ทราบ สำหรับ Use Case ส่วนใหญ่ เราขอแนะนำให้ใช้ REQUEST_COUNT เป็น 18 เพื่อให้ได้ประสิทธิภาพสูงสุด

  • เปิดใช้การข้ามระดับรายละเอียด ดูข้อมูลเพิ่มเติมได้ที่ปัญหาเกี่ยวกับ Cesium

ตรวจสอบว่าคุณแสดงการระบุแหล่งที่มาของข้อมูลอย่างถูกต้องโดยเปิดใช้ showCreditsOnScreen: true ดูข้อมูลเพิ่มเติมได้ที่นโยบาย

เมตริกการแสดงผล

หากต้องการดูอัตราเฟรม ให้ดูจำนวนครั้งที่เรียกใช้เมธอด requestAnimationFrame ต่อวินาที

หากต้องการดูวิธีคํานวณเวลาในการตอบสนองของเฟรม ให้ดูคลาส PerformanceDisplay

ตัวอย่างโปรแกรมแสดงผล CesiumJS

คุณสามารถใช้โปรแกรมแสดงผล CesiumJS กับไทล์ 3 มิติของ Map Tiles API ได้โดยเพียงแค่ระบุ URL ของชุดข้อมูลราก

ตัวอย่างง่ายๆ

ตัวอย่างต่อไปนี้จะเริ่มต้นโปรแกรมแสดงผล CesiumJS แล้วโหลดชุดพื้น

<!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 ได้ที่การเปิดใช้โหมดการแสดงผลคำขอ

หน้า HTML จะแสดงผลตามที่แสดงที่นี่

การผสานรวม Places API

คุณสามารถใช้ CesiumJS กับ Places API เพื่อดึงข้อมูลเพิ่มเติมได้ คุณสามารถใช้วิดเจ็ตการเติมข้อความอัตโนมัติเพื่อไปยังมุมมองของสถานที่ได้ ตัวอย่างนี้ใช้ Places Autocomplete API ซึ่งเปิดใช้ได้โดยทำตามวิธีการเหล่านี้ และ Maps JavaScript API ซึ่งเปิดใช้ได้โดยทำตามวิธีการเหล่านี้

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

มุมมองโดรนแบบหมุน

คุณควบคุมกล้องเพื่อแสดงภาพเคลื่อนไหวผ่านชุดชิ้นส่วนได้ เมื่อใช้ร่วมกับ Places API และ Elevation API ภาพเคลื่อนไหวนี้จะจำลองภาพโดรนที่บินผ่านจุดที่น่าสนใจแบบอินเทอร์แอกทีฟ

ตัวอย่างโค้ดนี้จะพาคุณไปยังสถานที่ที่คุณเลือกในวิดเจ็ตการเติมข้อความอัตโนมัติ

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

วาดเส้นประกอบและป้ายกำกับ

ตัวอย่างโค้ดนี้แสดงวิธีเพิ่มเส้นประกอบและป้ายกำกับลงในแผนที่ คุณสามารถเพิ่มเส้นประกอบลงในแผนที่เพื่อแสดงเส้นทางการขับรถและการเดิน หรือเพื่อแสดงขอบเขตของพร็อพเพอร์ตี้ หรือเพื่อคํานวณระยะเวลาในการขับรถและการเดิน นอกจากนี้ คุณยังรับแอตทริบิวต์ได้โดยไม่ต้องเรนเดอร์ฉากจริง

คุณสามารถพาผู้ใช้ไปทัวร์ชมย่านต่างๆ ที่คัดสรรมา หรือแสดงที่พักใกล้เคียงที่กําลังลดราคาอยู่ แล้วเพิ่มวัตถุ 3 มิติ เช่น ป้ายโฆษณา ลงในฉาก

คุณสามารถสรุปการเดินทาง แสดงที่พักที่ดู แสดงรายละเอียดเหล่านี้ในวัตถุเสมือน

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

การแพนกล้อง

ใน Cesium คุณสามารถหมุนกล้องรอบจุดที่น่าสนใจเพื่อหลีกเลี่ยงการชนกับอาคาร หรือจะทําให้อาคารโปร่งใสก็ได้เมื่อกล้องเคลื่อนผ่าน

ก่อนอื่น ให้ล็อกกล้องไว้ที่จุดหนึ่ง จากนั้นสร้างการโคจรของกล้องเพื่อแสดงชิ้นงาน ซึ่งทำได้โดยใช้ฟังก์ชัน lookAtTransform ของกล้องร่วมกับ EventListener ดังที่แสดงในตัวอย่างโค้ดนี้

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับการควบคุมกล้องได้ที่หัวข้อควบคุมกล้อง

ทำงานร่วมกับ Cesium for Unreal

หากต้องการใช้ปลั๊กอิน Cesium for Unreal กับ 3D Tiles API ให้ทำตามขั้นตอนด้านล่าง

  1. ติดตั้งปลั๊กอิน Cesium for Unreal

  2. สร้างโปรเจ็กต์ Unreal ใหม่

  3. เชื่อมต่อกับ Google Photorealistic 3D Tiles API

    1. เปิดหน้าต่าง Cesium โดยเลือก Cesium > Cesium จากเมนู

    2. เลือกชุดชิ้นส่วนไทล์ 3 มิติเปล่า

    3. ในเครื่องมือจัดทําโครงร่างโลก ให้เปิดแผงรายละเอียดโดยเลือก Cesium3DTileset นี้

    4. เปลี่ยนแหล่งที่มาจากจาก Cesium Ion เป็นจาก URL

    5. ตั้งค่า URL เป็น URL ของชิ้นส่วนแผนที่ 3 มิติของ Google

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. เปิดใช้แสดงเครดิตบนหน้าจอเพื่อแสดงการระบุแหล่งที่มาอย่างถูกต้อง
  4. ซึ่งจะโหลดโลก หากต้องการไปยัง LatLng ใดก็ได้ ให้เลือกรายการ CesiumGeoreference ในแผงเครื่องมือจัดทําโครงร่าง แล้วแก้ไข Origin Latitude/Longitude/Height ในแผงรายละเอียด

ใช้งาน Cesium for Unity

หากต้องการใช้ไทล์ที่เหมือนภาพถ่ายจริงกับ Cesium for Unity ให้ทำตามขั้นตอนด้านล่าง

  1. สร้างโปรเจ็กต์ Unity ใหม่

  2. เพิ่มรีจิสทรีที่มีขอบเขตใหม่ในส่วนเครื่องมือจัดการแพ็กเกจ (ผ่านเครื่องมือแก้ไข > การตั้งค่าโปรเจ็กต์)

    • ชื่อ: ซีเซียม

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

    • ขอบเขต: com.cesium.unity

  3. ติดตั้งแพ็กเกจ Cesium for Unity

  4. เชื่อมต่อกับ Google Photorealistic 3D Tiles API

    1. เปิดหน้าต่าง Cesium โดยเลือก Cesium > Cesium จากเมนู

    2. คลิกชุดชิ้นส่วนไทล์ 3 มิติเปล่า

    3. ในแผงด้านซ้าย ในตัวเลือกแหล่งที่มาของชุดข้อมูลแผนที่ในส่วนแหล่งที่มา ให้เลือกจาก URL (แทนจาก Cesium Ion)

    4. ตั้งค่า URL เป็น URL ของชิ้นส่วน 3 มิติของ Google

    https://tile.googleapis.com/v1/3dtiles/root.json?key=YOUR_API_KEY
    
    1. เปิดใช้แสดงเครดิตบนหน้าจอเพื่อแสดงการระบุแหล่งที่มาอย่างถูกต้อง
  5. ซึ่งจะโหลดโลก หากต้องการย้ายไปยัง LatLng ใดก็ได้ ให้เลือกรายการ CesiumGeoreference ในลําดับชั้นของฉาก แล้วแก้ไขละติจูด/ลองจิจูด/ความสูงของจุดเริ่มต้นในเครื่องมือตรวจสอบ

ทำงานกับ deck.gl

deck.gl ที่ทำงานด้วย WebGL เป็นเฟรมเวิร์ก JavaScript แบบโอเพนซอร์สสำหรับการจําลองข้อมูลขนาดใหญ่ที่มีประสิทธิภาพสูง

การระบุแหล่งที่มา

ตรวจสอบว่าคุณแสดงการระบุแหล่งที่มาของข้อมูลอย่างถูกต้องโดยการดึงข้อมูลcopyright ฟิลด์จาก tiles gltf asset แล้วแสดงในมุมมองที่ผ่านการจัดการแสดงผล ดูข้อมูลเพิ่มเติมได้ที่การระบุแหล่งที่มาของข้อมูลในการแสดงผล

ตัวอย่างโปรแกรมแสดงผล deck.gl

ตัวอย่างง่ายๆ

ตัวอย่างต่อไปนี้จะเริ่มต้นโปรแกรมแสดงผล deck.gl แล้วโหลดสถานที่เป็น 3 มิติ ในโค้ด อย่าลืมแทนที่ YOUR_API_KEY ด้วยคีย์ API จริง

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

แสดงภาพเลเยอร์ 2 มิติบนชิ้นส่วนแผนที่ 3 มิติแบบสมจริงของ Google

deck.gl TerrainExtension แสดงผลข้อมูล 2 มิติบนพื้นผิว 3 มิติ เช่น คุณสามารถวางซ้อน GeoJSON ของร่องรอยอาคารบนเรขาคณิตของชิ้นส่วนแผนที่ 3 มิติแบบสมจริง

ในตัวอย่างต่อไปนี้ เลเยอร์อาคารจะแสดงเป็นภาพด้วยรูปหลายเหลี่ยมที่ปรับให้เข้ากับพื้นผิวของไทล์ 3 มิติที่เหมือนภาพถ่าย

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