סקירה כללית
Google Street View מספק תצוגות פנורמיות של 360 מעלות מכבישים ייעודיים בכל היקף גיאוגרפי שלו. הכיסוי של Street View ב-API זהה לכיסוי באפליקציית מפות Google (https://maps.google.com/). רשימת הערים שנתמכות כרגע ב-Street View זמינה באתר מפות Google.
למטה מוצגת תמונה לדוגמה של Street View.
Maps JavaScript API מספק שירות Street View כדי לקבל את התמונות שמוצגות ב-Street View במפות Google ולבצע בהן שינויים. השירות הזה של 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.
כשהמשתמש מציב את סמן האטב-איש ברחוב, המפה מתעדכנת ומציגה פנורמה ב-Street View של המיקום שצוין.
תמונות פנורמיות ב-Street View
כדי להציג תמונות Street View, משתמשים באובייקט StreetViewPanorama, שמספק ממשק API ל "מציג" של Street View. כל מפה מכילה פנורמה ב-Street View כברירת מחדל, שאפשר לאחזר על ידי קריאה ל-method getStreetView() של המפה. כשמוסיפים למפה פקד של Street View על ידי הגדרת האפשרות streetViewControl לערך true, הפקד של האיש הצהוב מתחבר באופן אוטומטי לתמונת הפנורמה הזו של Street View שמוגדרת כברירת מחדל.
אפשר גם ליצור אובייקט StreetViewPanorama משלכם ולהגדיר את המפה כך שתשתמש בו במקום בברירת המחדל, על ידי הגדרת המאפיין streetView של המפה באופן מפורש לאובייקט שנוצר. אם אתם רוצים לשנות את התנהגות ברירת המחדל, כמו שיתוף אוטומטי של שכבות-על בין המפה לבין הפנורמה, אתם יכולים לשנות את הגדרת ברירת המחדל של הפנורמה. (ראו שכבות-על ב-Street View בהמשך).
קונטיינרים של Street View
במקום זאת, יכול להיות שתרצו להציג StreetViewPanorama
בתוך רכיב DOM נפרד, בדרך כלל רכיב <div>.
פשוט מעבירים את רכיב ה-DOM בתוך ה-constructor של StreetViewPanorama. כדי שהתמונות יוצגו בצורה אופטימלית, אנחנו ממליצים על גודל מינימלי של 200 פיקסלים על 200 פיקסלים.
הערה: למרות שהפונקציונליות של Street View מיועדת לשימוש בשילוב עם מפה, השימוש הזה לא חובה. אפשר להשתמש באובייקט Street View עצמאי בלי מפה.
מיקומים ונקודת מבט (POV) ב-Street View
ה-constructor של StreetViewPanorama מאפשר גם להגדיר את המיקום ואת נקודת המבט ב-Street View באמצעות הפרמטר StreetViewOptions. אפשר להפעיל את
setPosition() ו-setPov() על האובייקט אחרי הבנייה כדי לשנות את המיקום ואת נקודת המבט שלו.
המיקום ב-Street View מגדיר את המיקום של מיקוד המצלמה בתמונה, אבל לא את הכיוון של המצלמה בתמונה הזו. לשם כך, האובייקט StreetViewPov מגדיר שני מאפיינים:
-
heading(ברירת המחדל היא0) מגדיר את זווית הסיבוב סביב מיקום המצלמה במעלות ביחס לצפון האמיתי. הכיוונים נמדדים בכיוון השעון (90 מעלות זה מזרח אמיתי). -
pitch(ברירת המחדל היא0) מגדיר את השונות בזווית "למעלה" או "למטה" מהזווית הראשונית של המצלמה, שלרוב (אבל לא תמיד) היא אופקית שטוחה. (לדוגמה, תמונה שצולמה על גבעה תציג כנראה זווית ברירת מחדל שאינה אופקית). זווית העלרוד נמדדת בערכים חיוביים כשמסתכלים למעלה (עד 90+ מעלות ישר למעלה ואורתוגונלי לעלרוד שמוגדר כברירת מחדל) ובערכים שליליים כשמסתכלים למטה (עד 90- מעלות ישר למטה ואורתוגונלי לעלרוד שמוגדר כברירת מחדל).
האובייקט StreetViewPov משמש בדרך כלל לקביעת נקודת המבט של מצלמת Street View. אפשר גם לקבוע את נקודת המבט של הצלם – בדרך כלל הכיוון שאליו פנו המכונית או התלת-אופן – באמצעות השיטה StreetViewPanorama.getPhotographerPov().
הקוד הבא מציג מפה של בוסטון עם תצוגה ראשונית של פנוויי פארק. אם תבחרו את האטב-איש ותגררו אותו למיקום נתמך במפה, הפנורמה ב-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_changed.- האירוע
visible_changedמופעל בכל פעם שסטטוס החשיפה של Street View משתנה. חשוב לזכור שהאירוע הזה עשוי לפעול באופן אסינכרוני אחרי שינוי במזהה הפנורמה שצוין באמצעותpano_changed.
הקוד הבא ממחיש איך אפשר לטפל באירועים האלה כדי לאסוף נתונים על ה-StreetViewPanorama הבסיסי:
TypeScript
function initPano() { const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano") as HTMLElement, { position: { lat: 37.869, lng: -122.255 }, pov: { heading: 270, pitch: 0, }, visible: true, } ); panorama.addListener("pano_changed", () => { const panoCell = document.getElementById("pano-cell") as HTMLElement; panoCell.innerHTML = panorama.getPano(); }); panorama.addListener("links_changed", () => { const linksTable = document.getElementById("links_table") as HTMLElement; while (linksTable.hasChildNodes()) { linksTable.removeChild(linksTable.lastChild as ChildNode); } const links = panorama.getLinks(); for (const i in links) { const row = document.createElement("tr"); linksTable.appendChild(row); const labelCell = document.createElement("td"); labelCell.innerHTML = "<b>Link: " + i + "</b>"; const valueCell = document.createElement("td"); valueCell.innerHTML = links[i].description as string; linksTable.appendChild(labelCell); linksTable.appendChild(valueCell); } }); panorama.addListener("position_changed", () => { const positionCell = document.getElementById( "position-cell" ) as HTMLElement; (positionCell.firstChild as HTMLElement).nodeValue = panorama.getPosition() + ""; }); panorama.addListener("pov_changed", () => { const headingCell = document.getElementById("heading-cell") as HTMLElement; const pitchCell = document.getElementById("pitch-cell") as HTMLElement; (headingCell.firstChild as HTMLElement).nodeValue = panorama.getPov().heading + ""; (pitchCell.firstChild as HTMLElement).nodeValue = panorama.getPov().pitch + ""; }); } declare global { interface Window { initPano: () => void; } } window.initPano = initPano;
JavaScript
function initPano() { const panorama = new google.maps.StreetViewPanorama( document.getElementById("pano"), { position: { lat: 37.869, lng: -122.255 }, pov: { heading: 270, pitch: 0, }, visible: true, }, ); panorama.addListener("pano_changed", () => { const panoCell = document.getElementById("pano-cell"); panoCell.innerHTML = panorama.getPano(); }); panorama.addListener("links_changed", () => { const linksTable = document.getElementById("links_table"); while (linksTable.hasChildNodes()) { linksTable.removeChild(linksTable.lastChild); } const links = panorama.getLinks(); for (const i in links) { const row = document.createElement("tr"); linksTable.appendChild(row); const labelCell = document.createElement("td"); labelCell.innerHTML = "<b>Link: " + i + "</b>"; const valueCell = document.createElement("td"); valueCell.innerHTML = links[i].description; linksTable.appendChild(labelCell); linksTable.appendChild(valueCell); } }); panorama.addListener("position_changed", () => { const positionCell = document.getElementById("position-cell"); positionCell.firstChild.nodeValue = panorama.getPosition() + ""; }); panorama.addListener("pov_changed", () => { const headingCell = document.getElementById("heading-cell"); const pitchCell = document.getElementById("pitch-cell"); headingCell.firstChild.nodeValue = panorama.getPov().heading + ""; pitchCell.firstChild.nodeValue = panorama.getPov().pitch + ""; }); } window.initPano = initPano;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; } #floating-panel { position: absolute; top: 10px; left: 25%; z-index: 5; background-color: #fff; padding: 5px; border: 1px solid #999; text-align: center; font-family: "Roboto", "sans-serif"; line-height: 30px; padding-left: 10px; } #pano { width: 50%; height: 100%; float: left; } #floating-panel { width: 45%; height: 100%; float: right; text-align: left; overflow: auto; position: static; border: 0px solid #999; }
HTML
<html>
<head>
<title>Street View Events</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="pano"></div>
<div id="floating-panel">
<table>
<tr>
<td><b>Position</b></td>
<td id="position-cell"> </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בשדהpanControlOptions.zoomControlמאפשרת להגדיל את התמונה. האפשרות הזו מופיעה כברירת מחדל בפינה השמאלית התחתונה של התמונה הפנורמית. אפשר לשנות את המראה של הפקד על ידי הוספתZoomControlOptionsבשדהzoomControlOptions.addressControlמספק שכבת-על של טקסט שמציינת את הכתובת של המיקום המשויך, ומציעה קישור לפתיחת המיקום במפות Google. אפשר לשנות את המראה של הפקד על ידי הוספתStreetViewAddressControlOptionsבשדהaddressControlOptions.fullscreenControlמאפשר לפתוח את Street View במצב מסך מלא. אפשר לשנות את המראה של הפקד על ידי הוספתFullscreenControlOptionsבשדהfullscreenControlOptions.motionTrackingControlמאפשר להפעיל או להשבית את מעקב התנועה במכשירים ניידים. האפשרות הזו מופיעה רק במכשירים שתומכים באירועים של כיוון המכשיר. כברירת מחדל, הפקד מופיע ליד הפינה הימנית התחתונה של הפנורמה. אפשר לשנות את המיקום של הפקד באמצעותMotionTrackingControlOptions. מידע נוסף זמין בקטע בנושא מעקב תנועה.linksControlמספק חיצי הדרכה על התמונה כדי לעבור לתמונות פנורמיות סמוכות.- פקד סגירה מאפשר למשתמש לסגור את Street View. אפשר להפעיל או להשבית את פקד הסגירה על ידי הגדרת
enableCloseButtonלערךtrueאוfalse.
בדוגמה הבאה משנים את אמצעי הבקרה שמוצגים ב-Street View המשויך ומסירים את הקישורים של התצוגה:
TypeScript
function initPano() { // Note: constructed panorama objects have visible: true // set by default. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map") as HTMLElement, { position: { lat: 42.345573, lng: -71.098326 }, addressControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER, }, linksControl: false, panControl: false, enableCloseButton: false, } ); } declare global { interface Window { initPano: () => void; } } window.initPano = initPano;
JavaScript
function initPano() { // Note: constructed panorama objects have visible: true // set by default. const panorama = new google.maps.StreetViewPanorama( document.getElementById("map"), { position: { lat: 42.345573, lng: -71.098326 }, addressControlOptions: { position: google.maps.ControlPosition.BOTTOM_CENTER, }, linksControl: false, panControl: false, enableCloseButton: false, }, ); } window.initPano = initPano;
CSS
/* * Always set the map height explicitly to define the size of the div element * that contains the map. */ #map { height: 100%; } /* * Optional: Makes the sample page fill the window. */ html, body { height: 100%; margin: 0; padding: 0; }
HTML
<html>
<head>
<title>Street View Controls</title>
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.js"></script>
</head>
<body>
<div id="map"></div>
<!--
The `defer` attribute causes the script to execute after the full HTML
document has been parsed. For non-blocking uses, avoiding race conditions,
and consistent behavior across browsers, consider loading using Promises. See
https://developers.google.com/maps/documentation/javascript/load-maps-js-api
for more information.
-->
<script
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
defer
></script>
</body>
</html>גישה ישירה לנתוני Street View
יכול להיות שתרצו לקבוע באופן פרוגרמטי את הזמינות של נתוני Street View, או להחזיר מידע על פנורמות מסוימות, בלי שתצטרכו לבצע שינויים ישירים במפה או בפנורמה. כדי לעשות זאת, אפשר להשתמש באובייקט StreetViewService, שמספק ממשק לנתונים שמאוחסנים בשירות Street View של Google.
בקשות לשירותי Street View
הגישה לשירות Street View היא אסינכרונית, כי ה-Google Maps API צריך לבצע קריאה לשרת חיצוני. לכן, צריך להעביר שיטת קריאה חוזרת (callback) שתופעל בסיום הבקשה. שיטת הקריאה החוזרת הזו מעבדת את התוצאה.
אפשר לשלוח בקשות ל-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>
<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. באמצעות תמונות פנורמיות בהתאמה אישית, אתם יכולים להציג את החלק הפנימי של מבנים, נופים ממקומות יפים או כל דבר אחר שאתם יכולים לדמיין. אתם יכולים אפילו
לקשר את התמונות הפנורמיות המותאמות אישית האלה לתמונות הפנורמיות הקיימות של Google
ב-Street View.
כדי להגדיר קבוצה של תמונות פנורמיות בהתאמה אישית, צריך לבצע את השלבים הבאים:
- יוצרים תמונה פנורמית בסיסית לכל תמונה פנורמית בהתאמה אישית. תמונת הבסיס צריכה להיות ברזולוציה הגבוהה ביותר שבה רוצים להציג את התמונה בהגדלה.
- (אופציונלי, אבל מומלץ) יוצרים קבוצה של משבצות פנורמיות ברמות זום שונות מהתמונה הבסיסית.
- יוצרים קישורים בין התמונות הפנורמיות המותאמות אישית.
- (אופציונלי) הגדירו תמונות פנורמיות של "כניסה" בתמונות Street View הקיימות של Google, והתאימו אישית את הקישורים אל הקבוצה בהתאמה אישית וממנה אל הקבוצה הרגילה.
- מגדירים מטא-נתונים לכל תמונה פנורמית באובייקט
StreetViewPanoramaData. - מטמיעים פונקציה שקובעת את הנתונים והתמונות של הפנורמה בהתאמה אישית, ומגדירים את הפונקציה הזו כ-handler בהתאמה אישית בתוך האובייקט
StreetViewPanorama.
בקטעים הבאים מוסבר על התהליך הזה.
יצירת תמונות פנורמיות בהתאמה אישית
כל פנורמה ב-Street View היא תמונה או קבוצת תמונות שמספקות תצוגה מלאה של 360 מעלות ממיקום אחד.
האובייקט StreetViewPanorama משתמש בתמונות שתואמות להיטל שווה-זווית (Plate Carrée). היטל כזה מכיל 360 מעלות של תצוגה אופקית (תצוגה פנורמית מלאה) ו-180 מעלות של תצוגה אנכית (מלמעלה עד למטה). שדות הראייה האלה יוצרים תמונה ביחס גובה-רוחב של 2:1. למטה מוצגת תמונה פנורמית מלאה.

תמונות פנורמיות נוצרות בדרך כלל על ידי צילום של כמה תמונות ממיקום אחד וחיבור שלהן באמצעות תוכנה פנורמית. (למידע נוסף, אפשר לעיין בערך Comparison of photo stitching applications בוויקיפדיה). התמונות האלה צריכות להיות מאותו "מיקום" של המצלמה, שממנו צולמה כל אחת מהתמונות הפנורמיות. התמונה הפנורמית ב-360 מעלות שנוצרת יכולה להגדיר היטל על כדור, כשהתמונה עוטפת את המשטח הדו-ממדי של הכדור.

ההתייחסות לתמונה הפנורמית כהיטל על כדור עם מערכת קואורדינטות ישרת-זווית היא יתרון כשמחלקים את התמונה למשבצות ישרות-זווית, ומציגים תמונות על סמך קואורדינטות מחושבות של משבצות.
יצירת משבצות פנורמה בהתאמה אישית
ב-Street View אפשר גם להציג רמות שונות של פירוט בתמונה באמצעות פקד הזום, שמאפשר להגדיל ולהקטין את התצוגה שמוגדרת כברירת מחדל. באופן כללי, Street View מספק חמש רמות של רזולוציית זום לכל תמונה פנורמית נתונה. אם תסתמכו על תמונה פנורמית אחת כדי להציג את כל רמות הזום, התמונה הזו תהיה בהכרח גדולה מאוד ותאט באופן משמעותי את האפליקציה, או שהרזולוציה שלה תהיה נמוכה מאוד ברמות זום גבוהות יותר, כך שתוצג תמונה מפוקסלת. למרבה המזל, אנחנו יכולים להשתמש בתבנית עיצוב דומה לזו שמשמשת להצגת משבצות המפה של Google ברמות זום שונות, כדי לספק תמונות ברזולוציה מתאימה לתמונות פנורמיות בכל רמת זום.
כשהאובייקט StreetViewPanorama נטען בפעם הראשונה, כברירת מחדל מוצגת תמונה שמורכבת מ-25% (קשת של 90 מעלות) מהרוחב האופקי של הפנורמה ברמת זום 1. התצוגה הזו תואמת פחות או יותר לשדה הראייה הרגיל של בני אדם. הקטנת התצוגה (zoom out) מברירת המחדל הזו מספקת קשת רחבה יותר, והגדלת התצוגה (zoom in) מצמצמת את שדה הראייה לקשת קטנה יותר. 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, תמונה אחת שכוללת את כל הפנורמה מייצגת את כל "עולם" הפנורמה (תמונת הבסיס) ברמת זום 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>