ภาพรวม
Google Street View แสดงภาพพาโนรามา 360 องศาจากถนนที่กำหนดทั่วทั้งพื้นที่ขอบเขตการทำข่าว ความครอบคลุมของ API ของ Street View จะเหมือนกับความครอบคลุมของแอปพลิเคชัน Google Maps (https://maps.google.com/) ดูรายชื่อเมืองที่ Street View รองรับในปัจจุบันได้ที่เว็บไซต์ Google Maps
ตัวอย่างภาพ Street View แสดงอยู่ด้านล่าง
Maps JavaScript API มีบริการ Street View สำหรับรับและจัดการภาพที่ใช้ใน Google Maps Street View บริการ 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
async function init(): Promise<void> { // Request needed libraries. const [{ StreetViewPanorama }] = await Promise.all([ google.maps.importLibrary('streetView'), google.maps.importLibrary('maps'), ]); // Get the gmp-map element and its innerMap. const mapElement = document.querySelector('gmp-map')!; const innerMap = mapElement.innerMap; // Get the center of the map. const position = mapElement.center as google.maps.LatLng; // Create a new StreetViewPanorama, set its position, and attach it to the map. const panorama = new StreetViewPanorama(document.getElementById('pano')!, { position, pov: { heading: 34, pitch: 10, }, }); /** * Set the StreetViewPanorama so it displays in the pano element * rather than taking over the map. * This creates a link between the map and the panorama so that * the map is updated when the StreetViewPanorama position changes, * and the StreetViewPanorama is updated when the map changes. */ innerMap.setStreetView(panorama); } void init();
JavaScript
async function init() { // Request needed libraries. const [{ StreetViewPanorama }] = await Promise.all([ google.maps.importLibrary('streetView'), google.maps.importLibrary('maps'), ]); // Get the gmp-map element and its innerMap. const mapElement = document.querySelector('gmp-map'); const innerMap = mapElement.innerMap; // Get the center of the map. const position = mapElement.center; // Create a new StreetViewPanorama, set its position, and attach it to the map. const panorama = new StreetViewPanorama(document.getElementById('pano'), { position, pov: { heading: 34, pitch: 10, }, }); /** * Set the StreetViewPanorama so it displays in the pano element * rather than taking over the map. * This creates a link between the map and the panorama so that * the map is updated when the StreetViewPanorama position changes, * and the StreetViewPanorama is updated when the map changes. */ innerMap.setStreetView(panorama); } void init();
CSS
html, body { height: 100%; margin: 0; padding: 0; } body { display: flex; } gmp-map, #pano { flex: 1; height: 100%; }
HTML
<html>
<head>
<title>Street View split-map-panes</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.ts"></script>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "GOOGLE_MAPS_API_KEY",
});
</script>
</head>
<body>
<gmp-map
center="42.345573,-71.098326"
zoom="14"
map-id="DEMO_MAP_ID"></gmp-map>
<div id="pano"></div>
</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 ของโครงสร้างของคุณเอง คุณจะลบล้างพาโนรามาเริ่มต้น
ตัวอย่างต่อไปนี้แสดงเครื่องหมายที่ระบุสถานที่ต่างๆ รอบ Astor Place ในนครนิวยอร์ก สลับการแสดงผลเป็น Street View เพื่อแสดงเครื่องหมายที่แชร์ซึ่งแสดงภายใน StreetViewPanorama
TypeScript
const ASSET_BASE_URL = new URL('https://maps-docs-team.web.app/samples/streetview-overlays/dist/'); let panorama: google.maps.StreetViewPanorama; let innerMap: google.maps.Map; async function init() { // Request needed libraries. const [{ Marker }] = await Promise.all([ google.maps.importLibrary('marker'), google.maps.importLibrary('maps'), ]); // Set the location of Astor Place. const astorPlace = { lat: 40.729884, lng: -73.990988 }; const mapElement = document.querySelector('gmp-map')!; innerMap = mapElement.innerMap; document .getElementById('streetview-toggle-button')! .addEventListener('click', toggleStreetView); const cafeIcon = document.createElement('img'); cafeIcon.src = new URL('./cafe_icon.svg', ASSET_BASE_URL).href; const dollarIcon = document.createElement('img'); dollarIcon.src = new URL('./bank_icon.svg', ASSET_BASE_URL).href; const busIcon = document.createElement('img'); busIcon.src = new URL('./bus_icon.svg', ASSET_BASE_URL).href; // Set up the markers on the map new Marker({ position: { lat: 40.730031, lng: -73.991428 }, map: innerMap, title: 'Cafe', icon: cafeIcon.src, }); new Marker({ position: { lat: 40.729681, lng: -73.991138 }, map: innerMap, title: 'Bank', icon: dollarIcon.src, }); new Marker({ position: { lat: 40.729559, lng: -73.990741 }, map: innerMap, 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 = innerMap.getStreetView()!; // TODO fix type panorama.setPosition(astorPlace); panorama.setPov({ heading: 265, pitch: 0, }); } function toggleStreetView(): void { const toggle = panorama.getVisible(); if (!toggle) { panorama.setVisible(true); } else { panorama.setVisible(false); } } void init();
JavaScript
const ASSET_BASE_URL = new URL('https://maps-docs-team.web.app/samples/streetview-overlays/dist/'); let panorama; let innerMap; async function init() { // Request needed libraries. const [{ Marker }] = await Promise.all([ google.maps.importLibrary('marker'), google.maps.importLibrary('maps'), ]); // Set the location of Astor Place. const astorPlace = { lat: 40.729884, lng: -73.990988 }; const mapElement = document.querySelector('gmp-map'); innerMap = mapElement.innerMap; document .getElementById('streetview-toggle-button') .addEventListener('click', toggleStreetView); const cafeIcon = document.createElement('img'); cafeIcon.src = new URL('./cafe_icon.svg', ASSET_BASE_URL).href; const dollarIcon = document.createElement('img'); dollarIcon.src = new URL('./bank_icon.svg', ASSET_BASE_URL).href; const busIcon = document.createElement('img'); busIcon.src = new URL('./bus_icon.svg', ASSET_BASE_URL).href; // Set up the markers on the map new Marker({ position: { lat: 40.730031, lng: -73.991428 }, map: innerMap, title: 'Cafe', icon: cafeIcon.src, }); new Marker({ position: { lat: 40.729681, lng: -73.991138 }, map: innerMap, title: 'Bank', icon: dollarIcon.src, }); new Marker({ position: { lat: 40.729559, lng: -73.990741 }, map: innerMap, 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 = innerMap.getStreetView(); // TODO fix type panorama.setPosition(astorPlace); panorama.setPov({ heading: 265, pitch: 0, }); } function toggleStreetView() { const toggle = panorama.getVisible(); if (!toggle) { panorama.setVisible(true); } else { panorama.setVisible(false); } } void init(); export {};
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; } #streetview-toggle-button { height: 40px; display: flex; align-items: center; justify-content: center; padding: 0 17px; border: none; background: white; cursor: pointer; border-radius: 2px; box-shadow: 0 1px 4px -1px rgba(0, 0, 0, 0.3); margin: 10px 0px 10px -2px; font-family: Roboto, Arial, sans-serif; font-size: 18px; font-weight: 400; color: rgb(86, 86, 86); } #streetview-toggle-button:hover { background: #f4f4f4; color: #000; }
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>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<gmp-map map-id="DEMO_MAP_ID" center="40.729884, -73.990988" zoom="18">
<input
type="button"
value="Toggle Street View"
id="streetview-toggle-button"
slot="control-block-start-inline-start" />
</gmp-map>
</body>
</html>ลองใช้ตัวอย่าง
กิจกรรม Street View
เมื่อไปยังส่วนต่างๆ ระหว่าง Street View หรือปรับเปลี่ยนการวางแนว คุณอาจต้องการตรวจสอบเหตุการณ์หลายรายการที่บ่งบอกถึงการเปลี่ยนแปลงสถานะของ StreetViewPanorama ดังนี้
pano_changedจะเริ่มทำงานเมื่อรหัสภาพพาโนรามาแต่ละรายการมีการเปลี่ยนแปลง เหตุการณ์นี้ไม่ได้รับประกันว่าข้อมูลที่เกี่ยวข้องภายในภาพพาโนรามา (เช่น ลิงก์) จะมีการเปลี่ยนแปลงด้วยเมื่อเหตุการณ์นี้ทริกเกอร์ เหตุการณ์นี้ระบุเพียงว่ารหัสภาพพาโนรามามีการเปลี่ยนแปลง โปรดทราบว่ารหัสพาโนรามา (ซึ่งคุณใช้เพื่ออ้างอิงพาโนรามานี้ได้) จะคงที่ภายในเซสชันเบราว์เซอร์ปัจจุบันเท่านั้นposition_changedจะเริ่มทำงานเมื่อใดก็ตามที่ตำแหน่ง (LatLng) พื้นฐานของภาพพาโนรามามีการเปลี่ยนแปลง การหมุนภาพพาโนรามาจะไม่ทริกเกอร์เหตุการณ์นี้ โปรดทราบว่าคุณสามารถเปลี่ยนตำแหน่งที่อยู่เบื้องหลังของภาพพาโนรามาได้โดยไม่ต้องเปลี่ยนรหัสภาพพาโนรามาที่เชื่อมโยง เนื่องจาก API จะเชื่อมโยงรหัสภาพพาโนรามาที่ใกล้ที่สุดกับตำแหน่งของภาพพาโนรามาโดยอัตโนมัติpov_changedจะเริ่มทำงานเมื่อStreetViewPovของ Street View มีการเปลี่ยนแปลง โปรดทราบว่าเหตุการณ์นี้อาจเริ่มทำงานขณะที่ตำแหน่งและรหัสพาโนรามายังคงที่links_changedจะเริ่มทำงานเมื่อใดก็ตามที่ลิงก์ของ Street View มีการเปลี่ยนแปลง โปรดทราบว่าเหตุการณ์นี้อาจเริ่มทำงานแบบอะซิงโครนัสหลังจากมีการเปลี่ยนแปลงรหัสพาโนรามาที่ระบุผ่านpano_changedvisible_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"> </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"> </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ภายในช่องpanControlOptionszoomControlช่วยให้คุณซูมภายในรูปภาพได้ โดยค่าเริ่มต้น ตัวควบคุมนี้จะปรากฏที่ด้านขวาล่างของภาพพาโนรามา คุณสามารถเปลี่ยนลักษณะที่ปรากฏของตัวควบคุมได้โดยระบุZoomControlOptionsภายในช่องzoomControlOptionsaddressControlจะแสดงการวางซ้อนข้อความที่ระบุที่อยู่ของสถานที่ตั้งที่เชื่อมโยง และมีลิงก์สำหรับเปิดสถานที่ตั้งใน Google Maps คุณสามารถเปลี่ยนลักษณะที่ปรากฏของตัวควบคุมได้โดยระบุStreetViewAddressControlOptionsภายในช่องaddressControlOptionsfullscreenControlมีตัวเลือกให้เปิด Street View ในโหมดเต็มหน้าจอ คุณสามารถเปลี่ยนลักษณะที่ปรากฏของตัวควบคุมได้โดยระบุFullscreenControlOptionsภายในช่องfullscreenControlOptionsmotionTrackingControlมีตัวเลือกในการเปิดหรือปิดใช้การติดตามการเคลื่อนไหวในอุปกรณ์เคลื่อนที่ การควบคุมนี้จะปรากฏเฉพาะในอุปกรณ์ที่รองรับเหตุการณ์การวางแนวอุปกรณ์เท่านั้น โดยค่าเริ่มต้น ตัวควบคุมจะปรากฏที่บริเวณด้านขวาล่างของภาพพาโนรามา คุณเปลี่ยนตำแหน่งของตัวควบคุมได้โดยระบุ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 ใช้รูปภาพที่สอดคล้องกับการฉายภาพแบบ Equirectangular (Plate Carrée) การฉายภาพดังกล่าวประกอบด้วยมุมมองแนวนอน 360 องศา (แบบรอบทิศทาง) และมุมมองแนวตั้ง 180 องศา (จากบนลงล่าง) ขอบเขตการมองเห็นเหล่านี้จะทำให้ได้รูปภาพที่มีสัดส่วนภาพ 2:1 ภาพพาโนรามาแบบเต็ม 360 องศาแสดงอยู่ด้านล่าง

โดยทั่วไปแล้ว ภาพพาโนรามาจะได้มาจากการถ่ายภาพหลายๆ ภาพจากตำแหน่งเดียว แล้วนำมาต่อกันโดยใช้ซอฟต์แวร์พาโนรามา (ดูข้อมูลเพิ่มเติมได้ที่การเปรียบเทียบแอปพลิเคชันการต่อภาพของ 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 ทั้งหมด หากคุณระบุคอนเทนเนอร์ที่กว้างขึ้น บริการจะยังคงให้ขอบเขตการมองเห็นเดียวกันสำหรับระดับการซูมที่กำหนด แม้ว่าอาจเลือกชิ้นส่วนที่เหมาะสมกับความละเอียดนั้นมากกว่าแทนก็ตาม
เนื่องจากภาพพาโนรามาแต่ละภาพประกอบด้วยการฉายภาพแบบ Equirectangular การสร้างชิ้นส่วนภาพพาโนรามาจึงค่อนข้างง่าย เนื่องจากการฉายภาพจะให้รูปภาพที่มีสัดส่วนภาพ 2:1 ชิ้นส่วนที่มีสัดส่วน 2:1 จึงใช้งานได้ง่ายกว่า แม้ว่าชิ้นส่วนสี่เหลี่ยมจัตุรัสอาจให้ประสิทธิภาพที่ดีกว่าในแผนที่สี่เหลี่ยมจัตุรัส (เนื่องจากขอบเขตการมองเห็นจะเป็นสี่เหลี่ยมจัตุรัส)
สำหรับไทล์ 2:1 รูปภาพเดียวที่ครอบคลุมทั้งภาพพาโนรามาจะแสดง "โลก" ของภาพพาโนรามาทั้งหมด (รูปภาพฐาน) ที่ระดับการซูม 0 โดยระดับการซูมที่เพิ่มขึ้นแต่ละระดับจะมีไทล์ 4zoomLevel รายการ (เช่น ที่ระดับการซูม 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
async function init(): Promise<void> { // Request needed libraries. const [{ StreetViewPanorama }, { Size }] = await Promise.all([ google.maps.importLibrary('streetView'), google.maps.importLibrary('core'), ]); // Construct the appropriate StreetViewPanoramaData given // the passed pano IDs. function getCustomPanorama( pano: string ): google.maps.StreetViewPanoramaData | null { 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 Size(1024, 512), worldSize: new Size(2048, 1024), // The heading in degrees at the origin of the panorama // tile set. centerHeading: 105, getTileUrl: getCustomPanoramaTileUrl, }, }; } return null; } // 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 StreetViewPanorama(document.getElementById('map')!, { 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-${String(zoom)}-${String(tileX)}-${String(tileY)}.jpg`; } void init();
JavaScript
async function init() { // Request needed libraries. const [{ StreetViewPanorama }, { Size }] = await Promise.all([ google.maps.importLibrary('streetView'), google.maps.importLibrary('core'), ]); // 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 Size(1024, 512), worldSize: new Size(2048, 1024), // The heading in degrees at the origin of the panorama // tile set. centerHeading: 105, getTileUrl: getCustomPanoramaTileUrl, }, }; } return null; } // 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 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-${String(zoom)}-${String(tileX)}-${String(tileY)}.jpg`; } void init();
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>
<script>
// prettier-ignore
(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
key: "GOOGLE_MAPS_API_KEY"
});
</script>
</head>
<body>
<div id="map"></div>
</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>