שירות Street View

סקירה כללית

בחירת פלטפורמה: Android iOS JavaScript

Google Street View מספקת תמונות פנורמיות של 360 מעלות מכבישים ייעודיים באזור הכיסוי של המקום. כיסוי ה-API של Street View זהה לזה של אפליקציית מפות Google (https://maps.google.com/). רשימת הערים הנתמכות כרגע ב-Street View זמינה באתר מפות Google.

בהמשך מוצגת תמונה לדוגמה של Street View.


Maps JavaScript API מספק שירות Street View לצורך קבלה וטיפול בתמונות שנמצאות בשימוש במפות Google ב-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.

כשהמשתמש מפיל את סמן האטב-איש ברחוב, המפה מתעדכנת ומציגה תמונת 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 בתוך ה-build של StreetViewPanorama. לתצוגה אופטימלית של תמונות, מומלץ להשתמש בגודל מינימלי של 200 פיקסלים על 200 פיקסלים.

הערה: אמנם הפונקציונליות של Street View מיועדת לשימוש בשילוב עם מפה, אך השימוש הזה אינו הכרחי. אפשר להשתמש באובייקט Street View עצמאי ללא מפה.

מיקומים של Street View ונקודת מבט (POV)

הבנאי StreetViewPanorama גם מאפשר להגדיר את המיקום ואת נקודת המבט ב-Street View באמצעות הפרמטר StreetViewOptions. אפשר לקרוא ל- setPosition() ול-setPov() לאובייקט אחרי הבנייה כדי לשנות את המיקום ואת נקודת המבט (POV) שלו.

המיקום של Street View מגדיר את המיקום של מיקוד המצלמה לגבי תמונה, אבל הוא לא מגדיר את כיוון המצלמה עבור אותה תמונה. לשם כך, האובייקט StreetViewPov מגדיר שני מאפיינים:

  • heading (ברירת המחדל 0) מגדיר את זווית הסיבוב סביב מיקום המצלמה במעלות יחסית מהצפון האמיתי. הכותרות נמדדות בכיוון השעון (90 מעלות מייצגות את כיוון החוף המזרחי).
  • ההגדרה pitch (ברירת המחדל 0) מגדירה את שונות הזווית 'למעלה' או 'למטה' מגובה ברירת המחדל הראשונית של המצלמה, שלרוב (אבל לא תמיד) לרוחב של פורמט אופקי. (לדוגמה, סביר להניח שתמונה שצולמה על גבעה תציג גובה צליל שמוגדר כברירת מחדל שאינו אופקי). זוויות גובה צליל נמדדות בערכים חיוביים שמביטים למעלה (ל- +90 מעלות ישר למעלה ואורתוגונלי לגובה ברירת המחדל) וערכים שליליים כשמסתכלים למטה (ל- -90 מעלות ישר למטה ואורתוגונלי לגובה ברירת המחדל).

לרוב, האובייקט StreetViewPov משמש לקביעת נקודת המבט של מצלמת Street View. ניתן גם להשתמש ב-method StreetViewPanorama.getPhotographerPov() כדי להבין את נקודת המבט של הצלם — בדרך כלל את הכיוון שאליו פונה המכונית או התלת-אופן.

הקוד הבא מציג מפה של בוסטון עם תצוגה ראשונית של פנוויי פארק. בחירה באטב-איש וגרירתו למיקום נתמך במפה תשנה את הפנורמה של Street View:

TypeScript

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

  map.setStreetView(panorama);
}

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

JavaScript

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

  map.setStreetView(panorama);
}

window.initialize = initialize;

CSS

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

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

HTML

<html>
  <head>
    <title>Street View split-map-panes</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initialize&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

מעקב תנועה במכשירים ניידים

במכשירים שתומכים באירועי כיוון של מכשיר, ה-API מאפשר למשתמשים לשנות את נקודת המבט של Street View על סמך תנועת המכשיר. המשתמשים יכולים להביט סביב על ידי הזזת המכשירים שלהם. התהליך הזה נקרא 'מעקב אחר תנועה' או 'מעקב אחר סיבוב המכשיר'.

כמפתחי אפליקציות, תוכלו לשנות את התנהגות ברירת המחדל באופן הבא:

  • הפעלה או השבתה של פונקציונליות מעקב התנועה. כברירת מחדל, מעקב התנועה מופעל בכל מכשיר שתומך בו. הדוגמה הבאה משביתה את המעקב אחר התנועה, אבל משאירה את הפקד של מעקב התנועה גלוי. (לתשומת ליבכם: המשתמש יכול להפעיל את מעקב התנועה על ידי הקשה על הפקד).
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false
        });
    
  • הסתרה או הצגה של פקד מעקב התנועה. כברירת מחדל, הפקד מוצג במכשירים שתומכים במעקב אחר תנועה. המשתמש יכול להקיש על הפקד כדי להפעיל או להשבית את המעקב אחר התנועה. חשוב לשים לב: אם המכשיר לא תומך במעקב אחר תנועה, הפקד לא יופיע, ללא קשר לערך של motionTrackingControl.

    הדוגמה הבאה משביתה את מעקב התנועה ואת בקרת המעקב אחר התנועה. במקרה כזה, המשתמש לא יכול להפעיל את מעקב התנועה:

    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false,
          motionTrackingControl: false
        });
    
  • לשנות את מיקום ברירת המחדל של פקד מעקב התנועה. כברירת מחדל, הפקד מופיע ליד הפינה הימנית התחתונה של הפנורמה (מיקום RIGHT_BOTTOM). הדוגמה הבאה מגדירה את מיקום הפקד לתחתית המסך:
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTrackingControlOptions: {
            position: google.maps.ControlPosition.LEFT_BOTTOM
          }
        });
    

כדי לראות את מעקב התנועה בפעולה, אפשר לצפות בדוגמה הבאה במכשיר נייד (או בכל מכשיר שתומך באירועי כיוון מכשיר):


להצגת דוגמה

שכבות-על ב-Street View

אובייקט StreetViewPanorama המוגדר כברירת מחדל תומך בתצוגה המקורית של שכבות-על במפה. בדרך כלל, שכבות-על מופיעות ב'ברמת הרחוב' ועוגנות ב-LatLng מיקומים. (לדוגמה, הסמנים יופיעו כשהזנבות שלהם מוצמדים למישור האופקי של המיקום, בתוך הפנורמה של Street View.)

בשלב זה, סוגי שכבות-העל שנתמכים בפנורמות Street View מוגבלים ל-Marker, ל-InfoWindow ול-OverlayView בהתאמה אישית. ניתן להציג שכבות-על שמוצגות במפה בפנורמה של Street View באמצעות התייחסות לפנורמה כתחליף לאובייקט Map, קריאה ל-setMap() והעברת הערך StreetViewPanorama כארגומנט במקום כמפה. באופן דומה, ניתן לפתוח חלונות מידע גם בפנורמה של Street View על ידי קריאה ל-open(), תוך העברה של StreetViewPanorama() במקום במפה.

כמו כן, כשיוצרים מפה עם StreetViewPanorama כברירת מחדל, כל הסמנים שנוצרו במפה משותפים באופן אוטומטי עם תמונת ה-Street View המשויכת למפה, בתנאי שאפשר לראות את תמונת הפנורמה. כדי לאחזר את תמונת ברירת המחדל של Street View, צריך לקרוא לפונקציה getStreetView() באובייקט Map. חשוב לשים לב שאם מגדירים במפורש את המאפיין streetView של המפה ל-StreetViewPanorama של המבנה שלך, המערכת מבטלת את ברירת המחדל של תמונת הפנורמה.

בדוגמה הבאה מוצגים סמנים שמציינים מיקומים שונים סביב אסטור פלייס, העיר ניו יורק. החלפת המצב של התצוגה ל-Street View כדי להציג את הסמנים המשותפים שמוצגים בתוך StreetViewPanorama.

TypeScript

let panorama: google.maps.StreetViewPanorama;

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

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

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

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

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

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

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

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

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

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

JavaScript

let panorama;

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

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

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

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

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

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

window.initMap = initMap;

CSS

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

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

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

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

HTML

<html>
  <head>
    <title>Overlays Within Street View</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

אירועים של Street View

במהלך ניווט בין Street View או שינוי הכיוון שלו, מומלץ לעקוב אחרי מספר אירועים שמעידים על שינויים במצב של StreetViewPanorama:

  • pano_changed מופעל בכל פעם שמזהה התמונה הפנורמית משתנה. האירוע הזה לא מבטיח שהנתונים המשויכים בפנורמה (כמו הקישורים) ישתנו גם הם עד שהאירוע הזה יופעל. האירוע הזה רק מציין שמזהה ה-Pano השתנה. חשוב לשים לב שמזהה הפנורמה (ניתן להשתמש בו כדי להפנות לפנורמה הזו) יציב רק במהלך ההפעלה הנוכחית של הדפדפן.
  • position_changed מופעלת בכל פעם שהמיקום (LatLng) הבסיס של התמונה הפנורמית משתנה. סיבוב תמונת פנורמה לא יפעיל את האירוע הזה. לתשומת ליבכם, אפשר לשנות את המיקום הבסיסי של התמונה הפנורמית בלי לשנות את מזהה הפנורמה שמשויך, כי ה-API ישייך באופן אוטומטי את מזהה הפנורמה הקרוב ביותר למיקום של התמונה הפנורמית.
  • pov_changed מופעלת בכל פעם שמשתנה StreetViewPov של Street View. לתשומת ליבך, האירוע הזה עשוי לפעול כל עוד המיקום ומזהה הפנורמה נשארים יציבים.
  • links_changed מופעלת בכל פעם שהקישורים של Street View משתנים. חשוב לשים לב שהאירוע הזה עשוי לפעול באופן אסינכרוני אחרי שינוי במזהה הפנורמה שצוין דרך pano_changed.
  • visible_changed מופעלת בכל פעם שהחשיפה של Street View משתנה. חשוב לשים לב שהאירוע הזה עשוי לפעול באופן אסינכרוני אחרי שינוי במזהה הפנורמה שצוין דרך pano_changed.

הקוד הבא מדגים איך אפשר לטפל באירועים האלה כדי לאסוף נתונים על מקור הנתונים StreetViewPanorama:

TypeScript

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

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

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

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

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

    const links = panorama.getLinks();

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

      linksTable.appendChild(row);

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

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

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

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

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

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

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

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

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

JavaScript

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

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

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

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

    const links = panorama.getLinks();

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

      linksTable.appendChild(row);

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

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

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

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

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

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

window.initPano = initPano;

CSS

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

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

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

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

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

HTML

<html>
  <head>
    <title>Street View Events</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

פקדי Street View

כשמציגים StreetViewPanorama, כברירת מחדל מופיעים מגוון פקדים בפנורמה. כדי להפעיל או להשבית את אמצעי הבקרה האלה, צריך להגדיר את השדות המתאימים ב StreetViewPanoramaOptions לערך true או false:

  • panControl מאפשר לסובב את הפנורמה. הפקד הזה מופיע כברירת מחדל כפקד משולב סטנדרטי של מצפן והזזה. כדי לשנות את מיקום הפקד, אפשר לציין PanControlOptions בשדה panControlOptions.
  • באמצעות zoomControl אפשר להגדיל את התצוגה בתוך התמונה. הפקד הזה מופיע כברירת מחדל ליד הפינה השמאלית התחתונה של הפנורמה. כדי לשנות את המראה של פקד הבקרה, אפשר להזין את הערך ZoomControlOptions בשדה zoomControlOptions.
  • addressControl מציג שכבת-על של טקסט שמציינת את הכתובת של המיקום המשויך, וכולל קישור לפתיחת המיקום במפות Google. כדי לשנות את המראה של פקד הבקרה, אפשר להזין את הערך StreetViewAddressControlOptions בשדה addressControlOptions.
  • בfullscreenControl יש אפשרות לפתוח את Street View במצב מסך מלא. כדי לשנות את המראה של פקד הבקרה, אפשר להזין את הערך FullscreenControlOptions בשדה fullscreenControlOptions.
  • בmotionTrackingControl יש אפשרות להפעיל או להשבית מעקב תנועה במכשירים ניידים. הפקד הזה מופיע רק במכשירים שתומכים באירועי כיוון מכשיר. כברירת מחדל, הפקד מופיע ליד הפינה השמאלית התחתונה של הפנורמה. כדי לשנות את מיקום הפקד, אפשר לספק את הערך MotionTrackingControlOptions. למידע נוסף, אפשר לעיין בקטע מעקב אחר תנועה.
  • ב-linksControl יש חיצי קו מנחה בתמונה, כדי לעבור לתמונות פנורמה סמוכות.
  • מתג סגירה מאפשר למשתמש לסגור את מציג Street View. אפשר להפעיל או להשבית את הפקד 'סגירה' על ידי הגדרת הערך של enableCloseButton לערך true או false.

בדוגמה הבאה משנים את הפקדים שמוצגים ב-Street View המשויך ומסירים את הקישורים של התצוגה:

TypeScript

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

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

JavaScript

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

window.initPano = initPano;

CSS

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

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

HTML

<html>
  <head>
    <title>Street View Controls</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

גישה ישירה לנתוני Street View

ייתכן שתרצה לקבוע באופן פרוגרמטי את הזמינות של נתוני Street View, או להחזיר מידע על תמונות פנורמה מסוימות, בלי שיהיה צורך במניפולציה ישירה של המפה או הפנורמה. אפשר לעשות זאת באמצעות האובייקט StreetViewService, שמספק ממשק לנתונים שמאוחסנים בשירות Street View של Google.

בקשות לשירות Street View

הגישה לשירות Street View היא אסינכרונית, כי Google Maps API צריך לבצע קריאה לשרת חיצוני. לכן, צריך להגדיר שיטת callback כדי להפעיל את התכונה אחרי שתשלימו את הבקשה. שיטת הקריאה החוזרת הזו מעבדת את התוצאה.

אפשר לשלוח בקשות אל StreetViewService באמצעות StreetViewPanoRequest או StreetViewLocationRequest.

בקשה עם StreetViewPanoRequest מחזירה נתונים של פנורמה באמצעות מזהה הפניה שמזהה באופן ייחודי את הפנורמה. שימו לב שמזהי ההפניה האלה יציבים רק לכל משך החיים של התמונות של אותה פנורמה.

בקשה באמצעות StreetViewLocationRequest מחפשת נתוני פנורמה במיקום מסוים באמצעות הפרמטרים הבאים:

  • location מציין את המיקום (קו רוחב וקו אורך) שבו רוצים לחפש פנורמה.
  • preference מגדיר העדפה לבחירת המיקום הפנורמי ברדיוס: זו הקרובה ביותר למיקום שצוין או התמונה הטובה ביותר שנמצאת ברדיוס.
  • radius מגדיר רדיוס שצוין במטרים, שבו יש לחפש פנורמה, במרכז לפי קו הרוחב וקו האורך שצוינו. אם הערך לא מצוין, ברירת המחדל היא 50.
  • source מציין את המקור של תמונות פנורמה לחיפוש. הערכים התקינים הם:
    • default משתמש במקורות ברירת המחדל עבור Street View. החיפוש אינו מוגבל למקורות ספציפיים.
    • outdoor מגביל את החיפושים לאוספים בחוץ. שים לב שייתכן כי לא קיימות תמונות פנורמיות בחוץ עבור המיקום שצוין.

תגובות של שירות Street View

הפונקציה getPanorama() צריכה פונקציית callback כדי לפעול לאחר אחזור תוצאה משירות Street View. פונקציית הקריאה החוזרת מחזירה קבוצה של נתוני פנורמה בתוך אובייקט StreetViewPanoramaData וקוד StreetViewStatus שמציין את סטטוס הבקשה, בסדר הזה.

מפרט האובייקט StreetViewPanoramaData מכיל מטא-נתונים על פנורמה ב-Street View בפורמט הבא:

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

שימו לב שאובייקט הנתונים הזה אינו אובייקט StreetViewPanorama עצמו. כדי ליצור אובייקט Street View באמצעות הנתונים האלה, צריך ליצור StreetViewPanorama ולקרוא ל-setPano(), ולהעביר לו את המזהה כפי שצוין בשדה location.pano שמוחזר.

הקוד status עשוי להחזיר אחד מהערכים הבאים:

  • OK מציין שהשירות מצא תמונת פנורמה תואמת.
  • ZERO_RESULTS מציין שהשירות לא הצליח למצוא תמונת פנורמה שתואמת לקריטריונים שהועברו.
  • UNKNOWN_ERROR מציין שלא ניתן היה לעבד בקשה ל-Street View, אך הסיבה המדויקת אינה ידועה.

הקוד הבא יוצר StreetViewService שמגיב לקליקים של משתמשים על מפה על ידי יצירת סמנים, שבלחיצה עליהם, מוצג StreetViewPanorama של המיקום הזה. הקוד משתמש בתוכן של StreetViewPanoramaData שמוחזר מהשירות.

TypeScript

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

let map: google.maps.Map;

let panorama: google.maps.StreetViewPanorama;

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

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

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

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

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

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

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

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

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

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

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

JavaScript

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

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

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

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

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

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

window.initMap = initMap;

CSS

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

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

HTML

<html>
  <head>
    <title>Directly Accessing Street View Data</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

מתן תמונות פנורמיות ב-Street View בהתאמה אישית

Maps JavaScript API תומך בהצגת תמונות פנורמיות בהתאמה אישית בתוך אובייקט StreetViewPanorama. באמצעות תמונות פנורמיות בהתאמה אישית אפשר להציג את פנים המבנים, נופים ממיקומים ציוריים או כל דבר אחר לדמיין. אפשר אפילו לקשר את התמונות הפנורמיות המותאמות אישית האלה לפנורמות Street View הקיימות של Google.

הגדרת קבוצה של תמונות פנורמה מותאמות אישית כוללת את השלבים הבאים:

  • צור תמונה פנורמית בסיסית לכל פנורמה מותאמת אישית. התמונה הבסיסית צריכה להיות בתמונה ברזולוציה הגבוהה ביותר שבה אתם רוצים להציג תמונות מוגדלות.
  • (אופציונלי, אך מומלץ) אפשר ליצור קבוצה של משבצות פנורמיות ברמות זום שונות מהתמונה הבסיסית.
  • יצירת קישורים בין תמונות הפנורמה המותאמות אישית שלך.
  • (אופציונלי) ציון פנורמות "כניסה" בתוך תמונות Street View הקיימות של Google והתאימו אישית קישורים לקבוצה המותאמת אישית לקבוצה הסטנדרטית.
  • הגדרת מטא-נתונים לכל תמונה פנורמית בתוך אובייקט StreetViewPanoramaData.
  • צריך להטמיע שיטה שקובעת את הנתונים והתמונות של הפנורמה בהתאמה אישית, ולהגדיר את השיטה הזו כ-handler בהתאמה אישית בתוך האובייקט StreetViewPanorama.

בחלקים הבאים מוסבר התהליך הזה.

יצירת תמונות פנורמה מותאמות אישית

כל פנורמה ב-Street View היא תמונה או קבוצת תמונות שמספקות תצוגה מלאה ב-360 מעלות ממיקום יחיד. האובייקט StreetViewPanorama משתמש בתמונות שתואמות להיטל הכדורי (Plate Carrée). היטל כזה כולל תצוגה אופקית ב-360 מעלות (תמונת היקפית מלאה) ו-180 מעלות של תצוגה אנכית (מישור למעלה עד ישר למטה). שדות התצוגה האלה יוצרים תמונה ביחס גובה-רוחב של 2:1. למטה מופיעה פנורמה מלאה.

תמונת פנורמה של רחוב עירוני

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

כדור עם נוף פנורמי של רחוב על פני השטח

התייחסות לפנורמה בתור היטל בכדור עם מערכת קואורדינטות ישרה מועילה כאשר מחלקים את התמונה לאריחים בזווית ישרה, וכשמציגים תמונות על סמך קואורדינטות אריחים מחושבות.

יצירה של אריחי פנורמה מותאמים אישית

Street View תומך גם ברמות שונות של פרטי תמונה באמצעות שימוש בפקד של מרחק מתצוגה, שמאפשר לך להגדיל או להקטין את התצוגה כברירת מחדל. באופן כללי, Street View מספקת חמש רמות של רזולוציית זום לכל תמונה פנורמית. אם מסתמכים על תמונה פנורמית אחת להצגת כל רמות הזום, תמונה כזו תהיה בהכרח גדולה למדי ותאט באופן משמעותי את האפליקציה שלך, או שהרזולוציה שלה תהיה נמוכה ברמות זום גבוהות יותר, אחרת תמונה לא תהיה מפוקסלת בצורה טובה. למרבה המזל, עם זאת, אנחנו יכולים להשתמש בדפוס עיצוב דומה המשמש להצגת קטעי המפה של Google ברמות זום שונות, כדי לספק תמונות ברזולוציה המתאימה לצילומי פנורמה בכל אחת מרמות המרחק מהתצוגה.

כאשר StreetViewPanorama נטען לראשונה, כברירת מחדל מוצגת תמונה שמורכבת מ-25% (90 מעלות קשת) מהרוחב האופקי של הפנורמה ברמת זום 1. התצוגה הזו תואמת פחות או יותר לשדה ראייה רגיל. התקרבות "להתרחק" מתצוגת ברירת המחדל הזו מספקת למעשה קשת רחבה יותר, וההתקרבות מצמצמת את שדה התצוגה לקשת קטנה יותר. השדה StreetViewPanorama מחשב באופן אוטומטי את שדה הראייה המתאים לרמת הזום שנבחרה, ולאחר מכן בוחר את התמונות המתאימות ביותר לרזולוציה הזו על ידי בחירת קבוצת משבצות שתואמת בערך למידות של שדה התצוגה האופקי. השדות הבאים של תצוגת המפה לרמות המרחק מהתצוגה ב-Street View:

רמת זום ב-Street View שדה ראייה (מעלות)
0 180
1 (ברירת מחדל) 90
2 45
3 22.5
4 11.25

לתשומת ליבך, גודל התמונה שמוצגת ב-Street View תלוי לחלוטין בגודל המסך (רוחב) של מאגר Street View. אם מספקים מאגר רחב יותר, השירות עדיין מספק את אותו שדה ראייה בכל אחת מהרמות של המרחק מהתצוגה, אבל יכול להיות שבמקום זאת יבחרו משבצות שמתאימות יותר לרזולוציה הזו.

מכיוון שכל פנורמה מורכבת מהיטל מלבני, קל ליצור משבצות של פנורמה. מאחר שההיטל מספק תמונה ביחס גובה-רוחב של 2:1, קל יותר להשתמש במשבצות עם יחס גובה-רוחב של 2:1. עם זאת, משבצות מרובעות עשויות להניב ביצועים טובים יותר במפות ריבועיות (מכיוון ששדה התצוגה יהיה ריבועי).

עבור משבצות ביחס של 2:1, תמונה יחידה המקיפה את כל הפנורמה מייצגת את "העולם" המלא (תמונת הבסיס) ברמת זום 0, כאשר כל רמה מוגדלת של מרחק מתצוגה מציעה 4 משבצות zoomLevel. (לדוגמה, במרחק מתצוגה 2, כל הפנורמה מורכבת מ-16 אריחים). הערה: רמות המרחק מהתצוגה ב-Street View לא תואמות ישירות לרמות המרחק מהתצוגה, כפי שסופקו באמצעות הפקד של Street View. במקום זאת, רמות המרחק מהתצוגה בפקד של Street View בוחרים שדה ראייה (FoV), שממנו נבחרות המשבצות המתאימות.

תמונת פנורמה של רחוב עירוני המחולק לאריחים

באופן כללי, מומלץ לתת שם למשבצות התמונות כדי שאפשר יהיה לבחור אותן באופן פרוגרמטי. במאמר טיפול בבקשות פנורמה מותאמות אישית מוסבר איך מציעים שמות כאלה.

טיפול בבקשות פנורמה מותאמות אישית

כדי להשתמש בפנורמה מותאמת אישית, צריך להתקשר אל StreetViewPanorama.registerPanoProvider() ולציין את שם השיטה המותאמת אישית של ספק הפנורמה. השיטה של ספק הפנורמה חייבת להחזיר אובייקט StreetViewPanoramaData, שכוללת את החתימה הבאה:

Function(pano):StreetViewPanoramaData

StreetViewPanoramaData הוא אובייקט מהצורה הבאה:

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

הצג פנורמה מותאמת אישית באופן הבא:

  • מגדירים את המאפיין StreetViewPanoramaOptions.pano כערך מותאם אישית.
  • אפשר להפעיל את StreetViewPanorama.registerPanoProvider() כדי לספק פונקציה מותאמת אישית של ספק הפנורמה.
  • יישום הפונקציה המותאמת אישית של ספק הפנורמה שלך כדי לטפל בערך pano שצוין.
  • יוצרים אובייקט StreetViewPanoramaData.
  • מגדירים את המאפיין StreetViewTileData.getTileUrl לשם הפונקציה של ספק האריחים בהתאמה אישית שאתם מספקים. לדוגמה, getCustomPanoramaTileUrl.
  • מטמיעים את הפונקציה של ספק האריחים בהתאמה אישית, כפי שמוצג בדוגמאות שבהמשך.
  • מחזירים את האובייקט StreetViewPanoramaData.

הערה: אין להגדיר position ישירות ב-StreetViewPanorama כאשר ברצונך להציג תמונות פנורמיות מותאמות אישית. מיקום כזה ינחה את שירות Street View לבקש את תמונות ברירת המחדל של Street View בקרבת מקום. במקום זאת, צריך להגדיר את המיקום הזה בשדה location.latLng של האובייקט StreetViewPanoramaData בהתאמה אישית.

בדוגמה הבאה מוצג נוף פנורמי מותאם אישית למשרד Google בסידני. לידיעתך, בדוגמה הבאה לא נעשה שימוש במפה או בתמונות ברירת מחדל ב-Street View:

TypeScript

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

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

JavaScript

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

window.initPano = initPano;

CSS

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

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

HTML

<html>
  <head>
    <title>Custom Street View Panoramas</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initPano&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?

ספק הפנורמה בהתאמה אישית מחזיר את האריח המתאים על סמך מזהה הפנורמה שעבר, רמת הזום וקואורדינטות הפנורמה של הפנורמה. בחירת התמונות תלויה בערכים שהועברו, ולכן כדאי לתת שם לתמונות שאפשר לבחור באופן פרוגרמטי על סמך הערכים שהועברו, כמו pano_zoom_tileX_tileY.png.

בדוגמה הבאה מתווסף לתמונה עוד חץ, בנוסף לחיצי הניווט של Street View שמוגדרים כברירת מחדל, שמכוונים ל-Google סידני וקישורים לתמונות המותאמות אישית:

TypeScript

let panorama: google.maps.StreetViewPanorama;

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

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

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

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

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

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

JavaScript

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

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

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

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

window.initMap = initMap;

CSS

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

#street-view {
  height: 100%;
}

HTML

<html>
  <head>
    <title>Custom Street View Panorama Tiles</title>
    <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>

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

    <!-- 
      The `defer` attribute causes the callback to execute after the full HTML
      document has been parsed. For non-blocking uses, avoiding race conditions,
      and consistent behavior across browsers, consider loading using Promises.
      See https://developers.google.com/maps/documentation/javascript/load-maps-js-api
      for more information.
      -->
    <script
      src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB41DRUbKWJHPxaFjMAwdrzWzbVKartNGg&callback=initMap&v=weekly"
      defer
    ></script>
  </body>
</html>
להצגת דוגמה

רוצה לנסות דוגמה?