Panoramica
Google Street View offre viste panoramiche a 360 gradi
dalle strade designate in tutta l'area di copertura. La copertura API di Street View è la stessa per l'applicazione Google Maps (https://maps.google.com/
). L'elenco delle città attualmente supportate per Street View è disponibile sul sito web di Google Maps.
Di seguito è riportato un esempio di immagine di Street View.
L'API Maps JavaScript fornisce un servizio Street View per ottenere e manipolare le immagini utilizzate in Street View di Google Maps. Questo servizio Street View è supportato in modo nativo nel browser.
Utilizzo delle mappe di Street View
Street View può essere utilizzato all'interno di un elemento DOM autonomo, ma è più utile per indicare una posizione su una mappa. Per impostazione predefinita, Street View è abilitato su una mappa e un controllo Peggman di Street View viene integrato nei controlli di navigazione (zoom e panoramica). Puoi nascondere questo controllo all'interno delle MapOptions
della mappa impostando streetViewControl
su false
. Puoi anche modificare la posizione predefinita del controllo di Street View impostando la proprietà streetViewControlOptions.position
di Map
su un nuovo elemento ControlPosition
.
Il controllo di Street View Pegman ti consente di visualizzare le panoramiche di Street View direttamente dalla mappa. Quando l'utente fa clic e tiene premuto Pegman, la mappa viene aggiornata per mostrare i contorni blu intorno alle strade abilitate per Street View, offrendo un'esperienza utente simile all'app Google Maps.
Quando l'utente posiziona un indicatore su una strada, la mappa viene aggiornata e mostra una panoramica di Street View della località indicata.
Panorama di Street View
Le immagini di Street View sono supportate tramite l'uso
dell'oggetto StreetViewPanorama
, che fornisce un'interfaccia
API a un "visualizzatore" di Street View. Ogni mappa contiene una panoramica predefinita di Street View, che puoi recuperare chiamando il metodo getStreetView()
della mappa. Quando aggiungi un controllo di Street View alla mappa impostando la relativa opzione streetViewControl
su true
, colleghi automaticamente il controllo Pegman a questo panorama Street View predefinito.
Puoi anche creare il tuo oggetto StreetViewPanorama
e impostare la mappa per utilizzarlo al posto di quello predefinito, impostando la proprietà streetView
della mappa in modo esplicito su tale oggetto costruito. Ti consigliamo di ignorare la panoramica predefinita se vuoi modificare il comportamento predefinito, ad esempio la condivisione automatica degli overlay tra la mappa e la panoramica. Consulta la sezione Sovrapposizioni all'interno di Street View di seguito.
Container Street View
Potresti invece voler visualizzare un StreetViewPanorama
all'interno di un elemento DOM separato, spesso un elemento <div>
.
Devi solo passare l'elemento DOM all'interno del
costruttore di StreetViewPanorama
. Per una visualizzazione ottimale delle immagini, consigliamo una dimensione minima di 200 x 200 pixel.
Nota: sebbene la funzionalità Street View sia progettata per essere utilizzata insieme a una mappa, questo utilizzo non è obbligatorio. Puoi utilizzare un oggetto Street View autonomo senza una mappa.
Posizioni e punti di vista Street View
Il costruttore StreetViewPanorama
consente inoltre di impostare la posizione e il punto di vista Street View utilizzando il parametro StreetViewOptions
. Puoi chiamare
setPosition()
e setPov()
sull'oggetto dopo
la costruzione per modificarne la posizione e l'ordine di acquisto.
La posizione di Street View definisce la posizione della fotocamera
per un'immagine, ma non definisce l'orientamento della
fotocamera per quell'immagine. A tale scopo, l'oggetto StreetViewPov
definisce due proprietà:
heading
(valore predefinito:0
) definisce l'angolo di rotazione attorno al luogo della fotocamera in gradi rispetto al vero nord. Le intestazioni vengono misurate in senso orario (90 gradi è true est).pitch
(valore predefinito:0
) definisce la varianza di angolo "su" o "giù" rispetto all'intonazione predefinita iniziale della videocamera, che spesso è (ma non sempre) orizzontale in orizzontale. Ad esempio, un'immagine scattata in collina probabilmente mostrerà un tono predefinito non orizzontale. Gli angoli di inclinazione sono misurati con valori positivi rivolti verso l'alto (fino a +90 gradi in verticale e ortogonali all'intonazione predefinita) e valori negativi verso l'alto (fino a -90 gradi verso il basso e ortogonali all'intonazione predefinita).
L'oggetto StreetViewPov
viene utilizzato più spesso per determinare il
punto di vista della fotocamera Street View. Puoi anche utilizzare il metodo StreetViewPanorama.getPhotographerPov()
per determinare il
punto di vista del fotografo, in genere la
direzione dell'auto
o del trike.
Il codice seguente mostra una mappa di Boston con una vista iniziale di Fenway Park. Se selezioni Pegman e lo trascini in una località supportata sulla mappa, la vista di Street View cambierà:
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>
Prova di esempio
Monitoraggio dei movimenti sui dispositivi mobili
Sui dispositivi che supportano gli eventi di orientamento del dispositivo, l'API offre agli utenti la possibilità di cambiare il punto di vista Street View in base al movimento del dispositivo. Gli utenti possono guardarsi intorno spostando i dispositivi. Questa operazione è chiamata monitoraggio del movimento o monitoraggio della rotazione del dispositivo.
In qualità di sviluppatore di app, puoi modificare il comportamento predefinito come descritto di seguito:
- Attivare o disattivare la funzionalità di monitoraggio del movimento. Per impostazione predefinita, il monitoraggio del movimento è attivo su qualsiasi dispositivo che lo supporta. L'esempio seguente disabilita il monitoraggio del movimento, ma lascia visibile il controllo del movimento.
Tieni presente che l'utente può attivare il monitoraggio del movimento toccando il controllo.
var panorama = new google.maps.StreetViewPanorama( document.getElementById('pano'), { position: {lat: 37.869260, lng: -122.254811}, pov: {heading: 165, pitch: 0}, motionTracking: false });
-
Nascondi o mostra il controllo del movimento. Per impostazione predefinita, il controllo viene visualizzato sui dispositivi che supportano il monitoraggio del movimento. L'utente può toccare il controllo per attivare o disattivare il rilevamento dei movimenti. Tieni presente che questo controllo non verrà mai visualizzato se il dispositivo non supporta il rilevamento dei movimenti, indipendentemente dal valore di
motionTrackingControl
.Il seguente esempio disabilita sia il monitoraggio del movimento sia il controllo del monitoraggio del movimento. In questo caso, l'utente non può attivare il monitoraggio del movimento:
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 });
- Cambiare la posizione predefinita del controllo di movimento. Per impostazione predefinita, il controllo viene visualizzato in basso a destra nella panoramica (posizione
RIGHT_BOTTOM
). Il seguente esempio imposta la posizione del controllo su in basso a sinistra: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 } });
Per vedere il monitoraggio del movimento in azione, visualizza il seguente esempio su un dispositivo mobile (o su qualsiasi dispositivo che supporta gli eventi di orientamento del dispositivo):
Overlay in Street View
L'oggetto StreetViewPanorama
predefinito supporta la visualizzazione nativa degli
overlay
mappa.
In genere le sovrapposizioni vengono visualizzate a "livello strada" ancorate in posizioni
LatLng
. Gli indicatori verranno visualizzati con la coda ancorata al piano orizzontale
della località all'interno della panoramica di Street View.
Attualmente, i tipi di overlay supportati sulle panoramiche di Street View sono limitati a Marker
, InfoWindow
e OverlayView
personalizzati. Gli overlay che visualizzi su una mappa potrebbero essere
visualizzati su una panoramica di Street View considerare la panoramica come un sostituto
dell'oggetto Map
, chiamando setMap()
e passando
StreetViewPanorama
come argomento anziché come mappa. Allo stesso modo, puoi aprire le finestre informative all'interno di una panoramica di Street View chiamando open()
, superando StreetViewPanorama()
invece di una mappa.
Inoltre, quando crei una mappa con un valore predefinito
StreetViewPanorama
, tutti gli indicatori creati su una mappa
vengono condivisi automaticamente con la panoramica di Street View associata, a condizione che
la panoramica sia visibile. Per recuperare la panoramica predefinita di Street View, chiama
getStreetView()
nell'oggetto Map
. Tieni presente che se
imposti esplicitamente la proprietà streetView
della mappa su
StreetViewPanorama
dalla tua costruzione, verrà sostituita la panoramica predefinita.
L'esempio seguente mostra indicatori che indicano varie località nei pressi di
Astor Place, New York. Attiva la visualizzazione su Street View per mostrare
gli indicatori condivisi visualizzati all'interno di 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>
Prova di esempio
Eventi di Street View
Quando esplori tra Street View o ne modifichi l'orientamento, puoi monitorare diversi eventi che indicano modifiche allo stato di StreetViewPanorama
:
pano_changed
si attiva ogni volta che il singolo ID di panoramica cambia. Questo evento non garantisce che tutti i dati associati all'interno della panoramica (come i link) siano cambiati anche al momento dell'attivazione di questo evento; questo evento indica solo che un ID panoramica è cambiato. Tieni presente che l'ID panoramica (che puoi utilizzare per fare riferimento a questa panoramica) è stabile solo all'interno della sessione corrente del browser.position_changed
si attiva ogni volta che la posizione sottostante (LatLng
) della panoramica cambia. La rotazione di una panoramica non attiva questo evento. Tieni presente che puoi modificare la posizione sottostante di una panoramica senza modificare l'ID panoramica associato, poiché l'API assocerà automaticamente l'ID panoramica più vicino alla posizione della panoramica.pov_changed
si attiva ogni volta cheStreetViewPov
di Street View cambia. Tieni presente che questo evento potrebbe attivarsi mentre la posizione e l'ID panoramica rimangono stabili.links_changed
si attiva ogni volta che i link di Street View cambiano. Tieni presente che questo evento potrebbe attivarsi in modo asincrono dopo una modifica nell'ID panoramica indicato tramitepano_changed
.visible_changed
si attiva ogni volta che la visibilità di Street View cambia. Tieni presente che questo evento potrebbe attivarsi in modo asincrono dopo una modifica nell'ID panoramica indicato tramitepano_changed
.
Il codice seguente illustra come è possibile gestire questi eventi per raccogliere dati su 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"> </td> </tr> <tr> <td><b>POV Heading</b></td> <td id="heading-cell">270</td> </tr> <tr> <td><b>POV Pitch</b></td> <td id="pitch-cell">0.0</td> </tr> <tr> <td><b>Pano ID</b></td> <td id="pano-cell"> </td> </tr> <table id="links_table"></table> </table> </div> <!-- The `defer` attribute causes the 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>
Prova di esempio
Controlli Street View
Quando visualizzi un StreetViewPanorama
, una varietà di controlli viene visualizzata sul panorama per impostazione predefinita. Puoi attivare o disattivare questi controlli impostando i campi appropriati in StreetViewPanoramaOptions
su true
o false
:
panControl
consente di ruotare il panorama. Per impostazione predefinita, questo controllo viene visualizzato come bussola integrata e controllo standard. Puoi modificare la posizione del controllo fornendoPanControlOptions
nel campopanControlOptions
.- L'elemento
zoomControl
consente di eseguire lo zoom all'interno dell'immagine. Per impostazione predefinita, questo controllo viene visualizzato nella parte inferiore destra della panoramica. Puoi modificare l'aspetto del controllo fornendoZoomControlOptions
nel campozoomControlOptions
. - Un
addressControl
fornisce un overlay di testo che indica l'indirizzo della località associata e offre un link per aprire la località in Google Maps. Puoi modificare l'aspetto del controllo fornendoStreetViewAddressControlOptions
nel campoaddressControlOptions
. fullscreenControl
offre l'opzione per aprire Street View in modalità a schermo intero. Puoi modificare l'aspetto del controllo fornendoFullscreenControlOptions
nel campofullscreenControlOptions
.motionTrackingControl
offre la possibilità di abilitare o disabilitare il monitoraggio dei movimenti sui dispositivi mobili. Questo controllo viene visualizzato solo sui dispositivi che supportano gli eventi di orientamento del dispositivo. Per impostazione predefinita, il controllo viene visualizzato in basso a destra nella panoramica. Puoi modificare la posizione del controllo fornendoMotionTrackingControlOptions
. Per ulteriori informazioni, consulta la sezione sul monitoraggio dei movimenti.- Un
linksControl
fornisce frecce sull'immagine per spostarti sulle immagini panoramiche adiacenti. - Un controllo Chiudi consente all'utente di chiudere il visualizzatore Street View. Puoi abilitare o disabilitare il controllo Chiudi impostando
enableCloseButton
sutrue
ofalse
.
L'esempio seguente modifica i controlli visualizzati all'interno delle immagini di Street View associate e rimuove i relativi link:
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>
Prova di esempio
Accedere direttamente ai dati di Street View
Potresti decidere di determinare in modo programmatico la disponibilità dei dati di Street View oppure restituire informazioni relative a determinati panorami, senza richiedere la manipolazione diretta di una mappa/panoramica. A tale scopo, utilizza
l'oggetto StreetViewService
, che fornisce
un'interfaccia per i dati archiviati nel servizio Street View di Google.
Richieste di servizio Street View
L'accesso al servizio Street View è asincrono, poiché l'API di Google Maps deve effettuare una chiamata a un server esterno. Per questo motivo, devi superare un metodo di callback da eseguire al termine della richiesta. Questo metodo di callback elabora il risultato.
Puoi avviare richieste a StreetViewService
utilizzando
StreetViewPanoRequest
o
StreetViewLocationRequest
.
Una richiesta che utilizza StreetViewPanoRequest
restituisce i dati
Panoramica in base a un ID di riferimento che identifica in modo univoco la panoramica. Tieni presente che questi ID di riferimento sono stabili solo per la durata delle immagini della panoramica.
Una richiesta che utilizza StreetViewLocationRequest
cerca
i dati della panoramica in una posizione specificata, utilizzando i seguenti parametri:
location
specifica la posizione (latitudine e longitudine) in cui cercare un panorama.preference
imposta una preferenza per quale panoramica deve essere trovata all'interno dell'area definita dal raggio: quella più vicina alla posizione specificata o quella migliore all'interno del raggio.radius
imposta un raggio, specificato in metri, in cui cercare un panorama centrato sulla latitudine e sulla longitudine specificate. Se non fornito, il valore predefinito è 50.source
specifica l'origine delle panoramiche da cercare. I valori validi sono:default
utilizza le sorgenti predefinite per Street View; le ricerche non sono limitate a sorgenti specifiche.outdoor
limita le ricerche alle raccolte all'aperto. Tieni presente che potrebbero non esistere panoramiche esterne per il luogo specificato.
Risposte del servizio Street View
La funzione getPanorama()
ha bisogno di una funzione di callback da eseguire al recupero di un risultato
dal servizio Street View. Questa funzione di callback restituisce un set di
dati panoramica all'interno di un oggetto StreetViewPanoramaData
e un
codice StreetViewStatus
che indica lo stato della richiesta, in
questo ordine.
La specifica di un oggetto StreetViewPanoramaData
contiene
metadati relativi a una panoramica di Street View del seguente formato:
{ "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 } }
Tieni presente che questo oggetto dati non è un oggetto StreetViewPanorama
stesso. Per creare un oggetto Street View utilizzando questi dati, è necessario creare un StreetViewPanorama
e chiamare
setPano()
, passando l'ID come indicato nel campo
location.pano
restituito.
Il codice status
potrebbe restituire uno dei seguenti valori:
OK
indica che il servizio ha trovato una panoramica corrispondente.ZERO_RESULTS
indica che il servizio non è riuscito a trovare una panoramica corrispondente con i criteri superati.UNKNOWN_ERROR
indica che non è stato possibile elaborare una richiesta Street View, anche se il motivo esatto è sconosciuto.
Il codice riportato di seguito crea un StreetViewService
che risponde ai clic dell'utente su una mappa creando indicatori che, se selezionati, mostrano un StreetViewPanorama
di tale località. Il codice utilizza i contenuti di StreetViewPanoramaData
restituiti dal servizio.
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>
Prova di esempio
Panoramiche in Street View personalizzate
L'API Maps JavaScript supporta la visualizzazione di panoramiche personalizzate
all'interno dell'oggetto StreetViewPanorama
. Con le panoramiche personalizzate puoi mostrare l'interno degli edifici, le viste da luoghi panoramici o qualsiasi cosa tu possa immaginare. Puoi persino
collegare queste panoramiche personalizzate alle panoramiche di Street View
esistenti di Google.
La configurazione di un insieme di immagini panoramiche personalizzate prevede i seguenti passaggi:
- Crea un'immagine panoramica di base per ogni panorama personalizzato. Questa immagine di base deve essere alla massima risoluzione con cui vuoi pubblicare immagini con zoom.
- (Facoltativo, ma consigliato) Crea un insieme di riquadri panoramici a diversi livelli di zoom dell'immagine di base.
- Crea collegamenti tra le panoramiche personalizzate.
- (Facoltativo) Definisci le panoramiche "in entrata" dalle immagini di Street View esistenti di Google e personalizza i link da/per l'insieme personalizzato all'insieme standard.
- Definisci i metadati per ogni immagine panoramica all'interno di un oggetto
StreetViewPanoramaData
. - Implementa un metodo che determini i dati e le immagini panoramiche personalizzati e designa tale metodo come gestore personalizzato
nell'oggetto
StreetViewPanorama
.
Questa procedura spiega le seguenti sezioni.
Creazione di panoramiche personalizzate
Ogni panorama di Street View è costituito da un'immagine o da un insieme di immagini
che offre una visione completa a 360 gradi da una singola posizione.
L'oggetto StreetViewPanorama
utilizza immagini conformi alla proiezione equirettangolare (Plate
Carrée). Questa proiezione contiene 360 gradi di vista orizzontale ( Questi campi della visualizzazione generano un'immagine con proporzioni 2:1. Di seguito è riportato un panorama completo.
In genere, le immagini panoramiche vengono scattate scattando più foto da una posizione e unendole utilizzando il software per la panoramica. Per saperne di più, consulta la pagina Confronto delle applicazioni di stitching delle foto di Wikipedia. Queste immagini devono condividere un unico luogo "fotocamera", da cui vengono tratte tutte le immagini panoramiche. La panoramica panoramica a 360° può quindi definire una proiezione su una sfera con l'immagine avvolta sulla superficie bidimensionale della sfera.
Trattare il panorama come una proiezione su una sfera con un sistema di coordinate rettilineo è vantaggioso quando si divide l'immagine in piastrelle rettangolari e si offrono immagini in base a coordinate di riquadri calcolate.
Creazione di riquadri panoramiche personalizzati
Street View supporta anche diversi livelli di dettaglio delle immagini grazie all'uso di un controllo zoom, che consente di aumentare e diminuire lo zoom dalla visualizzazione predefinita. In genere, Street View offre cinque livelli di risoluzione dello zoom per qualsiasi immagine panoramica. Se dovessi fare affidamento su una singola immagine panoramica per gestire tutti i livelli di zoom, un'immagine di questo tipo sarebbe necessariamente piuttosto grande e rallenterebbe notevolmente la tua applicazione, oppure avrà una risoluzione così bassa a livelli di zoom più elevati che useresti un'immagine pixellata con risoluzione scarsa. Fortunatamente, tuttavia, possiamo utilizzare un pattern di progettazione simile utilizzato per pubblicare i riquadri di mappa di Google a diversi livelli di zoom per fornire immagini con la risoluzione appropriata per le panoramiche a ogni livello di zoom.
Al primo caricamento di StreetViewPanorama
, per impostazione predefinita viene visualizzata un'immagine composta dal 25% (90 gradi dell'arco) dell'ampiezza orizzontale della panoramica al livello di zoom 1. Questa visualizzazione
corrisponde indicativamente a un normale campo visivo. Aumentando lo zoom verso il basso da questa visualizzazione predefinita, sostanzialmente si ottiene un arco più ampio, mentre lo zoom avanti restringe il campo di una visualizzazione a un arco più piccolo. StreetViewPanorama
calcola automaticamente il campo visivo appropriato per il livello di zoom selezionato, quindi seleziona le immagini più appropriate per la risoluzione selezionando un set di riquadri che corrisponde approssimativamente alle dimensioni del campo visivo orizzontale. I seguenti campi visivi vengono mappati ai livelli di zoom di Street View:
Livello di zoom Street View | Campo visivo (gradi) |
---|---|
0 | 180 |
1 (valore predefinito) | 90 |
2 | 45 |
3 | 22,5 |
4 | 11,25 |
Tieni presente che le dimensioni dell'immagine mostrata in Street View dipendono completamente dalle dimensioni dello schermo (larghezza) del contenitore di Street View. Se fornisci un container più ampio, il servizio continuerà a fornire lo stesso campo visivo per un determinato livello di zoom, anche se potrebbe selezionare riquadri più appropriati per la risoluzione in questione.
Poiché ogni panorama è costituito da una proiezione equirettangolare, creare riquadri di panoramica è relativamente facile. Poiché la proiezione fornisce un'immagine con proporzioni 2:1, i riquadri con proporzioni 2:1 sono più facili da usare, anche se i riquadri quadrati possono offrire prestazioni migliori sulle mappe quadrate (poiché il campo visivo sarà quadrato).
Per i riquadri 2:1, una singola immagine che include l'intero panorama rappresenta l'intero "mondo" (l'immagine di base) a livello di zoom 0, con ogni livello di zoom crescente che offre 4 riquadri zoomLevel. Ad esempio, al livello di zoom 2, l'intero panorama è composto da 16 riquadri. Nota: i livelli di zoom nel riquadro di Street View non corrispondono direttamente ai livelli di zoom forniti con il controllo di Street View. Al contrario, i livelli di zoom del controllo di Street View selezionano un campo visivo (FoV) da cui vengono selezionati i riquadri appropriati.
In genere, è consigliabile nominare i riquadri delle immagini in modo che possano essere selezionati in modo programmatico. Questo schema di denominazione è descritto più avanti in Gestione delle richieste personalizzate di panoramica.
Gestione delle richieste panoramiche personalizzate
Per utilizzare una panoramica personalizzata, chiama StreetViewPanorama.registerPanoProvider()
, specificando il nome del metodo del provider di panoramiche personalizzato. Il metodo del provider panoramica deve restituire un oggetto StreetViewPanoramaData
e avere la seguente firma:
Function(pano):StreetViewPanoramaData
StreetViewPanoramaData
è un oggetto del seguente modulo:
{ 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 ] }
Per visualizzare una panoramica personalizzata:
- Imposta la proprietà
StreetViewPanoramaOptions.pano
su un valore personalizzato. - Chiama
StreetViewPanorama.registerPanoProvider()
per fornire una funzione personalizzata di panoramica. - Implementa la funzione del fornitore di servizi panoramiche personalizzata per gestire il valore
pano
specificato. - Crea un oggetto
StreetViewPanoramaData
. - Imposta la proprietà
StreetViewTileData.getTileUrl
sul nome di una funzione personalizzata del fornitore di riquadri che fornisci. Ad esempio,getCustomPanoramaTileUrl
. - Implementare la funzione del fornitore di riquadri personalizzato, come mostrato negli esempi di seguito.
- Restituisci l'oggetto
StreetViewPanoramaData
.
Nota: non impostare direttamente un position
sul dispositivo StreetViewPanorama
quando vuoi visualizzare panoramiche personalizzate, poiché una posizione di questo tipo indica al servizio Street View di richiedere le immagini di Street View predefinite vicine al luogo in questione. Imposta invece questa posizione nel campo location.latLng
dell'oggetto StreetViewPanoramaData
personalizzato.
L'esempio seguente mostra una panoramica personalizzata dell'ufficio di Google Sydney. Tieni presente che questo esempio non utilizza una mappa o immagini di Street View predefinite:
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>
Prova di esempio
Il fornitore del panorama personalizzato restituisce il riquadro appropriato in base all'ID panoramica, al livello di zoom e alle coordinate del riquadro panoramico trasmessi.
Poiché la selezione delle immagini dipende da questi valori trasmessi, è utile assegnare un nome alle immagini che possono essere selezionate in modo programmatico date i valori trasmessi, ad esempio pano_zoom_tileX_tileY.png
.
L'esempio seguente aggiunge un'altra freccia all'immagine, oltre alle frecce di navigazione predefinite di Street View, che rimandano a Google Sydney e rimandano a immagini personalizzate:
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>