บริการ 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 แก่ "Viewer" ของ 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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);

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
    title: "Cafe",
  });

  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
    title: "Bank",
  });

  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
    title: "Bus Stop",
  });

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

  // Set up the markers on the map
  const cafeMarker = new google.maps.Marker({
    position: { lat: 40.730031, lng: -73.991428 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=cafe|FFFF00",
    title: "Cafe",
  });
  const bankMarker = new google.maps.Marker({
    position: { lat: 40.729681, lng: -73.991138 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=dollar|FFFF00",
    title: "Bank",
  });
  const busMarker = new google.maps.Marker({
    position: { lat: 40.729559, lng: -73.990741 },
    map,
    icon: "https://chart.apis.google.com/chart?chst=d_map_pin_icon&chld=bus|FFFF00",
    title: "Bus Stop",
  });

  // 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

เมื่อนําทางระหว่าง 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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 ต้องเรียกไปยังเซิร์ฟเวอร์ภายนอก ด้วยเหตุนี้ คุณจึงต้องส่งเมธอด backback เพื่อดําเนินการตามคําขอให้เสร็จสมบูรณ์ วิธีเรียกกลับนี้จะประมวลผลผลลัพธ์

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

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

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

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

การตอบสนองของบริการ Street View

ฟังก์ชัน getPanorama() ต้องใช้ฟังก์ชันเรียกกลับเพื่อเรียกใช้เมื่อดึงข้อมูลผลลัพธ์จากบริการ Street View ฟังก์ชันเรียกกลับนี้จะแสดงชุดข้อมูลพาโนรามาภายในออบเจ็กต์ 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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 พาโนรามาแบบล้อมรอบทั้งหมดจะแสดงด้านล่าง

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

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

ทรงกลมที่มีวิวถนนแบบพาโนรามา

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

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

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 11.25 น.

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

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

สําหรับการ์ด 2:1 รูปภาพ 1 รูปที่ครอบคลุมพาโนรามาทั้งหมดจะเป็นรูป "โลก" (รูปภาพฐาน) ทั้งรูปที่ระดับการซูม 0 โดยแต่ละระดับการซูมจะเพิ่มขึ้นเป็น 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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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",
      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>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

    <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 callback 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>
ดูตัวอย่าง

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