บริการ Street View

ภาพรวม

เลือกแพลตฟอร์ม: Android iOS JavaScript

Google Street View ให้มุมมอง 360 องศาแบบพาโนรามาจาก ถนนที่กำหนดไว้ตลอดพื้นที่ที่ครอบคลุม การครอบคลุม API ของ Street View นั้นเหมือนกับความครอบคลุมสำหรับแอปพลิเคชัน Google Maps (https://maps.google.com/) คุณสามารถดูรายการเมืองที่รองรับ Street View ในปัจจุบันได้ที่เว็บไซต์ Google Maps

ดูตัวอย่างภาพ Street View ได้ที่ด้านล่าง


Maps JavaScript API มีบริการ Street View สำหรับรับและจัดการภาพที่ใช้ใน Street View ของ Google Maps บริการ Street View นี้มีการรองรับโดยค่าเริ่มต้นภายในเบราว์เซอร์

การใช้งานแผนที่ Street View

แม้ว่าจะใช้ Street View ภายในองค์ประกอบ DOM แบบสแตนด์อโลนได้ แต่ก็มีประโยชน์มากที่สุดเมื่อระบุตำแหน่งในแผนที่ โดยค่าเริ่มต้น ระบบจะเปิด Street View ในแผนที่ และตัวควบคุมเพ็กแมนของ Street View จะปรากฏในส่วนควบคุมการนำทาง (ซูมและเลื่อน) คุณสามารถซ่อนตัวควบคุมนี้ภายใน MapOptions ของแผนที่โดยการตั้งค่า streetViewControl เป็น false คุณยังเปลี่ยนตำแหน่งเริ่มต้นของตัวควบคุม Street View ได้โดยตั้งค่าพร็อพเพอร์ตี้ streetViewControlOptions.position ของ Map เป็น ControlPosition ใหม่

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

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

พาโนรามาใน Street View

ระบบรองรับรูปภาพ Street View ผ่านการใช้ออบเจ็กต์ StreetViewPanorama ซึ่งมีอินเทอร์เฟซ API สำหรับ "ผู้ดู" ของ Street View แต่ละแผนที่จะมีภาพพาโนรามา Street View เริ่มต้น ซึ่งคุณสามารถเรียกดูได้โดยเรียกเมธอด getStreetView() ของแผนที่ เมื่อเพิ่มตัวควบคุม Street View ลงในแผนที่โดยตั้งค่าตัวเลือก streetViewControl เป็น true จะเป็นการเชื่อมต่อตัวควบคุมเพ็กแมนกับภาพพาโนรามาเริ่มต้นของ Street View นี้โดยอัตโนมัติ

คุณอาจสร้างออบเจ็กต์ StreetViewPanorama ของคุณเองและตั้งค่าแผนที่ให้ใช้ออบเจ็กต์ดังกล่าวแทนค่าเริ่มต้นได้ โดยการตั้งค่าพร็อพเพอร์ตี้ streetView ของแผนที่เป็นออบเจ็กต์ที่สร้างขึ้นดังกล่าวอย่างชัดแจ้ง คุณอาจต้องการลบล้างพาโนรามาเริ่มต้น หากคุณต้องการแก้ไขการทำงานเริ่มต้น เช่น การแชร์การวางซ้อนโดยอัตโนมัติระหว่างแผนที่และพาโนรามา (ดูการวางซ้อนภายใน Street View ด้านล่าง)

คอนเทนเนอร์ Street View

คุณอาจต้องแสดง StreetViewPanorama ภายในองค์ประกอบ DOM ที่แยกต่างหาก ซึ่งมักจะเป็นองค์ประกอบ <div> เพียงส่งองค์ประกอบ DOM ภายในตัวสร้างของ StreetViewPanorama สำหรับการแสดงภาพที่เหมาะสม เราขอแนะนำให้ใช้ขนาดขั้นต่ำ 200 x 200 พิกเซล

หมายเหตุ: แม้ว่าฟังก์ชันการทำงานของ Street View จะออกแบบมาให้ใช้ร่วมกับแผนที่ แต่ก็ไม่จำเป็นต้องใช้ คุณใช้ออบเจ็กต์ Street View แบบสแตนด์อโลนได้โดยไม่ต้องใช้แผนที่

ตำแหน่งของ Street View และมุมมอง (POV)

นอกจากนี้ เครื่องมือสร้าง StreetViewPanorama ยังให้คุณกำหนดตำแหน่งและมุมมอง Street View โดยใช้พารามิเตอร์ StreetViewOptions ได้ด้วย คุณอาจเรียกใช้ setPosition() และ setPov() บนออบเจ็กต์หลังการก่อสร้างเพื่อเปลี่ยนตำแหน่งและ POV ได้

ตำแหน่งของ Street View จะกำหนดตำแหน่งโฟกัสของกล้องสำหรับรูปภาพ แต่ไม่ได้กำหนดการวางแนวของกล้องสำหรับรูปภาพนั้น สำหรับวัตถุประสงค์ดังกล่าว ออบเจ็กต์ StreetViewPov จะกำหนดพร็อพเพอร์ตี้ 2 รายการดังนี้

  • heading (ค่าเริ่มต้น 0) กำหนดมุมการหมุนรอบโลคัสของกล้องเป็นองศาที่สัมพันธ์กับทิศเหนือจริง วัดส่วนหัวตามเข็มนาฬิกา (90 องศาคือทิศตะวันออกจริง)
  • pitch (ค่าเริ่มต้น 0) กำหนดความแปรปรวนของมุมเป็น "ขึ้น" หรือ "ลง" จากระดับความสูงต่ำเริ่มต้นของกล้อง ซึ่งมักจะเป็นแนวนอน (แต่ไม่เสมอไป) (เช่น รูปภาพที่ถ่ายบนเนินเขามีแนวโน้มที่จะแสดงระดับความสูงต่ำที่ไม่ใช่แนวนอน) มุมระดับความสูงต่ำวัดด้วยค่าบวกเมื่อมองขึ้นไป (ขึ้นไป +90 องศาตั้งขึ้นและตั้งฉากกับระดับเสียงเริ่มต้น) และค่าลบที่มองลง (ถึง -90 องศาโดยตรง และตั้งฉากกับระดับเสียงเริ่มต้น)

ออบเจ็กต์ StreetViewPov มักใช้เพื่อกำหนดมุมมองของกล้อง Street View นอกจากนี้คุณยังกำหนดมุมมองของช่างภาพได้โดยใช้เมธอด StreetViewPanorama.getPhotographerPov() ซึ่งโดยทั่วไปจะเป็นทิศทางที่รถยนต์หรือรถสามล้อหันไป

รหัสต่อไปนี้แสดงแผนที่เมืองบอสตันพร้อมมุมมองเริ่มต้นของ Fenway Park การเลือกเพ็กแมนและลากไปยังตำแหน่งที่รองรับบนแผนที่จะเปลี่ยนภาพพาโนรามาของ Street View ดังนี้

TypeScript

function initialize() {
  const fenway = { lat: 42.345573, lng: -71.098326 };
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: fenway,
      zoom: 14,
    }
  );
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement,
    {
      position: fenway,
      pov: {
        heading: 34,
        pitch: 10,
      },
    }
  );

  map.setStreetView(panorama);
}

declare global {
  interface Window {
    initialize: () => void;
  }
}
window.initialize = initialize;

JavaScript

function initialize() {
  const fenway = { lat: 42.345573, lng: -71.098326 };
  const map = new google.maps.Map(document.getElementById("map"), {
    center: fenway,
    zoom: 14,
  });
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano"),
    {
      position: fenway,
      pov: {
        heading: 34,
        pitch: 10,
      },
    },
  );

  map.setStreetView(panorama);
}

window.initialize = initialize;

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map,
#pano {
  float: left;
  height: 100%;
  width: 50%;
}

HTML

<html>
  <head>
    <title>Street View split-map-panes</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>
    <div id="pano"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initialize&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

การติดตามการเคลื่อนไหวบนอุปกรณ์เคลื่อนที่

ในอุปกรณ์ที่รองรับเหตุการณ์การวางแนวของอุปกรณ์ API จะช่วยให้ผู้ใช้สามารถเปลี่ยนมุมมองของ Street View ตามการเคลื่อนที่ของอุปกรณ์ได้ ผู้ใช้สามารถมองไปรอบๆ โดยการขยับอุปกรณ์ของตน ซึ่งเรียกว่าการติดตามการเคลื่อนไหวหรือการติดตามการหมุนอุปกรณ์

ในฐานะนักพัฒนาแอป คุณสามารถเปลี่ยนลักษณะการทำงานเริ่มต้นได้ดังนี้

  • เปิดหรือปิดการใช้งานฟังก์ชันการติดตามการเคลื่อนไหว ระบบจะเปิดใช้การติดตามการเคลื่อนไหวโดยค่าเริ่มต้นในทุกอุปกรณ์ที่รองรับ ตัวอย่างต่อไปนี้ปิดใช้การติดตามการเคลื่อนไหว แต่ยังคงมองเห็นการควบคุมการติดตามการเคลื่อนไหว (โปรดทราบว่าผู้ใช้เปิดการติดตามการเคลื่อนไหวได้โดยแตะที่ตัวควบคุม)
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false
        });
    
  • ซ่อนหรือแสดงการควบคุมการติดตามการเคลื่อนไหว โดยค่าเริ่มต้น การควบคุมจะแสดงในอุปกรณ์ที่รองรับการติดตามการเคลื่อนไหว ผู้ใช้แตะตัวควบคุมเพื่อเปิดหรือปิดการติดตามการเคลื่อนไหวได้ โปรดทราบว่าตัวควบคุมจะไม่ปรากฏขึ้นหากอุปกรณ์ไม่รองรับการติดตามการเคลื่อนไหว ไม่ว่าค่าของ motionTrackingControl จะเป็นอย่างไรก็ตาม

    ตัวอย่างต่อไปนี้ปิดใช้ทั้งการติดตามการเคลื่อนไหวและการควบคุมการติดตามการเคลื่อนไหว ในกรณีนี้ ผู้ใช้จะเปิดการติดตามการเคลื่อนไหวไม่ได้

    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false,
          motionTrackingControl: false
        });
    
  • เปลี่ยนตำแหน่งเริ่มต้นของการควบคุมการติดตามการเคลื่อนไหว โดยค่าเริ่มต้น ตัวควบคุมจะปรากฏบริเวณด้านขวาล่างของพาโนรามา (ตำแหน่ง RIGHT_BOTTOM) ตัวอย่างต่อไปนี้จะกำหนดตำแหน่งของตัวควบคุม ไว้ที่ด้านซ้ายล่าง
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTrackingControlOptions: {
            position: google.maps.ControlPosition.LEFT_BOTTOM
          }
        });
    

หากต้องการดูการทำงานของการติดตามการเคลื่อนไหว ให้ดูตัวอย่างต่อไปนี้ในอุปกรณ์เคลื่อนที่ (หรืออุปกรณ์ที่รองรับเหตุการณ์การวางแนวอุปกรณ์)


ดูตัวอย่าง

การวางซ้อนภายใน Street View

ออบเจ็กต์ StreetViewPanorama เริ่มต้นรองรับการวางซ้อนการแสดงแผนที่แบบเนทีฟ โดยทั่วไปแล้ว การวางซ้อนจะปรากฏที่ "ระดับถนน" ซึ่งตรึงไว้ที่ตำแหน่ง LatLng (เช่น เครื่องหมายจะปรากฏโดยยึดหางไว้กับระนาบแนวนอนของตำแหน่งนั้นภายในภาพพาโนรามาของ Street View เป็นต้น)

ปัจจุบัน ประเภทของการวางซ้อนที่รองรับในภาพพาโนรามาของ Street View ถูกจำกัดไว้ที่ Marker, InfoWindow และ OverlayView ที่กำหนดเอง การวางซ้อนที่คุณแสดงบนแผนที่อาจแสดงบนพาโนรามา Street View โดยถือว่าพาโนรามาเป็นสิ่งแทนวัตถุ Map โดยจะเรียกใช้ setMap() และส่ง StreetViewPanorama เป็นอาร์กิวเมนต์แทนที่จะเป็นแผนที่ คุณเปิดหน้าต่างข้อมูลในลักษณะเดียวกันได้ในพาโนรามาของ Street View โดยเรียกใช้ open() โดยผ่าน StreetViewPanorama() แทนแผนที่

นอกจากนี้ เมื่อสร้างแผนที่ด้วย StreetViewPanorama เริ่มต้น เครื่องหมายใดก็ตามที่สร้างขึ้นบนแผนที่จะถูกแชร์ กับภาพพาโนรามาของ Street View ที่เชื่อมโยงกับแผนที่โดยอัตโนมัติ หากสามารถดูภาพพาโนรามาได้ หากต้องการเรียกดูภาพพาโนรามาเริ่มต้นของ Street View ให้เรียกใช้ getStreetView() บนออบเจ็กต์ Map โปรดทราบว่าหากคุณตั้งค่าพร็อพเพอร์ตี้ streetView ของแผนที่เป็น StreetViewPanorama ของการก่อสร้างของคุณเองอย่างชัดแจ้ง คุณจะลบล้างภาพพาโนรามาเริ่มต้น

ตัวอย่างต่อไปนี้แสดงเครื่องหมายที่ระบุถึงสถานที่ต่างๆ รอบ แอสเตอร์เพลส นิวยอร์กซิตี้ สลับการแสดงผลเป็น Street View เพื่อแสดงเครื่องหมายที่แชร์ซึ่งแสดงภายใน StreetViewPanorama

TypeScript

let panorama: google.maps.StreetViewPanorama;

function initMap(): void {
  const astorPlace = { lat: 40.729884, lng: -73.990988 };

  // Set up the map
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: astorPlace,
      zoom: 18,
      streetViewControl: false,
    }
  );

  document
    .getElementById("toggle")!
    .addEventListener("click", toggleStreetView);

  const cafeIcon = document.createElement("img");
  cafeIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/cafe_icon.svg";

  const dollarIcon = document.createElement("img");
  dollarIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/bank_icon.svg";

  const busIcon = document.createElement("img");
  busIcon.src = "https://developers.google.com/maps/documentation/javascript/examples/full/images/bus_icon.svg";


  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    title: "Cafe",
    icon: cafeIcon.src,
  });

  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    title: "Bank",
    icon: dollarIcon.src,
  });

  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    title: "Bus Stop",
    icon: busIcon.src,
  });

  // We get the map's default panorama and set up some defaults.
  // Note that we don't yet set it visible.
  panorama = map.getStreetView()!; // TODO fix type
  panorama.setPosition(astorPlace);
  panorama.setPov(
    /** @type {google.maps.StreetViewPov} */ {
      heading: 265,
      pitch: 0,
    }
  );
}

function toggleStreetView(): void {
  const toggle = panorama.getVisible();

  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let panorama;

function initMap() {
  const astorPlace = { lat: 40.729884, lng: -73.990988 };
  // Set up the map
  const map = new google.maps.Map(document.getElementById("map"), {
    center: astorPlace,
    zoom: 18,
    streetViewControl: false,
  });

  document.getElementById("toggle").addEventListener("click", toggleStreetView);

  const cafeIcon = document.createElement("img");

  cafeIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/cafe_icon.svg";

  const dollarIcon = document.createElement("img");

  dollarIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/bank_icon.svg";

  const busIcon = document.createElement("img");

  busIcon.src =
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/bus_icon.svg";

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    title: "Cafe",
    icon: cafeIcon.src,
  });
  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    title: "Bank",
    icon: dollarIcon.src,
  });
  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    title: "Bus Stop",
    icon: busIcon.src,
  });

  // We get the map's default panorama and set up some defaults.
  // Note that we don't yet set it visible.
  panorama = map.getStreetView(); // TODO fix type
  panorama.setPosition(astorPlace);
  panorama.setPov(
    /** @type {google.maps.StreetViewPov} */ {
      heading: 265,
      pitch: 0,
    },
  );
}

function toggleStreetView() {
  const toggle = panorama.getVisible();

  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: "Roboto", "sans-serif";
  line-height: 30px;
  padding-left: 10px;
}

#floating-panel {
  margin-left: -100px;
}

HTML

<html>
  <head>
    <title>Overlays Within Street View</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="floating-panel">
      <input type="button" value="Toggle Street View" id="toggle" />
    </div>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&libraries=marker&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

เหตุการณ์ Street View

เมื่อนำทางระหว่าง Street View หรือเปลี่ยนทิศทางการเดินรถ คุณอาจต้องตรวจสอบเหตุการณ์ต่างๆ ที่บ่งชี้ถึงการเปลี่ยนแปลงสถานะของ StreetViewPanorama ดังนี้

  • pano_changed เริ่มทำงานเมื่อรหัสพาโนรามาแต่ละรหัสมีการเปลี่ยนแปลง เหตุการณ์นี้ไม่รับประกันว่าข้อมูลที่เกี่ยวข้องภายในพาโนรามา (เช่น ลิงก์) จะมีการเปลี่ยนแปลงตามเวลาที่ทริกเกอร์กิจกรรมนี้ด้วย เหตุการณ์นี้เป็นเพียงการระบุว่ารหัสพาโนรามามีการเปลี่ยนแปลง โปรดทราบว่ารหัสพาโนรามา (ซึ่งคุณสามารถใช้เพื่ออ้างอิงภาพพาโนรามานี้) จะเสถียรภายในเซสชันปัจจุบันของเบราว์เซอร์เท่านั้น
  • position_changed เริ่มทำงานเมื่อใดก็ตามที่ตำแหน่งเบื้องหลัง (LatLng) ของภาพพาโนรามามีการเปลี่ยนแปลง การหมุนพาโนรามาจะไม่ทริกเกอร์เหตุการณ์นี้ โปรดทราบว่าคุณสามารถเปลี่ยน ตำแหน่งเบื้องหลังของพาโนรามาได้โดยไม่ต้องเปลี่ยน รหัสพาโนรามาที่เชื่อมโยง เนื่องจาก API จะเชื่อมโยงพาโนรามา ที่ใกล้ที่สุดกับตำแหน่งของพาโนรามาโดยอัตโนมัติ
  • pov_changed เริ่มทำงานเมื่อ StreetViewPov ของ Street View มีการเปลี่ยนแปลง โปรดทราบว่าเหตุการณ์นี้อาจเริ่มทำงานขณะที่ตำแหน่งและรหัสพาโนรามายังคงนิ่งอยู่
  • links_changed เริ่มทำงานเมื่อใดก็ตามที่ลิงก์ของ Street View มีการเปลี่ยนแปลง โปรดทราบว่าเหตุการณ์นี้อาจเริ่มทำงานแบบไม่พร้อมกันหลังจากการเปลี่ยนแปลงในรหัสพาโนรามาที่ระบุผ่าน pano_changed
  • visible_changed เริ่มทำงานเมื่อมีการเปลี่ยนแปลงการมองเห็นของ Street View โปรดทราบว่าเหตุการณ์นี้อาจเริ่มทำงานแบบไม่พร้อมกันหลังจากการเปลี่ยนแปลงในรหัสพาโนรามาที่ระบุผ่าน pano_changed

โค้ดต่อไปนี้แสดงวิธีจัดการเหตุการณ์เหล่านี้เพื่อรวบรวมข้อมูลเกี่ยวกับ StreetViewPanorama ที่สำคัญ

TypeScript

function initPano() {
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement,
    {
      position: { lat: 37.869, lng: -122.255 },
      pov: {
        heading: 270,
        pitch: 0,
      },
      visible: true,
    }
  );

  panorama.addListener("pano_changed", () => {
    const panoCell = document.getElementById("pano-cell") as HTMLElement;

    panoCell.innerHTML = panorama.getPano();
  });

  panorama.addListener("links_changed", () => {
    const linksTable = document.getElementById("links_table") as HTMLElement;

    while (linksTable.hasChildNodes()) {
      linksTable.removeChild(linksTable.lastChild as ChildNode);
    }

    const links = panorama.getLinks();

    for (const i in links) {
      const row = document.createElement("tr");

      linksTable.appendChild(row);

      const labelCell = document.createElement("td");

      labelCell.innerHTML = "<b>Link: " + i + "</b>";

      const valueCell = document.createElement("td");

      valueCell.innerHTML = links[i].description as string;
      linksTable.appendChild(labelCell);
      linksTable.appendChild(valueCell);
    }
  });

  panorama.addListener("position_changed", () => {
    const positionCell = document.getElementById(
      "position-cell"
    ) as HTMLElement;

    (positionCell.firstChild as HTMLElement).nodeValue =
      panorama.getPosition() + "";
  });

  panorama.addListener("pov_changed", () => {
    const headingCell = document.getElementById("heading-cell") as HTMLElement;
    const pitchCell = document.getElementById("pitch-cell") as HTMLElement;

    (headingCell.firstChild as HTMLElement).nodeValue =
      panorama.getPov().heading + "";
    (pitchCell.firstChild as HTMLElement).nodeValue =
      panorama.getPov().pitch + "";
  });
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano"),
    {
      position: { lat: 37.869, lng: -122.255 },
      pov: {
        heading: 270,
        pitch: 0,
      },
      visible: true,
    },
  );

  panorama.addListener("pano_changed", () => {
    const panoCell = document.getElementById("pano-cell");

    panoCell.innerHTML = panorama.getPano();
  });
  panorama.addListener("links_changed", () => {
    const linksTable = document.getElementById("links_table");

    while (linksTable.hasChildNodes()) {
      linksTable.removeChild(linksTable.lastChild);
    }

    const links = panorama.getLinks();

    for (const i in links) {
      const row = document.createElement("tr");

      linksTable.appendChild(row);

      const labelCell = document.createElement("td");

      labelCell.innerHTML = "<b>Link: " + i + "</b>";

      const valueCell = document.createElement("td");

      valueCell.innerHTML = links[i].description;
      linksTable.appendChild(labelCell);
      linksTable.appendChild(valueCell);
    }
  });
  panorama.addListener("position_changed", () => {
    const positionCell = document.getElementById("position-cell");

    positionCell.firstChild.nodeValue = panorama.getPosition() + "";
  });
  panorama.addListener("pov_changed", () => {
    const headingCell = document.getElementById("heading-cell");
    const pitchCell = document.getElementById("pitch-cell");

    headingCell.firstChild.nodeValue = panorama.getPov().heading + "";
    pitchCell.firstChild.nodeValue = panorama.getPov().pitch + "";
  });
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#floating-panel {
  position: absolute;
  top: 10px;
  left: 25%;
  z-index: 5;
  background-color: #fff;
  padding: 5px;
  border: 1px solid #999;
  text-align: center;
  font-family: "Roboto", "sans-serif";
  line-height: 30px;
  padding-left: 10px;
}

#pano {
  width: 50%;
  height: 100%;
  float: left;
}

#floating-panel {
  width: 45%;
  height: 100%;
  float: right;
  text-align: left;
  overflow: auto;
  position: static;
  border: 0px solid #999;
}

HTML

<html>
  <head>
    <title>Street View Events</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="pano"></div>
    <div id="floating-panel">
      <table>
        <tr>
          <td><b>Position</b></td>
          <td id="position-cell">&nbsp;</td>
        </tr>
        <tr>
          <td><b>POV Heading</b></td>
          <td id="heading-cell">270</td>
        </tr>
        <tr>
          <td><b>POV Pitch</b></td>
          <td id="pitch-cell">0.0</td>
        </tr>
        <tr>
          <td><b>Pano ID</b></td>
          <td id="pano-cell">&nbsp;</td>
        </tr>
        <table id="links_table"></table>
      </table>
    </div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ตัวควบคุม Street View

เมื่อแสดง StreetViewPanorama ตัวควบคุมที่หลากหลายจะปรากฏบนพาโนรามาโดยค่าเริ่มต้น คุณเปิดหรือปิดใช้การควบคุมเหล่านี้ได้โดยตั้งค่าช่องที่เหมาะสมภายใน StreetViewPanoramaOptions เป็น true หรือ false ดังนี้

  • panControl เป็นวิธีหมุนพาโนรามา การควบคุมนี้จะปรากฏขึ้นโดยค่าเริ่มต้นเป็นเข็มทิศและตัวควบคุมการเลื่อนแบบมาตรฐานที่ผสานรวม คุณเปลี่ยนตำแหน่งการควบคุมได้โดยระบุ PanControlOptions ภายในช่อง panControlOptions
  • zoomControl ช่วยให้คุณสามารถซูมภายในรูปภาพได้ ตัวควบคุมนี้จะปรากฏโดยค่าเริ่มต้นบริเวณด้านล่างขวาของพาโนรามา คุณเปลี่ยนลักษณะที่ปรากฏของการควบคุมได้โดยระบุ ZoomControlOptions ภายในช่อง zoomControlOptions
  • addressControl จะแสดงข้อความวางซ้อนซึ่งระบุที่อยู่ของตำแหน่งที่เกี่ยวข้อง และให้ลิงก์เพื่อเปิดตำแหน่งดังกล่าวใน Google Maps คุณเปลี่ยนลักษณะที่ปรากฏของการควบคุมได้โดยระบุ StreetViewAddressControlOptions ภายในช่อง addressControlOptions
  • fullscreenControl มีตัวเลือกในการเปิด Street View ในโหมดเต็มหน้าจอ คุณเปลี่ยนลักษณะที่ปรากฏของการควบคุมได้โดยระบุ FullscreenControlOptions ภายในช่อง fullscreenControlOptions
  • motionTrackingControl มีตัวเลือกในการเปิดหรือปิดใช้การติดตามการเคลื่อนไหวในอุปกรณ์เคลื่อนที่ การควบคุมนี้จะปรากฏเฉพาะในอุปกรณ์ที่รองรับเหตุการณ์การวางแนวอุปกรณ์ โดยค่าเริ่มต้น ตัวควบคุมจะปรากฏที่บริเวณด้านขวาล่างของภาพพาโนรามา คุณเปลี่ยนตําแหน่งของตัวควบคุมได้โดยระบุ MotionTrackingControlOptions สำหรับข้อมูลเพิ่มเติม ดูส่วนการติดตามการเคลื่อนไหว
  • linksControl จะแสดงลูกศรนำทางในรูปภาพ สำหรับการเดินทางไปยังรูปภาพพาโนรามาที่อยู่ติดกัน
  • ตัวควบคุม "ปิด" ช่วยให้ผู้ใช้ปิดโปรแกรมดูภาพ Street View ได้ คุณเปิดหรือปิดการควบคุม "ปิด" ได้โดยตั้งค่า enableCloseButton เป็น true หรือ false

ตัวอย่างต่อไปนี้ปรับเปลี่ยนการควบคุมที่แสดงภายใน Street View ที่เชื่อมโยง และนำลิงก์ของมุมมองออก

TypeScript

function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map") as HTMLElement,
    {
      position: { lat: 42.345573, lng: -71.098326 },
      addressControlOptions: {
        position: google.maps.ControlPosition.BOTTOM_CENTER,
      },
      linksControl: false,
      panControl: false,
      enableCloseButton: false,
    }
  );
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map"),
    {
      position: { lat: 42.345573, lng: -71.098326 },
      addressControlOptions: {
        position: google.maps.ControlPosition.BOTTOM_CENTER,
      },
      linksControl: false,
      panControl: false,
      enableCloseButton: false,
    },
  );
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Street View Controls</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

การเข้าถึงข้อมูล Street View โดยตรง

คุณอาจต้องการตรวจสอบความพร้อมใช้งานของข้อมูล Street View โดยใช้โปรแกรม หรือแสดงผลข้อมูลเกี่ยวกับภาพพาโนรามาหนึ่งๆ โดยไม่ต้องปรับเปลี่ยนแผนที่/พาโนรามาโดยตรง ซึ่งทำได้โดยใช้ออบเจ็กต์ StreetViewService ซึ่งมีอินเทอร์เฟซข้อมูลที่จัดเก็บไว้ในบริการ Street View ของ Google

คำขอบริการ Street View

การเข้าถึงบริการ Street View เป็นแบบไม่พร้อมกันเนื่องจาก Google Maps API ต้องทำการเรียกไปยังเซิร์ฟเวอร์ภายนอก ด้วยเหตุนี้ คุณจึงต้องส่งเมธอด callback เพื่อดำเนินการเมื่อคำขอเสร็จสมบูรณ์ วิธี Callback นี้จะประมวลผลผลลัพธ์

คุณจะเริ่มคำขอไปยัง StreetViewService ได้โดยใช้ StreetViewPanoRequest หรือ StreetViewLocationRequest

คำขอที่ใช้ StreetViewPanoRequest จะแสดงผลข้อมูลพาโนรามา พร้อมรหัสอ้างอิงที่ระบุพาโนรามาแบบไม่ซ้ำกัน โปรดทราบว่ารหัสอ้างอิงเหล่านี้จะคงที่ตลอดอายุของภาพพาโนรามาดังกล่าวเท่านั้น

คำขอที่ใช้ StreetViewLocationRequest จะค้นหา ข้อมูลพาโนรามาในตำแหน่งที่ระบุ โดยใช้พารามิเตอร์ต่อไปนี้

  • location ระบุตำแหน่ง (ละติจูดและลองจิจูด) เพื่อค้นหาพาโนรามา
  • preference ตั้งค่ากำหนดว่าควรพบภาพพาโนรามาภายในรัศมี นั่นคือ ภาพที่ใกล้ที่สุดกับตำแหน่งที่ระบุ หรือภาพที่ดีที่สุดภายในรัศมี
  • radius กำหนดรัศมีซึ่งระบุเป็นหน่วยเมตรเพื่อค้นหาภาพพาโนรามา โดยมีศูนย์กลางอยู่ที่ละติจูดและลองจิจูดที่ระบุ ค่าเริ่มต้นจะเป็น 50 เมื่อไม่ได้ให้ไว้
  • source ระบุแหล่งที่มาของภาพพาโนรามาที่จะค้นหา ค่าที่ใช้ได้มีดังนี้
    • default ใช้แหล่งที่มาเริ่มต้นสำหรับ Street View การค้นหาจะไม่จำกัดอยู่ที่แหล่งที่มาใดแหล่งหนึ่งเท่านั้น
    • outdoor จำกัดการค้นหาให้อยู่ในคอลเล็กชันกลางแจ้ง โปรดทราบว่าตำแหน่งที่ระบุอาจไม่มีภาพพาโนรามากลางแจ้ง

การตอบกลับบริการ Street View

ฟังก์ชัน getPanorama() ต้องใช้ฟังก์ชัน callback เพื่อดำเนินการเมื่อดึงผลลัพธ์จากบริการ Street View ฟังก์ชัน Callback นี้จะแสดงชุดข้อมูลพาโนรามาภายในออบเจ็กต์ StreetViewPanoramaData และรหัส StreetViewStatus ที่แสดงถึงสถานะของคำขอตามลำดับดังกล่าว

ข้อกำหนดออบเจ็กต์ StreetViewPanoramaData มีข้อมูลเมตาเกี่ยวกับพาโนรามาของ Street View ในรูปแบบต่อไปนี้

{
  "location": {
    "latLng": LatLng,
    "description": string,
    "pano": string
  },
  "copyright": string,
  "links": [{
      "heading": number,
      "description": string,
      "pano": string,
      "roadColor": string,
      "roadOpacity": number
    }],
  "tiles": {
    "worldSize": Size,
    "tileSize": Size,
    "centerHeading": number
  }
}

โปรดทราบว่าออบเจ็กต์ข้อมูลนี้ไม่ใช่ออบเจ็กต์ StreetViewPanorama เอง หากต้องการสร้างออบเจ็กต์ Street View โดยใช้ข้อมูลนี้ คุณจะต้องสร้าง StreetViewPanorama และเรียกใช้ setPano() โดยส่งรหัสตามที่ระบุในช่อง location.pano ที่แสดงผล

โค้ด status อาจแสดงค่าใดค่าหนึ่งต่อไปนี้

  • OK ระบุว่าบริการพบภาพพาโนรามาที่ตรงกัน
  • ZERO_RESULTS บ่งบอกว่าบริการไม่พบภาพพาโนรามาที่ตรงกับเกณฑ์ที่ผ่านเกณฑ์
  • UNKNOWN_ERROR ระบุว่าไม่สามารถดำเนินการตามคำขอ Street View แม้ว่าจะไม่ทราบสาเหตุที่แท้จริง

โค้ดต่อไปนี้จะสร้าง StreetViewService ที่ตอบสนองต่อการคลิกของผู้ใช้บนแผนที่โดยการสร้างเครื่องหมาย ซึ่งเมื่อคลิกจะแสดง StreetViewPanorama ของตำแหน่งดังกล่าว โค้ดดังกล่าวใช้เนื้อหาของ StreetViewPanoramaData ที่แสดงผลจากบริการ

TypeScript

/*
 * Click the map to set a new location for the Street View camera.
 */

let map: google.maps.Map;

let panorama: google.maps.StreetViewPanorama;

function initMap(): void {
  const berkeley = { lat: 37.869085, lng: -122.254775 };
  const sv = new google.maps.StreetViewService();

  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano") as HTMLElement
  );

  // Set up the map.
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    center: berkeley,
    zoom: 16,
    streetViewControl: false,
  });

  // Set the initial Street View camera to the center of the map
  sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData);

  // Look for a nearby Street View panorama when the map is clicked.
  // getPanorama will return the nearest pano when the given
  // radius is 50 meters or less.
  map.addListener("click", (event) => {
    sv.getPanorama({ location: event.latLng, radius: 50 })
      .then(processSVData)
      .catch((e) =>
        console.error("Street View data not found for this location.")
      );
  });
}

function processSVData({ data }: google.maps.StreetViewResponse) {
  const location = data.location!;

  const marker = new google.maps.Marker({
    position: location.latLng,
    map,
    title: location.description,
  });

  panorama.setPano(location.pano as string);
  panorama.setPov({
    heading: 270,
    pitch: 0,
  });
  panorama.setVisible(true);

  marker.addListener("click", () => {
    const markerPanoID = location.pano;

    // Set the Pano to use the passed panoID.
    panorama.setPano(markerPanoID as string);
    panorama.setPov({
      heading: 270,
      pitch: 0,
    });
    panorama.setVisible(true);
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * Click the map to set a new location for the Street View camera.
 */
let map;
let panorama;

function initMap() {
  const berkeley = { lat: 37.869085, lng: -122.254775 };
  const sv = new google.maps.StreetViewService();

  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("pano"),
  );
  // Set up the map.
  map = new google.maps.Map(document.getElementById("map"), {
    center: berkeley,
    zoom: 16,
    streetViewControl: false,
  });
  // Set the initial Street View camera to the center of the map
  sv.getPanorama({ location: berkeley, radius: 50 }).then(processSVData);
  // Look for a nearby Street View panorama when the map is clicked.
  // getPanorama will return the nearest pano when the given
  // radius is 50 meters or less.
  map.addListener("click", (event) => {
    sv.getPanorama({ location: event.latLng, radius: 50 })
      .then(processSVData)
      .catch((e) =>
        console.error("Street View data not found for this location."),
      );
  });
}

function processSVData({ data }) {
  const location = data.location;
  const marker = new google.maps.Marker({
    position: location.latLng,
    map,
    title: location.description,
  });

  panorama.setPano(location.pano);
  panorama.setPov({
    heading: 270,
    pitch: 0,
  });
  panorama.setVisible(true);
  marker.addListener("click", () => {
    const markerPanoID = location.pano;

    // Set the Pano to use the passed panoID.
    panorama.setPano(markerPanoID);
    panorama.setPov({
      heading: 270,
      pitch: 0,
    });
    panorama.setVisible(true);
  });
}

window.initMap = initMap;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Directly Accessing Street View Data</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map" style="width: 45%; height: 100%; float: left"></div>
    <div id="pano" style="width: 45%; height: 100%; float: left"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ให้บริการภาพพาโนรามาของ Street View ตามสั่ง

Maps JavaScript API รองรับการแสดงพาโนรามาที่กำหนดเองภายในออบเจ็กต์ StreetViewPanorama เมื่อใช้ภาพพาโนรามาที่กำหนดเอง คุณสามารถแสดงภายในอาคาร วิวจากสถานที่อันงดงาม หรือสิ่งใดก็ได้จากจินตนาการของคุณ คุณยังสามารถลิงก์ภาพพาโนรามาที่กำหนดเองเหล่านี้กับภาพพาโนรามา Street View ที่มีอยู่ของ Google

การตั้งค่าชุดรูปภาพพาโนรามาที่กำหนดเองมีขั้นตอนดังนี้

  • สร้างภาพพาโนรามาพื้นฐานสำหรับภาพพาโนรามาที่กำหนดเองแต่ละภาพ รูปภาพฐานนี้ควรเป็นรูปภาพที่มีความละเอียดสูงสุดซึ่งคุณต้องการแสดงแบบซูม
  • (ไม่บังคับ แต่แนะนำ) สร้างชุดชิ้นส่วนพาโนรามาที่ระดับการซูมต่างๆ จากรูปภาพพื้นฐาน
  • สร้างลิงก์ระหว่างภาพพาโนรามาที่กำหนดเองของคุณ
  • (ไม่บังคับ) กำหนดภาพพาโนรามา "เข้า" ภายในภาพ Street View ที่มีอยู่ของ Google และปรับแต่งลิงก์ไปยัง/จากชุดแบบกำหนดเองให้เป็นชุดมาตรฐาน
  • กำหนดข้อมูลเมตาสำหรับภาพพาโนรามาแต่ละภาพ ภายในออบเจ็กต์ StreetViewPanoramaData
  • ใช้เมธอดที่กําหนดข้อมูลและรูปภาพพาโนรามาที่กำหนดเอง และกําหนดเมธอดนั้นเป็นตัวแฮนเดิลที่กําหนดเองภายในออบเจ็กต์ StreetViewPanorama

ส่วนต่อไปนี้จะอธิบายขั้นตอนนี้

การสร้างภาพพาโนรามาที่กำหนดเอง

พาโนรามาของ Street View แต่ละพาโนรามา คือรูปภาพหรือชุดรูปภาพ ที่ให้มุมมองแบบเต็ม 360 องศาจากสถานที่เดียว ออบเจ็กต์ StreetViewPanorama ใช้รูปภาพที่สอดคล้องกับการฉายภาพทรงกลม (Plate Carrée) การฉายภาพดังกล่าวมีมุมมองแนวนอน 360 องศา (ภาพรอบด้านแบบเต็ม) และมุมมองแนวตั้ง 180 องศา (จากตรงขึ้นไปจนถึงแนวดิ่ง) ช่องของมุมมองเหล่านี้จะแสดงผลเป็นรูปภาพที่มีสัดส่วนภาพ 2:1 ด้านล่างนี้เป็นภาพพาโนรามารอบด้าน

วิวถนนในเมืองแบบพาโนรามา

โดยทั่วไปแล้ว รูปภาพพาโนรามาจะได้จากการถ่ายภาพ หลายๆ ภาพจากตำแหน่งเดียว แล้วปะติดปะต่อเข้าด้วยกันโดยใช้ ซอฟต์แวร์พาโนรามา (ดูข้อมูลเพิ่มเติมได้ที่ การเปรียบเทียบแอปพลิเคชันการเย็บรูปภาพของวิกิพีเดีย) รูปภาพดังกล่าวควรใช้โลคัส "กล้อง" ตัวเดียวที่ใช้ถ่ายภาพพาโนรามาแต่ละภาพ ภาพพาโนรามา 360 องศาที่ได้จะสามารถกำหนดเส้นโครงบนทรงกลมโดยภาพนั้นตัดกับพื้นผิว 2 มิติของทรงกลม

ถนนแบบ 360 องศาที่มีวิวถนนแบบพาโนรามา

การจัดการภาพพาโนรามานั้นเป็นการฉายภาพบนทรงกลมด้วยระบบพิกัดเส้นตรง มีประโยชน์ในการแบ่งภาพเป็นชิ้นส่วนเส้นตรง และแสดงรูปภาพตามพิกัด ของชิ้นส่วนที่คำนวณได้

การสร้างการ์ดพาโนรามาที่กำหนดเอง

นอกจากนี้ Street View ยังรองรับรายละเอียดของรูปภาพในระดับต่างๆ ผ่าน การควบคุมการซูม ซึ่งช่วยให้คุณซูมเข้าและออกจากมุมมองเริ่มต้นได้ โดยทั่วไป Street View จะมีความละเอียดการซูม 5 ระดับสำหรับภาพพาโนรามาหนึ่งๆ หากคุณต้องใช้ภาพพาโนรามาเดียวในการซูมทุกระดับ ภาพดังกล่าวจะต้องมีขนาดใหญ่และทำให้แอปพลิเคชันของคุณช้าลงอย่างมาก หรือมีความละเอียดต่ำในระดับการซูมที่สูงขึ้นจนทำให้คุณแสดงภาพที่แตกเป็นพิกเซลได้ไม่ดี โชคดีที่เราสามารถใช้รูปแบบการออกแบบที่คล้ายกัน ซึ่งใช้เพื่อแสดง ชิ้นส่วนแผนที่ของ Google ที่ระดับการซูมต่างๆ กัน เพื่อให้ได้ภาพความละเอียดที่เหมาะสมสำหรับพาโนรามาในแต่ละระดับการซูม

เมื่อ StreetViewPanorama โหลดเป็นครั้งแรก ระบบจะแสดงรูปภาพที่ประกอบด้วยภาพโค้ง 25% (90 องศา) ของความกว้างแนวนอนของพาโนรามาที่ระดับการซูม 1 โดยค่าเริ่มต้น มุมมองนี้สอดคล้องกับขอบเขตการมองเห็นปกติของมนุษย์ การซูม "ออก" จากมุมมองเริ่มต้นนี้จะให้เส้นโค้งกว้างขึ้น ขณะที่การซูมเข้าจะจำกัดพื้นที่ของมุมมองให้แคบลงเป็นเส้นโค้งที่เล็กลง StreetViewPanorama จะคำนวณขอบเขตการมองเห็นที่เหมาะสมสำหรับระดับการซูมที่เลือกโดยอัตโนมัติ จากนั้นเลือกภาพที่เหมาะสมที่สุดสำหรับความละเอียดดังกล่าว โดยเลือกชุดชิ้นส่วนที่ตรงกับขนาดของช่องภาพในแนวนอน ฟิลด์ต่อไปนี้ของแผนที่ไปยังระดับการซูมของ Street View

ระดับการซูมของ Street View ฟิลด์ของมุมมอง (องศา)
0 180
1 (ค่าเริ่มต้น) 90
2 45
3 22.5
4 25.11

โปรดทราบว่าขนาดของภาพที่แสดงใน Street View จะขึ้นอยู่กับขนาดหน้าจอ (ความกว้าง) ของคอนเทนเนอร์ Street View หากคุณสร้างคอนเทนเนอร์ที่กว้างกว่า บริการก็ยังมีช่องมุมมองเดียวกันสำหรับระดับการซูมที่กำหนด แต่อาจเลือกชิ้นส่วนที่เหมาะสมกับความละเอียดดังกล่าวมากกว่า

เนื่องจากภาพพาโนรามาแต่ละภาพมีการฉายภาพเป็นรูปสี่เหลี่ยมผืนผ้า การสร้างชิ้นส่วนภาพพาโนรามาจึงค่อนข้างง่าย เนื่องจากเส้นโครงสี่เหลี่ยมจัตุรัสให้รูปภาพที่มีสัดส่วนภาพ 2:1 ชิ้นส่วนแผนที่ที่มีอัตราส่วน 2:1 จะใช้งานได้ง่ายกว่า แม้ว่าชิ้นส่วนสี่เหลี่ยมจตุรัสอาจให้ประสิทธิภาพที่ดีกว่าในแผนที่แบบสี่เหลี่ยมจัตุรัส (เนื่องจากขอบเขตการมองเห็นจะเป็นแบบสี่เหลี่ยมจัตุรัส)

สำหรับไทล์ 2:1 รูปภาพ 1 รูปที่ครอบคลุมภาพพาโนรามาทั้งหมดจะแสดง "โลก" ของพาโนรามาทั้งหมด (รูปภาพฐาน) ที่ระดับการซูม 0 โดยระดับการซูมที่เพิ่มขึ้นแต่ละระดับจะมีชิ้นส่วน zoomLevel อยู่ 4 ชิ้น (เช่น ที่ระดับการซูม 2 ภาพพาโนรามาทั้งหมดจะประกอบด้วยชิ้นส่วน 16 ชิ้น) หมายเหตุ: ระดับการซูมในไทล์ Street View ไม่ตรงกับระดับการซูมโดยตรงดังที่ระบุไว้โดยใช้ตัวควบคุม Street View แต่ระดับการซูมการควบคุม Street View จะเลือกช่องของมุมมอง (FoV) จากที่มีการเลือกชิ้นส่วนที่เหมาะสมแทน

มุมมองพาโนรามาของถนนในเมืองที่แบ่งออกเป็นชิ้นส่วน

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

การจัดการคำขอพาโนรามาที่กำหนดเอง

หากต้องการใช้พาโนรามาที่กำหนดเอง ให้เรียกใช้ StreetViewPanorama.registerPanoProvider() พร้อมระบุชื่อ เมธอดของผู้ให้บริการพาโนรามาที่กำหนดเองของคุณ เมธอดของผู้ให้บริการพาโนรามาจะต้องแสดงผลออบเจ็กต์ StreetViewPanoramaData และมีลายเซ็นต่อไปนี้

Function(pano):StreetViewPanoramaData

StreetViewPanoramaData เป็นออบเจ็กต์ในรูปแบบต่อไปนี้

{
  copyright: string,
  location: {
    description: string,
    latLng: google.maps.LatLng,
    pano: string
  },
  tiles: {
    tileSize: google.maps.Size,
    worldSize: google.maps.Size,
    heading: number,
    getTileUrl: Function
  },
  links: [
    description: string,
    heading: number,
    pano: string,
    roadColor: string,
    roadOpacity: number
  ]
}

แสดงภาพพาโนรามาที่กำหนดเองดังนี้:

  • ตั้งค่าพร็อพเพอร์ตี้ StreetViewPanoramaOptions.pano เป็นค่าที่กำหนดเอง
  • เรียกใช้ StreetViewPanorama.registerPanoProvider() เพื่อระบุฟังก์ชันของผู้ให้บริการภาพพาโนรามาที่กำหนดเอง
  • ใช้ฟังก์ชันผู้ให้บริการพาโนรามาที่กำหนดเองเพื่อจัดการค่า pano ที่ระบุ
  • สร้างออบเจ็กต์ StreetViewPanoramaData
  • ตั้งค่าพร็อพเพอร์ตี้ StreetViewTileData.getTileUrl เป็นชื่อฟังก์ชันผู้ให้บริการการ์ดที่กำหนดเองที่คุณระบุ เช่น getCustomPanoramaTileUrl
  • ใช้ฟังก์ชันผู้ให้บริการการ์ดที่กำหนดเองดังที่แสดงในตัวอย่างด้านล่าง
  • แสดงผลออบเจ็กต์ StreetViewPanoramaData

หมายเหตุ: อย่าตั้งค่า position ใน StreetViewPanorama โดยตรงเมื่อคุณต้องการแสดงภาพพาโนรามาที่กำหนดเอง เพราะตำแหน่งดังกล่าวจะสั่งให้บริการ Street View ขอภาพ Street View เริ่มต้นที่อยู่ใกล้กับตำแหน่งนั้น ให้ตั้งค่าตำแหน่งนี้ภายในช่อง location.latLng ของออบเจ็กต์ StreetViewPanoramaData ที่กำหนดเองแทน

ตัวอย่างต่อไปนี้แสดงภาพพาโนรามาของสำนักงาน Google ที่ซิดนีย์ โปรดทราบว่าตัวอย่างนี้ไม่ได้ใช้แผนที่หรือภาพ Street View เริ่มต้น

TypeScript

function initPano() {
  // Set up Street View and initially set it visible. Register the
  // custom panorama provider function. Set the StreetView to display
  // the custom panorama 'reception' which we check for below.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map") as HTMLElement,
    { pano: "reception", visible: true }
  );

  panorama.registerPanoProvider(getCustomPanorama);
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(
  pano: string,
  zoom: number,
  tileX: number,
  tileY: number
): string {
  return (
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
    "panoReception1024-" +
    zoom +
    "-" +
    tileX +
    "-" +
    tileY +
    ".jpg"
  );
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano: string): google.maps.StreetViewPanoramaData {
  if (pano === "reception") {
    return {
      location: {
        pano: "reception",
        description: "Google Sydney - Reception",
      },
      links: [],
      // The text for the copyright control.
      copyright: "Imagery (c) 2010 Google",
      // The definition of the tiles for this panorama.
      tiles: {
        tileSize: new google.maps.Size(1024, 512),
        worldSize: new google.maps.Size(2048, 1024),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl,
      },
    };
  }
  // @ts-ignore TODO fix typings
  return null;
}

declare global {
  interface Window {
    initPano: () => void;
  }
}
window.initPano = initPano;

JavaScript

function initPano() {
  // Set up Street View and initially set it visible. Register the
  // custom panorama provider function. Set the StreetView to display
  // the custom panorama 'reception' which we check for below.
  const panorama = new google.maps.StreetViewPanorama(
    document.getElementById("map"),
    { pano: "reception", visible: true },
  );

  panorama.registerPanoProvider(getCustomPanorama);
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
  return (
    "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
    "panoReception1024-" +
    zoom +
    "-" +
    tileX +
    "-" +
    tileY +
    ".jpg"
  );
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano) {
  if (pano === "reception") {
    return {
      location: {
        pano: "reception",
        description: "Google Sydney - Reception",
      },
      links: [],
      // The text for the copyright control.
      copyright: "Imagery (c) 2010 Google",
      // The definition of the tiles for this panorama.
      tiles: {
        tileSize: new google.maps.Size(1024, 512),
        worldSize: new google.maps.Size(2048, 1024),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl,
      },
    };
  }
  // @ts-ignore TODO fix typings
  return null;
}

window.initPano = initPano;

CSS

/* 
 * Always set the map height explicitly to define the size of the div element
 * that contains the map. 
 */
#map {
  height: 100%;
}

/* 
 * Optional: Makes the sample page fill the window. 
 */
html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

HTML

<html>
  <head>
    <title>Custom Street View Panoramas</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="map"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง

ผู้ให้บริการภาพพาโนรามาที่กำหนดเองจะแสดงการ์ดที่เหมาะสมด้วยรหัสพาโนรามา ระดับการซูม และพิกัดของการ์ดพาโนรามาที่ส่งไป เนื่องจากการเลือกรูปภาพขึ้นอยู่กับค่าที่ส่งผ่านเหล่านี้ จึงมีประโยชน์ในการตั้งชื่อรูปภาพที่จะเลือกแบบเป็นโปรแกรมได้ด้วยค่าที่ส่งผ่านดังกล่าว เช่น pano_zoom_tileX_tileY.png

ตัวอย่างต่อไปนี้เป็นการเพิ่มลูกศรอีกอันหนึ่งให้กับรูปภาพ ซึ่งนอกเหนือจากลูกศรนำทาง Street View เริ่มต้น ซึ่งชี้ไปที่ Google Sydney และลิงก์ไปยังภาพที่กำหนดเอง

TypeScript

let panorama: google.maps.StreetViewPanorama;

// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
let outsideGoogle: google.maps.StreetViewPanoramaData;

// StreetViewPanoramaData for a custom panorama: the Google Sydney reception.
function getReceptionPanoramaData(): google.maps.StreetViewPanoramaData {
  return {
    location: {
      pano: "reception", // The ID for this custom panorama.
      description: "Google Sydney - Reception",
      latLng: new google.maps.LatLng(-33.86684, 151.19583),
    },
    links: [
      {
        heading: 195,
        description: "Exit",
        pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano,
      },
    ],
    copyright: "Imagery (c) 2010 Google",
    tiles: {
      tileSize: new google.maps.Size(1024, 512),
      worldSize: new google.maps.Size(2048, 1024),
      centerHeading: 105,
      getTileUrl: function (
        pano: string,
        zoom: number,
        tileX: number,
        tileY: number
      ): string {
        return (
          "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
          "panoReception1024-" +
          zoom +
          "-" +
          tileX +
          "-" +
          tileY +
          ".jpg"
        );
      },
    },
  };
}

function initPanorama() {
  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("street-view") as HTMLElement,
    { pano: (outsideGoogle.location as google.maps.StreetViewLocation).pano }
  );
  // Register a provider for the custom panorama.
  panorama.registerPanoProvider(
    (pano: string): google.maps.StreetViewPanoramaData => {
      if (pano === "reception") {
        return getReceptionPanoramaData();
      }
      // @ts-ignore TODO fix typings
      return null;
    }
  );

  // Add a link to our custom panorama from outside the Google Sydney office.
  panorama.addListener("links_changed", () => {
    if (
      panorama.getPano() ===
      (outsideGoogle.location as google.maps.StreetViewLocation).pano
    ) {
      panorama.getLinks().push({
        description: "Google Sydney",
        heading: 25,
        pano: "reception",
      });
    }
  });
}

function initMap(): void {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  new google.maps.StreetViewService()
    .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } })
    .then(({ data }: google.maps.StreetViewResponse) => {
      outsideGoogle = data;
      initPanorama();
    });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let panorama;
// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
let outsideGoogle;

// StreetViewPanoramaData for a custom panorama: the Google Sydney reception.
function getReceptionPanoramaData() {
  return {
    location: {
      pano: "reception", // The ID for this custom panorama.
      description: "Google Sydney - Reception",
      latLng: new google.maps.LatLng(-33.86684, 151.19583),
    },
    links: [
      {
        heading: 195,
        description: "Exit",
        pano: outsideGoogle.location.pano,
      },
    ],
    copyright: "Imagery (c) 2010 Google",
    tiles: {
      tileSize: new google.maps.Size(1024, 512),
      worldSize: new google.maps.Size(2048, 1024),
      centerHeading: 105,
      getTileUrl: function (pano, zoom, tileX, tileY) {
        return (
          "https://developers.google.com/maps/documentation/javascript/examples/full/images/" +
          "panoReception1024-" +
          zoom +
          "-" +
          tileX +
          "-" +
          tileY +
          ".jpg"
        );
      },
    },
  };
}

function initPanorama() {
  panorama = new google.maps.StreetViewPanorama(
    document.getElementById("street-view"),
    { pano: outsideGoogle.location.pano },
  );
  // Register a provider for the custom panorama.
  panorama.registerPanoProvider((pano) => {
    if (pano === "reception") {
      return getReceptionPanoramaData();
    }
    // @ts-ignore TODO fix typings
    return null;
  });
  // Add a link to our custom panorama from outside the Google Sydney office.
  panorama.addListener("links_changed", () => {
    if (panorama.getPano() === outsideGoogle.location.pano) {
      panorama.getLinks().push({
        description: "Google Sydney",
        heading: 25,
        pano: "reception",
      });
    }
  });
}

function initMap() {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  new google.maps.StreetViewService()
    .getPanorama({ location: { lat: -33.867386, lng: 151.195767 } })
    .then(({ data }) => {
      outsideGoogle = data;
      initPanorama();
    });
}

window.initMap = initMap;

CSS

html,
body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#street-view {
  height: 100%;
}

HTML

<html>
  <head>
    <title>Custom Street View Panorama Tiles</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
    <div id="street-view"></div>

    <!-- 
      The `defer` attribute causes the script to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises. See
      https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
ดูตัวอย่าง

ลองใช้ตัวอย่าง