Eso es todo.

Para comenzar a desarrollar, consulta nuestra documentación para desarrolladores.

Activar la Google Maps JavaScript API

Para que puedas comenzar, te proporcionaremos orientación en la Google Developers Console a fin de que hagas primero algunas acciones:

  1. Crear o seleccionar un proyecto
  2. Activar la Google Maps JavaScript API y servicios relacionados
  3. Crear claves correspondientes
Continuar

Servicio de Street View

Información general

Google Street View proporciona vistas panorámicas a 360 grados de ubicaciones designadas en su área de cobertura. La cobertura de la API de Street View es igual a la que ofrece la aplicación de Google Maps (https://maps.google.com/). La lista de ciudades admitidas de Street View se encuentra disponible en el sitio web de Google Maps.

A continuación, se muestra una imagen de Street View.


La Google Maps JavaScript API proporciona un servicio de Street View para obtener y administrar las imágenes usadas en Street View de Google Maps. Este servicio de Street View tiene compatibilidad nativa con el navegador.

Uso de mapas de Street View

Aunque Street View puede usarse dentro de un elemento de DOM independiente, su mayor utilidad se manifiesta cuando se indica una ubicación en un mapa. De manera predeterminada, Street View se habilita a los mapas y el control del Pegman aparece integrado dentro de los controles de navegación (zoom y desplazamiento). Puedes ocultar este control dentro del objeto MapOptions fijando el valor de streetViewControl en false. También puedes cambiar la posición predeterminada del control de Street View configurando la propiedad streetViewControlOptions.position del objeto Map en una nueva ControlPosition.

El control del Pegman de Street View te permite ver panoramas de Street View de manera directa dentro del mapa. Cuando el usuario mantiene presionado el botón del mouse sobre el Pegman, el mapa se actualiza y muestra contornos azules alrededor de las calles con Street View activado. Esto ofrece al usuario una experiencia similar a la que brinda la aplicación de Google Maps.

Cuando el usuario suelta el marcador del Pegman sobre una calle, el mapa se actualiza y muestra un panorama de Street View de la ubicación indicada.

Panoramas de Street View

Se admiten imágenes de Street View a través del objeto StreetViewPanorama, que proporciona una interfaz de API a un “visor” de Street View. Cada mapa contiene un panorama predeterminado de Street View que puedes recuperar llamando al método getStreetView() del mapa. Al agregar un control de Street View al mapa fijando su opción streetViewControl en true, el control del Pegman se conecta automáticamente a este panorama predeterminado de Street View.

También puedes crear tu propio objeto StreetViewPanorama y configurar el mapa, a fin de que lo use en lugar del valor predeterminado, fijando su propiedad streetView de manera explícita en ese objeto construido. Probablemente desees invalidar el panorama predeterminado si deseas modificar el comportamiento predeterminado, como el uso compartido de superposiciones entre el mapa y el panorama. (Consulta Superposiciones dentro de Street View, a continuación).

Contenedores de Street View

Como alternativa, es posible que desees mostrar un StreetViewPanorama dentro de un elemento de DOM element separado; a menudo, un <div>. Simplemente, pasa el elemento de DOM dentro del constructor de StreetViewPanorama. Para que la visualización de imágenes se óptima, recomendamos un tamaño mínimo de 200 por 200 píxeles.

Nota: Aunque la funcionalidad de Street View está diseñada para usarse con un mapa, esta implementación no es necesaria. Puedes usar un objeto de Street View independiente sin un mapa.

Ubicaciones y punto de vista (POV) de Street View

El constructor de StreetViewPanorama también te permite configurar la ubicación y el punto de vista de Street View usando el parámetro StreetViewOptions. Puedes llamar a setPosition() y setPov() en el objeto después de la construcción para cambiar su ubicación y POV.

La ubicación de Street View define la ubicación del foco de la cámara de una imagen, pero no establece la orientación de la cámara para dicha imagen. Para este propósito, el objeto StreetViewPov define dos propiedades:

  • heading (el valor predeterminado es 0) define el ángulo de rotación alrededor del sitio de la cámara en grados respecto del norte geográfico. Los encabezados se miden en sentido horario (el punto de 90 grados representa el este verdadero).
  • pitch (el valor predeterminado es 0) define la variación de ángulo “hacia arriba” o “hacia abajo” a partir de la inclinación inicial predeterminada de la cámara, que a menudo (no siempre) es horizontal y plana. (Por ejemplo, una imagen tomada en una colina posiblemente exhiba una inclinación predeterminada que no es horizontal). Los ángulos de inclinación se miden con valores positivos que apuntan hacia arriba (hasta +90 grados en línea recta hacia arriba y ortogonal respecto de la inclinación predeterminada) y valores negativos que apuntan hacia abajo (hasta -90 grados en línea recta hacia abajo y ortogonales respecto de la inclinación predeterminada).

El objeto StreetViewPov se usa con mayor frecuencia para determinar el punto de vista de la cámara de Street View. También puedes determinar el punto de vista del fotógrafo (normalmente, la dirección en que apuntaba el auto o vehículo “trike”) con el método StreetViewPanorama.getPhotographerPov().

En el ejemplo siguiente aparece un mapa de Boston con una vista inicial del Fenway Park. Si se selecciona el Pegman y se lo arrastra hasta una ubicación admitida en el mapa, cambiará el panorama de Street View:

function initialize() {
  var fenway = {lat: 42.345573, lng: -71.098326};
  var map = new google.maps.Map(document.getElementById('map'), {
    center: fenway,
    zoom: 14
  });
  var panorama = new google.maps.StreetViewPanorama(
      document.getElementById('pano'), {
        position: fenway,
        pov: {
          heading: 34,
          pitch: 10
        }
      });
  map.setStreetView(panorama);
}
<div id="map"></div>
<div id="pano"></div>
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#map, #pano {
  float: left;
  height: 100%;
  width: 45%;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize">
</script>
function initialize() {
  var fenway = {lat: 42.345573, lng: -71.098326};
  var map = new google.maps.Map(document.getElementById('map'), {
    center: fenway,
    zoom: 14
  });
  var panorama = new google.maps.StreetViewPanorama(
      document.getElementById('pano'), {
        position: fenway,
        pov: {
          heading: 34,
          pitch: 10
        }
      });
  map.setStreetView(panorama);
}

Ver el ejemplo (streetview-simple.html).

Rastreo de movimiento en dispositivos móviles

En dispositivos que admiten eventos de orientación del dispositivo, la API ofrece a los usuarios la posibilidad de cambiar el punto de vista de Street View según el movimiento del dispositivo. Los usuarios pueden echar un vistazo moviendo sus dispositivos. Esto se denomina “rastreo de movimiento” o “rastreo de rotación de dispositivo”.

Como desarrollador de apps, puedes cambiar el comportamiento predeterminado de la siguiente manera:

  • Habilitar o inhabilitar la funcionalidad del rastreo de movimiento. De forma predeterminada, el rastreo de movimiento se encuentra habilitado en cualquier dispositivo que lo admita. El siguiente ejemplo inhabilita el rastreo de movimiento, pero deja visible el control de rastreo de movimiento. (Ten en cuenta que el usuario puede activar el rastreo de movimiento tocando el control).
    var panorama = new google.maps.StreetViewPanorama(
        document.getElementById('pano'), {
          position: {lat: 37.869260, lng: -122.254811},
          pov: {heading: 165, pitch: 0},
          motionTracking: false
        });
    
  • Oculta o muestra el control de rastreo de movimiento. De forma predeterminada, el control se muestra en dispositivos que admiten el rastreo de movimiento. El usuario puede tocar el control para activar o desactivar el rastreo de movimiento. Ten en cuenta que el control nunca aparecerá si el dispositivo no admite el rastreo de movimiento, independientemente del valor demotionTrackingControl.

    En el siguiente ejemplo se inhabilitan el rastreo de movimiento y el control de este. En este caso, el usuario no puede activar el rastreo de movimiento:

    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
        });
    
  • Cambiar la posición predeterminada del control de rastreo de movimiento. De forma predeterminada, el control aparece cerca de la esquina inferior derecha del panorama (posición RIGHT_BOTTOM). En el siguiente ejemplo, se configura la posición del control en la parte inferior izquierda:
    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
          }
        });
    

Para ver el rastreo de movimiento en acción, mira el siguiente ejemplo en un dispositivo móvil (o cualquier dispositivo que admita eventos de orientación de dispositivos):


Visualiza el ejemplo en una página nueva (streetview-embed.html).

Superposiciones dentro de Street View

El objeto StreetViewPanorama admite la visualización nativa de superposiciones de mapas. Las superposiciones generalmente aparecen en el “nivel de la calle” ancladas en posiciones de objetos LatLng. (Los marcadores aparecerán con los extremos anclados en el plano horizontal de la ubicación, por ejemplo, dentro del panorama de Street View).

Actualmente, los tipos de superposiciones admitidos en panoramas de Street View se limitan a objetos OverlayView personalizados, Marker y InfoWindow. Las superposiciones que se muestran en un mapa pueden aparecer en un panorama de Street View si se trata el panorama como a un sustituto para el objeto Map, se llama a setMap() y se pasa el objeto StreetViewPanorama como un argumento en lugar de un mapa. Las ventanas de información pueden abrirse dentro de un panorama de Street View llamando a open(), y pasando StreetViewPanorama() en lugar de un mapa.

A su vez, cuando se crea un mapa con un StreetViewPanorama predeterminado, se comparten de manera automática los marcadores generados en un mapa con el panorama de Street View asociado del mapa, dado que el panorama es visible. Para recuperar el panorama de Street View predeterminado, llama a getStreetView() en el objeto Map. Ten en cuenta que si configuras de manera explícita la propiedad streetView del mapa en un objeto StreetViewPanorama que construyas tú mismo, invalidarás el panorama predeterminado y deshabilitarás el uso compartido de superposiciones.

En el ejemplo siguiente, se muestran marcadores que indican varias ubicaciones en Astor Place, Nueva York. Activa la visualización de Street View para que se muestren los marcadores compartidos que aparecen en StreetViewPanorama.

var panorama;

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

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

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

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

  var busMarker = new google.maps.Marker({
      position: {lat: 40.729559, lng: -73.990741},
      map: 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();
  panorama.setPosition(astorPlace);
  panorama.setPov(/** @type {google.maps.StreetViewPov} */({
    heading: 265,
    pitch: 0
  }));
}

function toggleStreetView() {
  var toggle = panorama.getVisible();
  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}
<div id="floating-panel">
  <input type="button" value="Toggle Street View" onclick="toggleStreetView();"></input>
</div>
<div id="map"></div>
/* 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;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
var panorama;

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

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

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

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

  var busMarker = new google.maps.Marker({
      position: {lat: 40.729559, lng: -73.990741},
      map: 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();
  panorama.setPosition(astorPlace);
  panorama.setPov(/** @type {google.maps.StreetViewPov} */({
    heading: 265,
    pitch: 0
  }));
}

function toggleStreetView() {
  var toggle = panorama.getVisible();
  if (toggle == false) {
    panorama.setVisible(true);
  } else {
    panorama.setVisible(false);
  }
}

Ver el ejemplo (streetview-overlays.html).

Eventos de Street View

Al navegar entre Street View o manipular su orientación, probablemente desees controlar varios eventos que indiquen cambios en el estado del objeto StreetViewPanorama:

  • pano_changed se activa cuando cambia el id. individual de pano. En el momento en que se active, este evento no garantiza que también cambien los datos asociados dentro del panorama (como los vínculos). Solo indica el cambio de un id. de pano. Ten en cuenta que el id. de pano (que puedes usar para hacer referencia a este panorama) solo es estable en la sesión actual del navegador.
  • position_changed se activa cuando cambia la posición subyacente (LatLng) del panorama. La rotación de un panorama no activará este evento. Ten en cuenta que podrías cambiar la posición subyacente de un panorama sin modificar el id. de pano asociado, ya que la API asociará de manera automática el id. de pano más cercano a la posición del panorama.
  • pov_changed se activa cuando cambia el objeto StreetViewPov de Street View. Ten en cuenta que este evento puede activarse mientras la posición y el id. de pano permanecen estables.
  • links_changed se activa cuando cambian los vínculos de Street View. Ten en cuenta que este evento puede activarse de manera asincrónica tras un cambio en el id. de pano indicado a través de pano_changed.
  • visible_changed se activa cuando cambia la visibilidad de Street View. Ten en cuenta que este evento puede activarse de manera asincrónica tras un cambio en el Id. de pano indicado a través de pano_changed.

En el código siguiente se muestra la manera en que pueden administrarse estos eventos para recopilar datos sobre el objeto StreetViewPanorama:

function initPano() {
  var 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', function() {
      var panoCell = document.getElementById('pano-cell');
      panoCell.innerHTML = panorama.getPano();
  });

  panorama.addListener('links_changed', function() {
      var linksTable = document.getElementById('links_table');
      while (linksTable.hasChildNodes()) {
        linksTable.removeChild(linksTable.lastChild);
      }
      var links = panorama.getLinks();
      for (var i in links) {
        var row = document.createElement('tr');
        linksTable.appendChild(row);
        var labelCell = document.createElement('td');
        labelCell.innerHTML = '<b>Link: ' + i + '</b>';
        var valueCell = document.createElement('td');
        valueCell.innerHTML = links[i].description;
        linksTable.appendChild(labelCell);
        linksTable.appendChild(valueCell);
      }
  });

  panorama.addListener('position_changed', function() {
      var positionCell = document.getElementById('position-cell');
      positionCell.firstChild.nodeValue = panorama.getPosition() + '';
  });

  panorama.addListener('pov_changed', function() {
      var headingCell = document.getElementById('heading-cell');
      var pitchCell = document.getElementById('pitch-cell');
      headingCell.firstChild.nodeValue = panorama.getPov().heading + '';
      pitchCell.firstChild.nodeValue = panorama.getPov().pitch + '';
  });
}
<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>
/* 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;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initPano">
</script>
function initPano() {
  var 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', function() {
      var panoCell = document.getElementById('pano-cell');
      panoCell.innerHTML = panorama.getPano();
  });

  panorama.addListener('links_changed', function() {
      var linksTable = document.getElementById('links_table');
      while (linksTable.hasChildNodes()) {
        linksTable.removeChild(linksTable.lastChild);
      }
      var links = panorama.getLinks();
      for (var i in links) {
        var row = document.createElement('tr');
        linksTable.appendChild(row);
        var labelCell = document.createElement('td');
        labelCell.innerHTML = '<b>Link: ' + i + '</b>';
        var valueCell = document.createElement('td');
        valueCell.innerHTML = links[i].description;
        linksTable.appendChild(labelCell);
        linksTable.appendChild(valueCell);
      }
  });

  panorama.addListener('position_changed', function() {
      var positionCell = document.getElementById('position-cell');
      positionCell.firstChild.nodeValue = panorama.getPosition() + '';
  });

  panorama.addListener('pov_changed', function() {
      var headingCell = document.getElementById('heading-cell');
      var pitchCell = document.getElementById('pitch-cell');
      headingCell.firstChild.nodeValue = panorama.getPov().heading + '';
      pitchCell.firstChild.nodeValue = panorama.getPov().pitch + '';
  });
}

Ver el ejemplo (streetview-events.html).

Controles de Street View

Cuando se muestra un objeto StreetViewPanorama, aparecen varios controles en el panorama de manera predeterminada. Puedes habilitar o inhabilitar estos controles fijando en true o false los campos correspondientes dentro de StreetViewPanoramaOptions:

  • Un objeto panControl proporciona un método para rotar el panorama. Este control aparece, de manera predeterminada, como un control integrado de brújula y desplazamiento estándar. Puedes modificar la posición del control proporcionando PanControlOptions dentro del campo panControlOptions.
  • Un campo zoomControl proporciona un método para hacer zoom dentro de la imagen. Este control aparece de manera predeterminada cerca de la esquina inferior derecha del panorama. Puedes modificar el aspecto del control proporcionando ZoomControlOptions dentro del campo zoomControlOptions.
  • Un objeto addressControl proporciona una superposición textual que indica la dirección de la ubicación asociada y un vínculo para abrirla en Google Maps. Puedes modificar el aspecto del control proporcionando StreetViewAddressControlOptions dentro del campo addressControlOptions.
  • Un fullScreenControl ofrece la opción para abrir Street View en el modo de pantalla completa. Puedes modificar el aspecto del control proporcionando FullScreenAddressControlOptions dentro del campo fullScreenControlOptions.
  • Un motionTrackingControl ofrece la opción de habilitar o inhabilitar el rastreo de movimiento en dispositivos móviles. Este control solo aparece en dispositivos que admiten eventos de orientación de dispositivos. De forma predeterminada, el control aparece cerca de la esquina inferior derecha del panorama. Puedes modificar la posición del control proporcionando MotionTrackingControlOptions. Para obtener más información, consulta la sección en rastreo de movimiento.
  • Un objeto linksControl proporciona flechas de guía en la imagen para el desplazamiento hacia imágenes panorámicas cercanas.
  • Un control “Close” permite al usuario cerrar el visor de Street View. Puedes habilitar o deshabilitar el control “Close” fijando enableCloseButton en true o false:

En el ejemplo siguiente se modifican los controles que se muestran dentro del modo Street View asociado y se eliminan los vínculos de la vista:

Ver este ejemplo en pantalla completa.

function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  var 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
  });
}
<div id="map"></div>
/* 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;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initPano">
</script>
function initPano() {
  // Note: constructed panorama objects have visible: true
  // set by default.
  var 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
  });
}

Ver el ejemplo (streetview-controls.html).

Cómo acceder directamente a los datos de Street View

Es posible que desees determinar de manera programática la disponibilidad de datos de Street View, o devolver información sobre determinados panoramas, sin necesidad de manipular un mapa o panorama en forma directa. Puedes hacerlo a través del objeto StreetViewService, que proporciona una interfaz de los datos almacenados en el servicio de Street View de Google.

Solicitudes de servicio de Street View

El acceso al servicio de Street View es asincrónico, ya que la Google Maps API debe realizar una llamada a un servidor externo. Por esta razón, debes pasar un método callback para la ejecución al completarse la solicitud. Este método callback procesa el resultado.

Puedes iniciar dos tipos de solicitudes del objeto StreetViewService:

  • Con un objeto StreetViewPanoRequest. Esto devuelve datos panorámicos con un id. de referencia determinado que identifica el panorama de manera exclusiva. Ten en cuenta que estos id. de referencia solo son estables durante la vida útil de las imágenes del panorama en cuestión.
  • Con un objeto StreetViewLocationRequest. A través de esta, se buscan datos panorámicos en un área determinada cuando se pasa un objeto LatLng.

Respuestas del servicio de Street View

<Para la función getPanorama() es necesario que se ejecute una función de callback tras la obtención de un resultado del servicio de Street View. Esta función de callback devuelve un conjunto de datos panorámicos dentro de un objeto StreetViewPanoramaData y un código de StreetViewStatus que indica el estado de la solicitud, en el orden mencionado.

Una especificación del objeto StreetViewPanoramaData contiene metadatos sobre un panorama de Street View con la siguiente forma:

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

Ten en cuenta que este objeto de datos no es un objeto StreetViewPanorama en sí mismo. Para crear un objeto de Street View usando estos datos, deberás crear un objeto StreetViewPanorama, llamar a setPano() y pasarle el id. según lo que se observa en el campo location.pano devuelto.

El código status puede devolver uno de los siguientes valores:

  • OK indica que el servicio encontró un panorama coincidente.
  • ZERO_RESULTS indica que el servicio no pudo encontrar un panorama coincidente con los criterios pasados.
  • UNKNOWN_ERROR indica que no se pudo procesar una solicitud de Street View, aunque se desconoce el motivo exacto.

Con el código siguiente se crea un StreetViewService que responde a los clics del usuario con la creación de marcadores que, una vez seleccionados, muestran un objeto StreetViewPanorama de la ubicación en cuestión. En el código, se usa contenido de StreetViewPanoramaData devuelto a través del servicio.

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

var map;
var panorama;

function initMap() {
  var berkeley = {lat: 37.869085, lng: -122.254775};
  var 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}, processSVData);

  // Look for a nearby Street View panorama when the map is clicked.
  // getPanoramaByLocation will return the nearest pano when the
  // given radius is 50 meters or less.
  map.addListener('click', function(event) {
    sv.getPanorama({location: event.latLng, radius: 50}, processSVData);
  });
}

function processSVData(data, status) {
  if (status === 'OK') {
    var marker = new google.maps.Marker({
      position: data.location.latLng,
      map: map,
      title: data.location.description
    });

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

    marker.addListener('click', function() {
      var markerPanoID = data.location.pano;
      // Set the Pano to use the passed panoID.
      panorama.setPano(markerPanoID);
      panorama.setPov({
        heading: 270,
        pitch: 0
      });
      panorama.setVisible(true);
    });
  } else {
    console.error('Street View data not found for this location.');
  }
}
<div id="map" style="width: 45%; height: 100%;float:left"></div>
<div id="pano" style="width: 45%; height: 100%;float:left"></div>
/* 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;
}
 <!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initMap">
</script>
/*
 * Click the map to set a new location for the Street View camera.
 */

var map;
var panorama;

function initMap() {
  var berkeley = {lat: 37.869085, lng: -122.254775};
  var 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}, processSVData);

  // Look for a nearby Street View panorama when the map is clicked.
  // getPanoramaByLocation will return the nearest pano when the
  // given radius is 50 meters or less.
  map.addListener('click', function(event) {
    sv.getPanorama({location: event.latLng, radius: 50}, processSVData);
  });
}

function processSVData(data, status) {
  if (status === 'OK') {
    var marker = new google.maps.Marker({
      position: data.location.latLng,
      map: map,
      title: data.location.description
    });

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

    marker.addListener('click', function() {
      var markerPanoID = data.location.pano;
      // Set the Pano to use the passed panoID.
      panorama.setPano(markerPanoID);
      panorama.setPov({
        heading: 270,
        pitch: 0
      });
      panorama.setVisible(true);
    });
  } else {
    console.error('Street View data not found for this location.');
  }
}

Ver el ejemplo (streetview-service.html).

Cómo proporcionar panoramas de Street View personalizados

La Google Maps JavaScript API admite la visualización de panoramas personalizados dentro del objeto StreetViewPanorama. Mediante panoramas personalizados, puedes mostrar el interior de edificios, vistas de lugares pintorescos o lo que se te ocurra. Puedes incluso vincular estos panoramas a panoramas existentes de Street View de Google.

Para configurar un panorama personalizado deben realizarse los siguientes pasos:

  • Crea una imagen panorámica básica para cada panorama personalizado. Esta imagen básica debe tener la máxima resolución con la cual desees aportar imágenes ampliadas.
  • (Opcional, pero recomendado) Crea un conjunto de mosaicos panorámicos a diferentes niveles de zoom a partir de la imagen básica.
  • Crea vínculos entre tus panoramas personalizados.
  • (Opcional) Designa panoramas de “entrada” dentro de las imágenes de Street View existentes de Google y personaliza vínculos hacia o desde el conjunto personalizado para el conjunto estándar.
  • Define metadatos para cada imagen panorámica dentro de un objeto StreetViewPanoramaData.
  • Implementa un método que determine las imágenes y los datos panorámicos personalizados, y desígnalo como tu gestor personalizado dentro del objeto StreetViewPanorama.

En las secciones siguientes se explica el proceso.

Cómo crear panoramas personalizados:

Cada panorama de Street View es una imagen, o un conjunto de imágenes, que proporciona una vista a 360 grados desde una ubicación. El objeto StreetViewPanorama usa imágenes que cumplen con la proyección equirrectangular (Plate Carrée). Esta proyección contiene una vista horizontal a 360 grados (vista envolvente completa) y una vista vertical a 180 grados (desde el extremo superior hasta el inferior). A partir de estos campos se genera una imagen con una relación de aspecto de 2:1. A continuación, se muestra un panorama completo envolvente.

Las imágenes panorámicas se obtienen generalmente tomando varias fotos de una posición y uniéndolas con software que permite generar estas vistas. (Para obtener más información, consulta Editores de foto stitching en Wikipedia). Dichas imágenes deben compartir un único sitio para la “cámara” a partir del cual se obtenga cada una de las imágenes panorámicas. El panorama a 360 grados resultante define una proyección en una esfera con la imagen ajustada a la superficie bidimensional de la esfera.

Tratar el panorama como una proyección en una esfera con un sistema de coordenadas rectilíneas resulta ventajoso al dividir la imagen en mosaicos rectilíneos y proporcionar imágenes basadas en coordenadas de mosaicos computados.

Cómo crear mosaicos de panoramas personalizados

Street View también admite diferentes niveles de detalle de imágenes a través de un control de zoom, lo cual te permite aplicar zoom de acercamiento y alejamiento a la vista predeterminada. En general, Street View proporciona cinco niveles de resolución de zoom para cualquier imagen panorámica. Si usas una única imagen panorámica para todos los niveles de zoom, esta necesariamente será bastante grande y reducirá el rendimiento de tu aplicación o, a niveles de zoom superiores, tendrá una resolución tan baja que exhibirá poca calidad y píxeles visibles. Afortunadamente, sin embargo, se puede usar un patrón de diseño para ofrecer mosaicos de mapas de Google a diferentes niveles de zoom, a fin de ofrecer imágenes panorámicas con la resolución adecuada en cada uno de estos niveles.

Cuando se carga un objeto StreetViewPanorama por primera vez, este muestra de manera predeterminada una imagen que comprende un 25% (90 grados de arco) de la amplitud horizontal del panorama en el nivel de zoom 1. Esta vista se aproxima al campo visual de un ser humano convencional. El alejamiento de esta vista predeterminada proporciona básicamente un arco más amplio, mientras que el acercamiento reduce el campo visual a un arco más pequeño. El objeto StreetViewPanorama calcula en forma automática el campo visual correspondiente para el nivel de zoom seleccionado y luego selecciona las imágenes más apropiadas para dicha resolución seleccionando un conjunto de mosaicos que tenga un nivel de coincidencia aproximado respecto de las dimensiones del campo visual horizontal. Se asignan los siguientes campos visuales a los niveles de zoom de Street View:

Nivel de zoom de Street View Campo visual (grados)
0 180
1 (predeterminado). 90
2 45
3 22,5
4 11,25

Ten en cuenta que el tamaño de la imagen que se muestra dentro de Street View depende totalmente del tamaño de la pantalla (ancho) del contenedor de Street View. Si proporcionas un contenedor más amplio, el servicio proporcionará el mismo campo visual para cualquier nivel de zoom. No obstante, puede seleccionar mosaicos más adecuados para dicha resolución.

Debido a que cada panorama consiste en una proyección equirrectangular, crear mosaicos de panoramas es relativamente fácil. Debido a que la proyección proporciona una imagen con una relación de aspecto de 2:1, resulta más sencillo usar mosaicos con la misma relación de aspecto, si bien los mosaicos cuadrados pueden tener un mejor rendimiento en mapas de ángulos rectos (ya que el campo visual será rectangular).

En el caso de los mosaicos con relación de aspecto de 2:1, una única imagen que abarca el panorama por completo representa todo el panorama “mundo” (imagen básica) en el nivel de zoom 0, y en cada nivel de zoom de acercamiento se ofrecen mosaicos 4zoomLevel. (En el nivel de zoom 2, p. ej., todo el panorama consta de 16 mosaicos). Nota: Los niveles de zoom de mosaicos de Street View no coindicen en forma directa con los niveles de zoom proporcionados al usar el control de Street View. Como alternativa, a través de los niveles de zoom del control de Street View se selecciona un campo visual (FoV) a partir del cual se seleccionan los mosaicos correspondientes.

En general, te convendrá asignar nombres a tus mosaicos de imágenes para que puedan seleccionarse en forma programática. A continuación, en Administración de solicitudes de panoramas personalizados, se analiza un esquema de asignación de nombres.

Administración de solicitudes de panoramas personalizados

El uso de panoramas peronalizados se indica registrando un método de panoramas personalizados dentro del campo StreetViewPanoramaOptions panoProvider o llamando a StreetViewPanorama.registerPanoProvider() de manera explícita. El método que proporciona panoramas es una función que devuelve un objeto StreetViewPanoramaData y tiene la siguiente firma:

Function(pano,zoom,tileX,tileY):StreetViewPanoramaData

StreetViewPanoramaData es un objeto que tiene la siguiente forma:

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

Puedes hacer que se vea un panorama personalizado con solo fijar la propiedad pano de StreetViewPanorama en un valor personalizado, configurar panoProvider y luego administrar el valor personalizado de pano dentro del método que proporciona panoramas personalizados, construir un objeto StreetViewPanoramaData y devolverlo.

Nota: no configures directamente una propiedad position en StreetViewPanorama cuando desees que se muestren panoramas personalizados, ya que dicha propiedad indicará al servicio de Street View que solicite las imágenes de Street View cercanas a la ubicación. En lugar de ello, configura esta posición dentro del campo location.latLng de StreetViewPanoramaData.

En el ejemplo siguiente se muestra un panorama personalizado de la oficina de Google en Sídney. Ten en cuenta que en este caso no se recurre a un mapa (ni a imágenes predeterminadas de Street View):

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.
  var panorama = new google.maps.StreetViewPanorama(
    document.getElementById('map'), {
      pano: 'reception',
      visible: true,
      panoProvider: getCustomPanorama
  });
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
  // Note: robust custom panorama methods would require tiled pano data.
  // Here we're just using a single tile, set to the tile size and equal
  // to the pano "world" size.
  return 'https://developers.google.com/maps/documentation/javascript/examples/full/images/panoReception1024-0.jpg';
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano, zoom, tileX, tileY) {
  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(1024, 512),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl
      }
    };
  }
}
<div id="map"></div>
/* 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;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initPano">
</script>
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.
  var panorama = new google.maps.StreetViewPanorama(
    document.getElementById('map'), {
      pano: 'reception',
      visible: true,
      panoProvider: getCustomPanorama
  });
}

// Return a pano image given the panoID.
function getCustomPanoramaTileUrl(pano, zoom, tileX, tileY) {
  // Note: robust custom panorama methods would require tiled pano data.
  // Here we're just using a single tile, set to the tile size and equal
  // to the pano "world" size.
  return 'https://developers.google.com/maps/documentation/javascript/examples/full/images/panoReception1024-0.jpg';
}

// Construct the appropriate StreetViewPanoramaData given
// the passed pano IDs.
function getCustomPanorama(pano, zoom, tileX, tileY) {
  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(1024, 512),
        // The heading in degrees at the origin of the panorama
        // tile set.
        centerHeading: 105,
        getTileUrl: getCustomPanoramaTileUrl
      }
    };
  }
}

Ver el ejemplo (streetview-custom-simple.html).

Observa que en el ejemplo anterior solo se devolvió una imagen, y que el zoom de acercamiento sobre esa imagen dio como resultado una baja resolución. Como alternativa, se puede ofrecer un conjunto de mosaicos creando imágenes de mosaicos y modificando panoProvider de modo que devuelva el mosaico correspondiente con el id. de panorama transmitido y la coordenada de mosaicos de panorama.

Debido a que la selección de imágenes depende de estos valores pasados, resulta útil nombrar imágenes que puedan seleccionarse de manera programática con esos valores; por ejemplo, pano_zoom_tileX_tileY.png.

En el ejemplo siguiente se aplica un leve aumento para incluir dos niveles de zoom. Además de las flechas de navegación predeterminadas de Street View, se agrega a la imagen otra flecha que apunta hacia la oficina de Google en Sídney y genera un vínculo a las imágenes personalizadas:

var panorama;

// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
var 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 our custom panorama.
        panoProvider: function(pano) {
          if (pano === 'reception') {
            return getReceptionPanoramaData();
          }
        }
      });

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

function initialize() {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  var streetviewService = new google.maps.StreetViewService;
  streetviewService.getPanorama(
      {location: {lat: -33.867386, lng: 151.195767}},
      function(result, status) {
        if (status === 'OK') {
          outsideGoogle = result;
          initPanorama();
        }
      });
}
<div id="street-view"></div>
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#street-view {
  height: 100%;
}
<!-- Replace the value of the key parameter with your own API key. -->
<script async defer
    src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&callback=initialize">
</script>
var panorama;

// StreetViewPanoramaData of a panorama just outside the Google Sydney office.
var 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 our custom panorama.
        panoProvider: function(pano) {
          if (pano === 'reception') {
            return getReceptionPanoramaData();
          }
        }
      });

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

function initialize() {
  // Use the Street View service to find a pano ID on Pirrama Rd, outside the
  // Google office.
  var streetviewService = new google.maps.StreetViewService;
  streetviewService.getPanorama(
      {location: {lat: -33.867386, lng: 151.195767}},
      function(result, status) {
        if (status === 'OK') {
          outsideGoogle = result;
          initPanorama();
        }
      });
}

Ver el ejemplo (streetview-custom-tiles.html).

Enviar comentarios sobre...

Google Maps JavaScript API
Google Maps JavaScript API
Si necesitas ayuda, visita nuestra página de asistencia.