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

นักพัฒนาแอปในเขตเศรษฐกิจยุโรป (EEA)

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

ทำงานกับ CesiumJS

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

คุณใช้โปรแกรมแสดงผล CesiumJS กับ 3D Tiles ของ 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 ของกล้องที่มีเครื่องมือตรวจหาเหตุการณ์ ดังที่แสดงในตัวอย่างโค้ดนี้

// 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 ของ Google 3D Tiles

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

ทำงานกับ Cesium for Unity

หากต้องการใช้ไทล์สมจริงด้วย Cesium สำหรับ Unity ให้ทำตามขั้นตอนด้านล่าง

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

  2. เพิ่มรีจิสทรีที่กำหนดขอบเขตใหม่ในส่วน Package Manager (ผ่านEditor > Project Settings)

    • ชื่อ: Cesium

    • 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 ของ Google 3D Tiles

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

ทำงานกับ deck.gl

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

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

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

ตัวอย่างโปรแกรมแสดงผล 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>