Usługa Street View

Przegląd

Wybierz platformę: Android iOS JavaScript

Google Street View udostępnia widoki sferyczne z wyznaczonych dróg na całym obsługiwanym obszarze. Zasięg interfejsu API Street View jest taki sam jak w aplikacji Mapy Google (https://maps.google.com/). Listę miast, w których usługa Street View jest obecnie dostępna, znajdziesz na stronie Map Google.

Poniżej znajduje się przykładowe zdjęcie Street View.


Interfejs Maps JavaScript API udostępnia usługę Street View, która umożliwia uzyskiwanie i modyfikowanie zdjęć używanych w Street View w Mapach Google. Ta usługa Street View jest obsługiwana natywnie w przeglądarce.

Korzystanie z mapy Street View

Chociaż widoku Street View można używać w samodzielnym elemencie DOM, jest on najbardziej przydatny, gdy wskazuje lokalizację na mapie. Domyślnie widok Street View jest włączony na mapie, a element sterujący Pegman jest zintegrowany z elementami sterującymi nawigacją (powiększanie i przesuwanie). Możesz ukryć ten element sterujący w MapOptions mapy, ustawiając streetViewControl na false. Możesz też zmienić domyślną pozycję elementu sterującego Street View, ustawiając właściwość streetViewControlOptions.position obiektu Map na nową wartość ControlPosition.

Element sterujący Pegman Street View umożliwia wyświetlanie panoram Street View bezpośrednio na mapie. Gdy użytkownik kliknie i przytrzyma Pegmana, mapa zaktualizuje się, aby wyświetlić niebieskie kontury wokół ulic, na których dostępny jest widok Street View. Dzięki temu użytkownik będzie mógł korzystać z aplikacji w podobny sposób jak z Map Google.

Gdy użytkownik upuści znacznik Pegmana na ulicę, mapa zostanie zaktualizowana i wyświetli się panorama Street View wskazanej lokalizacji.

Panoramy Street View

Zdjęcia Street View są obsługiwane przez obiekt StreetViewPanorama, który udostępnia interfejs API do „przeglądarki” Street View. Każda mapa zawiera domyślną panoramę Street View, którą można pobrać, wywołując metodę getStreetView() mapy. Gdy dodasz do mapy element sterujący Street View, ustawiając opcję streetViewControl na true, automatycznie połączysz element sterujący Pegman z tą domyślną panoramą Street View.

Możesz też utworzyć własny obiekt StreetViewPanorama i ustawić mapę tak, aby używała go zamiast domyślnego, przez jawne ustawienie właściwości streetView mapy na ten utworzony obiekt. Możesz zastąpić domyślną panoramę, jeśli chcesz zmodyfikować działanie domyślne, np. automatyczne udostępnianie nakładek między mapą a panoramą. (patrz sekcja Nakładki w Street View poniżej).

Kontenery Street View

Możesz też wyświetlać StreetViewPanorama w osobnym elemencie DOM, często w elemencie <div>. Wystarczy przekazać element DOM w konstruktorze StreetViewPanorama. Aby uzyskać optymalną jakość wyświetlania obrazów, zalecamy minimalny rozmiar 200 x 200 pikseli.

Uwaga: chociaż funkcja Street View została zaprojektowana do używania w połączeniu z mapą, nie jest to wymagane. Możesz użyć samodzielnego obiektu Street View bez mapy.

Lokalizacje i punkt widzenia (POV) w Street View

Konstruktor StreetViewPanorama umożliwia też ustawienie lokalizacji i punktu widzenia Street View za pomocą parametru StreetViewOptions. Po utworzeniu obiektu możesz wywołać na nim metody setPosition() i setPov(), aby zmienić jego lokalizację i punkt widzenia.

Lokalizacja Street View określa położenie punktu ostrości aparatu na zdjęciu, ale nie określa orientacji aparatu na tym zdjęciu. W tym celu obiekt StreetViewPov definiuje 2 właściwości:

  • heading (domyślnie 0) określa kąt obrotu wokół punktu kamery w stopniach względem północy geograficznej. Kierunki są mierzone zgodnie z ruchem wskazówek zegara (90 stopni to kierunek wschodni).
  • pitch (domyślnie 0) określa odchylenie kąta „w górę” lub „w dół” od początkowego domyślnego nachylenia kamery, które często (ale nie zawsze) jest poziome. (np. zdjęcie zrobione na wzgórzu będzie prawdopodobnie miało domyślne nachylenie, które nie jest poziome). Kąty nachylenia są mierzone za pomocą wartości dodatnich, gdy patrzy się w górę (do +90 stopni prosto w górę i prostopadle do domyślnego nachylenia), oraz wartości ujemnych, gdy patrzy się w dół (do -90 stopni prosto w dół i prostopadle do domyślnego nachylenia).

Obiekt StreetViewPov jest najczęściej używany do określania punktu widzenia kamery Street View. Możesz też określić punkt widzenia fotografa – zwykle kierunek, w którym był zwrócony samochód lub rower – za pomocą metody StreetViewPanorama.getPhotographerPov().

Poniższy kod wyświetla mapę Bostonu z początkowym widokiem Fenway Park. Wybranie Pegmana i przeciągnięcie go do obsługiwanej lokalizacji na mapie spowoduje zmianę panoramy 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>
Zobacz przykład

Skorzystaj z przykładu

Śledzenie ruchu na urządzeniach mobilnych

Na urządzeniach, które obsługują zdarzenia orientacji urządzenia, interfejs API umożliwia użytkownikom zmianę punktu widzenia Street View na podstawie ruchu urządzenia. Użytkownicy mogą rozglądać się, poruszając urządzeniami. Nazywa się to śledzeniem ruchu lub śledzeniem obrotu urządzenia.

Jako deweloper aplikacji możesz zmienić działanie domyślne w ten sposób:

  • Włącz lub wyłącz funkcję śledzenia ruchu. Domyślnie śledzenie ruchu jest włączone na każdym urządzeniu, które je obsługuje. Poniższy przykład wyłącza śledzenie ruchu, ale pozostawia widoczny element sterujący śledzeniem ruchu. (Pamiętaj, że użytkownik może włączyć śledzenie ruchu, klikając element sterujący).
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false
        });
  • Ukryj lub pokaż element sterujący śledzeniem ruchu. Domyślnie element sterujący jest wyświetlany na urządzeniach, które obsługują śledzenie ruchu. Użytkownik może kliknąć element sterujący, aby włączyć lub wyłączyć śledzenie ruchu. Pamiętaj, że element sterujący nigdy nie pojawi się, jeśli urządzenie nie obsługuje śledzenia ruchu, niezależnie od wartości motionTrackingControl.

    Poniższy przykład wyłącza zarówno śledzenie ruchu, jak i element sterujący śledzeniem ruchu. W takim przypadku użytkownik nie może włączyć śledzenia ruchu:

    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
        });
  • Zmień domyślną pozycję elementu sterującego śledzeniem ruchu. Domyślnie element sterujący pojawia się w prawym dolnym rogu panoramy (pozycja RIGHT_BOTTOM). W poniższym przykładzie ustawiono pozycję elementu sterującego na lewy dolny róg:
    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
          }
        });

Aby zobaczyć, jak działa śledzenie ruchu, wyświetl ten przykład na urządzeniu mobilnym (lub dowolnym urządzeniu obsługującym zdarzenia orientacji urządzenia):


Zobacz przykład

Nakładki w Street View

Domyślny obiekt StreetViewPanorama obsługuje natywne wyświetlanie nakładek mapy. Nakładki zwykle pojawiają się na „poziomie ulicy” i są zakotwiczone w pozycjach LatLng. (Znaczniki będą wyświetlane z ogonami zakotwiczonymi w płaszczyźnie poziomej lokalizacji w panoramie Street View).

Obecnie typy nakładek obsługiwanych w panoramach Street View są ograniczone do obiektów Marker, InfoWindow i niestandardowych obiektów OverlayView. Nakładki, które wyświetlasz na mapie, mogą być wyświetlane na panoramie Street View, jeśli potraktujesz panoramę jako zamiennik obiektu Map, wywołując setMap() i przekazując StreetViewPanorama jako argument zamiast mapy. Okna informacyjne można też otwierać w panoramie Street View, wywołując metodę open() i przekazując obiekt StreetViewPanorama() zamiast mapy.

Dodatkowo podczas tworzenia mapy z domyślnym obiektem StreetViewPanorama wszystkie znaczniki utworzone na mapie są automatycznie udostępniane powiązanej z nią panoramie Street View, o ile jest ona widoczna. Aby pobrać domyślną panoramę Street View, wywołaj getStreetView() na obiekcie Map. Pamiętaj, że jeśli jawnie ustawisz właściwość streetView mapy na utworzony przez siebie obiekt StreetViewPanorama, zastąpisz domyślną panoramę.

Poniższy przykład pokazuje znaczniki oznaczające różne lokalizacje wokół Astor Place w Nowym Jorku. Przełącz widok na Street View, aby wyświetlić udostępnione znaczniki w elemencie 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>
Zobacz przykład

Skorzystaj z przykładu

Zdarzenia Street View

Podczas poruszania się w Street View lub zmieniania orientacji możesz monitorować kilka zdarzeń, które wskazują zmiany stanu obiektu StreetViewPanorama:

  • Zdarzenie pano_changed jest wywoływane za każdym razem, gdy zmienia się identyfikator pojedynczej panoramy. To zdarzenie nie gwarantuje, że powiązane dane w panoramie (np. linki) również uległy zmianie w momencie wywołania tego zdarzenia. Wskazuje ono tylko, że zmienił się identyfikator panoramy. Pamiętaj, że identyfikator panoramy (którego możesz użyć do odwołania się do tej panoramy) jest stabilny tylko w ramach bieżącej sesji przeglądarki.
  • Zdarzenie position_changed jest wywoływane, gdy zmienia się pozycja (LatLng) panoramy. Obrócenie panoramy nie spowoduje wywołania tego zdarzenia. Pamiętaj, że możesz zmienić pozycję panoramy bez zmiany powiązanego identyfikatora panoramy, ponieważ interfejs API automatycznie powiąże najbliższy identyfikator panoramy z pozycją panoramy.
  • Zdarzenie pov_changed jest wywoływane, gdy zmienia się StreetViewPov widoku Street View. Pamiętaj, że to zdarzenie może zostać wywołane, gdy pozycja i identyfikator panoramy pozostają stabilne.
  • Zdarzenie links_changed jest wywoływane za każdym razem, gdy zmieniają się linki Street View. Pamiętaj, że to zdarzenie może zostać wywołane asynchronicznie po zmianie identyfikatora panoramy wskazanej przez pano_changed.
  • Zdarzenie visible_changed jest wywoływane za każdym razem, gdy zmienia się widoczność Street View. Pamiętaj, że to zdarzenie może zostać wywołane asynchronicznie po zmianie identyfikatora panoramy wskazanej przez pano_changed.

Poniższy kod pokazuje, jak można obsługiwać te zdarzenia, aby zbierać dane o podstawowym elemencie StreetViewPanorama:

TypeScript

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

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

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

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

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

    const links = panorama.getLinks();

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

      linksTable.appendChild(row);

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

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

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

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

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

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

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

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

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

JavaScript

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

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

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

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

    const links = panorama.getLinks();

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

      linksTable.appendChild(row);

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

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

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

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

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

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

window.initPano = initPano;

CSS

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

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

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

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

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

HTML

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

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

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

Sterowanie Street View

Podczas wyświetlania obiektu StreetViewPanorama na panoramie domyślnie pojawiają się różne elementy sterujące. Możesz włączyć lub wyłączyć te ustawienia, ustawiając odpowiednie pola w StreetViewPanoramaOptions na true lub false:

  • panControl umożliwia obracanie panoramy. Domyślnie ten element sterujący jest wyświetlany jako standardowy zintegrowany kompas i element sterujący przesuwaniem. Możesz zmienić pozycję elementu sterującego, podając PanControlOptions w polu panControlOptions.
  • zoomControl umożliwia powiększanie obrazu. Ten element sterujący pojawia się domyślnie w prawym dolnym rogu panoramy. Możesz zmienić wygląd elementu sterującego, podając ZoomControlOptions w polu zoomControlOptions.
  • addressControl zawiera nakładkę tekstową wskazującą adres powiązanej lokalizacji oraz link do otwarcia lokalizacji w Mapach Google. Możesz zmienić wygląd elementu sterującego, podając StreetViewAddressControlOptions w polu addressControlOptions.
  • fullscreenControl umożliwia otwarcie Street View w trybie pełnoekranowym. Możesz zmienić wygląd elementu sterującego, podając FullscreenControlOptions w polu fullscreenControlOptions.
  • motionTrackingControl umożliwia włączenie lub wyłączenie śledzenia ruchu na urządzeniach mobilnych. Ten element sterujący jest widoczny tylko na urządzeniach, które obsługują zdarzenia orientacji urządzenia. Domyślnie element sterujący pojawia się w prawym dolnym rogu panoramy. Możesz zmienić pozycję elementu sterującego, podając MotionTrackingControlOptions. Więcej informacji znajdziesz w sekcji dotyczącej śledzenia ruchu.
  • linksControl zawiera strzałki na obrazie, które wskazują, jak przejść do sąsiednich zdjęć panoramicznych.
  • Element sterujący Zamknij umożliwia użytkownikowi zamknięcie przeglądarki Street View. Możesz włączyć lub wyłączyć element sterujący Zamknij, ustawiając enableCloseButton na true lub false.

Ten przykład zmienia elementy sterujące wyświetlane w powiązanym widoku Street View i usuwa linki do widoku:

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>
Zobacz przykład

Bezpośredni dostęp do danych Street View

Możesz automatycznie określać dostępność danych Street View lub zwracać informacje o konkretnych panoramach bez konieczności bezpośredniego manipulowania mapą lub panoramą. Możesz to zrobić za pomocą obiektu StreetViewService, który udostępnia interfejs do danych przechowywanych w usłudze Google Street View.

Prośby o usługi Street View

Dostęp do usługi Street View jest asynchroniczny, ponieważ interfejs API Map Google musi wykonać wywołanie do serwera zewnętrznego. Z tego powodu musisz przekazać metodę wywołania zwrotnego, która zostanie wykonana po zakończeniu żądania. Ta metoda wywołania zwrotnego przetwarza wynik.

Żądania do StreetViewService możesz inicjować za pomocą StreetViewPanoRequest lub StreetViewLocationRequest.

Żądanie używające StreetViewPanoRequest zwraca dane panoramy na podstawie identyfikatora referencyjnego, który jednoznacznie identyfikuje panoramę. Pamiętaj, że te identyfikatory referencyjne są stabilne tylko przez okres ważności zdjęć tej panoramy.

Żądanie używające StreetViewLocationRequest wyszukuje dane panoramy w określonej lokalizacji, używając tych parametrów:

  • location określa lokalizację (szerokość i długość geograficzną), w której ma zostać wyszukana panorama.
  • preference określa preferencje dotyczące panoramy, która powinna zostać znaleziona w promieniu: najbliższej podanej lokalizacji lub najlepszej w promieniu.
  • radius określa promień (w metrach), w którym ma być wyszukiwana panorama, ze środkiem w podanej szerokości i długości geograficznej. Jeśli nie zostanie podana, domyślna wartość to 50.
  • source określa źródło panoram do wyszukiwania. Prawidłowe wartości to:
    • default używa domyślnych źródeł Street View; wyszukiwanie nie jest ograniczone do konkretnych źródeł.
    • outdoor ogranicza wyszukiwanie do kolekcji zewnętrznych. Pamiętaj, że dla określonej lokalizacji mogą nie istnieć panoramy zewnętrzne.

Odpowiedzi usługi Street View

Funkcja getPanorama() wymaga funkcji wywołania zwrotnego, która zostanie wykonana po pobraniu wyniku z usługi Street View. Ta funkcja wywołania zwrotnego zwraca zestaw danych panoramy w obiekcie StreetViewPanoramaData i kod StreetViewStatus oznaczający stan żądania (w tej kolejności).

Specyfikacja obiektu StreetViewPanoramaData zawiera metadane dotyczące panoramy Street View w tym formacie:

{
  "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
  }
}

Pamiętaj, że ten obiekt danych nie jest obiektem StreetViewPanorama. Aby utworzyć obiekt Street View na podstawie tych danych, musisz utworzyć StreetViewPanorama i wywołać setPano(), przekazując identyfikator podany w zwróconym polu location.pano.

Kod status może zwracać jedną z tych wartości:

  • OK wskazuje, że usługa znalazła pasującą panoramę.
  • ZERO_RESULTS wskazuje, że usługa nie mogła znaleźć pasującej panoramy spełniającej podane kryteria.
  • UNKNOWN_ERROR oznacza, że nie udało się przetworzyć żądania Street View, ale dokładna przyczyna nie jest znana.

Poniższy kod tworzy obiekt StreetViewService, który reaguje na kliknięcia mapy przez użytkownika, tworząc znaczniki, które po kliknięciu wyświetlają StreetViewPanorama danej lokalizacji. Kod używa zawartości StreetViewPanoramaData zwróconej z usługi.

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>
Zobacz przykład

Udostępnianie niestandardowych panoram Street View

Interfejs Maps JavaScript API obsługuje wyświetlanie niestandardowych panoram w obiekcie StreetViewPanorama. Dzięki niestandardowym panoramom możesz wyświetlać wnętrza budynków, widoki z malowniczych miejsc lub dowolne inne obrazy. Możesz nawet połączyć te niestandardowe panoramy z istniejącymi panoramami Street View Google.

Konfigurowanie zestawu niestandardowych zdjęć panoramicznych obejmuje te czynności:

  • Utwórz podstawowy obraz panoramiczny dla każdej niestandardowej panoramy. Ten obraz podstawowy powinien mieć najwyższą rozdzielczość, w jakiej chcesz wyświetlać powiększone obrazy.
  • (Opcjonalne, ale zalecane) Utwórz zestaw kafelków panoramicznych na różnych poziomach powiększenia z obrazu podstawowego.
  • Utwórz połączenia między niestandardowymi panoramami.
  • (Opcjonalnie) Wyznacz panoramy „wejściowe” w ramach istniejących zdjęć Street View Google i dostosuj linki do/z niestandardowego zestawu do standardowego zestawu.
  • Zdefiniuj metadane dla każdego obrazu panoramicznego w obiekcie StreetViewPanoramaData.
  • Zaimplementuj metodę, która określa niestandardowe dane i obrazy panoramy, i wyznacz tę metodę jako niestandardowy moduł obsługi w obiekcie StreetViewPanorama.

Ten proces został opisany w sekcjach poniżej.

Tworzenie niestandardowych panoram

Każda panorama Street View to obraz lub zestaw obrazów, które zapewniają pełny widok 360 stopni z jednej lokalizacji. Obiekt StreetViewPanorama używa obrazów zgodnych z odwzorowaniem walcowym równoodległościowym (Plate Carrée). Taka projekcja obejmuje 360 stopni widoku w poziomie (pełny obrót) i 180 stopni widoku w pionie (od góry do dołu). Te pola widzenia dają obraz o formacie obrazu 2:1. Poniżej znajduje się pełna panorama.

Widok panoramiczny ulicy w mieście

Obrazy panoramiczne są zwykle uzyskiwane przez zrobienie kilku zdjęć z jednej pozycji i połączenie ich za pomocą oprogramowania do tworzenia panoram. (Więcej informacji znajdziesz w artykule Wikipedii Porównanie aplikacji do łączenia zdjęć). Takie obrazy powinny mieć wspólny punkt „aparatu”, z którego są robione poszczególne zdjęcia panoramiczne. Powstała w ten sposób panorama 360 stopni może następnie definiować rzut na sferę, przy czym obraz jest owinięty wokół dwuwymiarowej powierzchni sfery.

Kula z panoramicznym widokiem ulicy na powierzchni

Traktowanie panoramy jako rzutu na sferę z prostoliniowym układem współrzędnych jest korzystne, gdy obraz jest dzielony na prostoliniowe kafelki, a obrazy są wyświetlane na podstawie obliczonych współrzędnych kafelków.

Tworzenie niestandardowych kafelków panoramicznych

Street View obsługuje też różne poziomy szczegółowości obrazu dzięki funkcji powiększenia, która umożliwia powiększanie i pomniejszanie widoku domyślnego. Zwykle Street View udostępnia 5 poziomów powiększenia dla każdego zdjęcia panoramicznego. Jeśli do obsługi wszystkich poziomów powiększenia użyjesz jednego obrazu panoramicznego, będzie on musiał być bardzo duży, co znacznie spowolni działanie aplikacji, lub będzie miał tak słabą rozdzielczość przy wyższych poziomach powiększenia, że obraz będzie bardzo rozpikselowany. Na szczęście możemy użyć podobnego wzorca projektowego, który jest używany do wyświetlania kafelków map Google na różnych poziomach powiększenia, aby zapewnić odpowiednią rozdzielczość zdjęć panoramicznych na każdym poziomie powiększenia.

Gdy obiekt StreetViewPanorama jest wczytywany po raz pierwszy, domyślnie wyświetla obraz obejmujący 25% (90 stopni łuku) poziomej szerokości panoramy przy poziomie powiększenia 1. Ten widok odpowiada mniej więcej normalnemu polu widzenia człowieka. Pomniejszenie tego domyślnego widoku zasadniczo zapewnia szerszy łuk, a powiększenie zawęża pole widzenia do mniejszego łuku. StreetViewPanorama automatycznie oblicza odpowiednie pole widzenia dla wybranego poziomu powiększenia, a następnie wybiera zdjęcia najbardziej odpowiednie dla tej rozdzielczości, wybierając zestaw kafelków, który mniej więcej odpowiada wymiarom poziomego pola widzenia. Te pola widzenia są mapowane na poziomy powiększenia Street View:

Poziom powiększenia Street View Pole widzenia (stopnie)
0 180
1 (domyślnie) 90
2 45
3 22,5
4 11.25

Pamiętaj, że rozmiar obrazu wyświetlanego w Street View zależy całkowicie od rozmiaru ekranu (szerokości) kontenera Street View. Jeśli udostępnisz szerszy kontener, usługa nadal będzie zapewniać to samo pole widzenia dla danego poziomu powiększenia, ale może wybrać kafelki bardziej odpowiednie dla tej rozdzielczości.

Każda panorama składa się z rzutu walcowego równoodległościowego, więc tworzenie kafelków panoramy jest stosunkowo łatwe. Ponieważ rzut zapewnia obraz o formacie obrazu 2:1, fragmenty mapy o proporcjach 2:1 są łatwiejsze w użyciu, chociaż kafelki kwadratowe mogą zapewniać lepszą wydajność na mapach kwadratowych (ponieważ pole widzenia będzie kwadratowe).

W przypadku kafelków 2:1 pojedynczy obraz obejmujący całą panoramę reprezentuje całą panoramę „świata” (obraz podstawowy) na poziomie powiększenia 0, a każdy kolejny poziom powiększenia oferuje 4zoomLevel kafelków. (np. na poziomie powiększenia 2 cała panorama składa się z 16 kafelków). Uwaga: poziomy powiększenia w kafelkach Street View nie odpowiadają bezpośrednio poziomom powiększenia dostępnym za pomocą elementu sterującego Street View. Zamiast tego poziomy powiększenia elementu sterującego Street View wybierają pole widzenia, z którego wybierane są odpowiednie kafelki.

Widok panoramiczny ulicy w mieście podzielony na kafelki

Zwykle warto nazwać kafelki obrazu, aby można było je wybrać automatycznie. Taki schemat nazewnictwa został omówiony poniżej w sekcji Obsługa niestandardowych żądań dotyczących panoramy.

Obsługa żądań niestandardowych panoram

Aby użyć niestandardowej panoramy, wywołaj funkcję StreetViewPanorama.registerPanoProvider(), podając nazwę niestandardowej metody dostawcy panoramy. Metoda dostawcy panoramy musi zwracać obiekt StreetViewPanoramaData i mieć następującą sygnaturę:

Function(pano):StreetViewPanoramaData

StreetViewPanoramaData to obiekt o następującej formie:

{
  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
  ]
}

Wyświetl niestandardową panoramę w ten sposób:

  • Ustaw właściwość StreetViewPanoramaOptions.pano na wartość niestandardową.
  • Wywołaj funkcję StreetViewPanorama.registerPanoProvider(), aby podać niestandardową funkcję dostawcy panoramy.
  • Zaimplementuj niestandardową funkcję dostawcy panoramy, aby obsługiwać określoną wartość pano.
  • Utwórz obiekt StreetViewPanoramaData.
  • Ustaw właściwość StreetViewTileData.getTileUrl na nazwę niestandardowej funkcji dostawcy kafelków, którą podajesz. Na przykład: getCustomPanoramaTileUrl.
  • Zaimplementuj funkcję niestandardowego dostawcy kafelków, jak pokazano w poniższych przykładach.
  • Zwróć obiekt StreetViewPanoramaData.

Uwaga: nie ustawiaj bezpośrednio właściwości position w obiekcie StreetViewPanorama, jeśli chcesz wyświetlać panoramy niestandardowe, ponieważ taka pozycja spowoduje, że usługa Street View będzie żądać domyślnych zdjęć Street View w pobliżu tej lokalizacji. Zamiast tego ustaw tę pozycję w polu location.latLng niestandardowego obiektu StreetViewPanoramaData.

Poniższy przykład pokazuje niestandardową panoramę biura Google w Sydney. Pamiętaj, że w tym przykładzie nie użyto mapy ani domyślnych zdjęć Street View:

TypeScript

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

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

JavaScript

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

  panorama.registerPanoProvider(getCustomPanorama);
}

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

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

window.initPano = initPano;

CSS

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

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

HTML

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

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

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

Niestandardowy dostawca panoramy zwraca odpowiedni fragment mapy na podstawie przekazanego identyfikatora panoramy, poziomu powiększenia i współrzędnych mapy panoramy. Ponieważ wybór obrazu zależy od przekazanych wartości, warto nazwać obrazy, które można wybrać automatycznie na podstawie tych wartości, np. pano_zoom_tileX_tileY.png.

W poniższym przykładzie do obrazu dodano kolejną strzałkę, oprócz domyślnych strzałek nawigacyjnych Street View, która wskazuje Google Sydney i prowadzi do niestandardowych zdjęć:

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>
Zobacz przykład