1. Antes de comenzar
Aprende a usar las APIs de Maps y Places de Google Maps Platform para crear una búsqueda de empresas locales que geolocalice al usuario y muestre lugares interesantes cercanos. La app integra la ubicación geográfica, Place Details, Place Photos y mucho más.
Requisitos previos
- Conocimientos básicos de HTML, CSS y JavaScript
- Un proyecto con una cuenta de facturación (sigue las instrucciones del siguiente paso si no tienes una)
- Para este paso, debes habilitar la API de Maps JavaScript y la API de Places.
- Es una clave de API para el proyecto anterior.
Cómo comenzar a utilizar Google Maps Platform
Si nunca usaste Google Maps Platform, sigue la guía Cómo comenzar a utilizar Google Maps Platform o mira la lista de reproducción Cómo comenzar a utilizar Google Maps Platform para completar los siguientes pasos:
- Crear una cuenta de facturación
- Crear un proyecto
- Habilitar las API y los SDK de Google Maps Platform (enumerados en la sección anterior)
- Generar una clave de API
Actividades
- Crea una página web que muestre un mapa de Google Maps
- Se centró el mapa en la ubicación del usuario.
- Encontrar lugares cercanos y mostrar los resultados como marcadores en los que se puede hacer clic
- Recuperar y mostrar más detalles sobre cada lugar
Requisitos
- Un navegador web, como Google Chrome (recomendado), Firefox, Safari o Internet Explorer
- Tu editor de texto o código favorito
Obtén el código de muestra
- Abre la interfaz de línea de comandos (Terminal en macOS o Símbolo del sistema en Windows) y descarga el código de muestra con este comando:
git clone https://github.com/googlecodelabs/google-maps-nearby-search-js/
Si eso no funciona, haz clic en el siguiente botón para descargar todo el código de este codelab y, luego, descomprime el archivo:
- Cambia al directorio que acabas de clonar o descargar.
cd google-maps-nearby-search-js
Las carpetas stepN
contienen el estado final deseado de cada paso de este codelab. Están disponibles como referencia. Realiza todo el trabajo de codificación en el directorio llamado work
.
2. Cómo crear un mapa con un centro predeterminado
Para crear un mapa de Google Maps en tu página web, sigue estos tres pasos:
- Crea una página HTML
- Agrega un mapa
- Pega tu clave de API
1. Crea una página HTML
A continuación, se muestra el mapa creado en este paso. El mapa está centrado en la Ópera de Sídney, en Sídney, Australia. Si el usuario rechaza el permiso para obtener su ubicación, el mapa se establecerá de forma predeterminada en esta ubicación y seguirá proporcionando resultados de búsqueda interesantes.
- Cambia los directorios a tu carpeta
work/
. En el resto del codelab, realiza las ediciones en la versión de la carpetawork/
.
cd work
- En el directorio
work/
, usa tu editor de texto para crear un archivo en blanco llamadoindex.html
. - Copia el siguiente código en
index.html
.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Sushi Finder</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 100%;
background-color: grey;
}
/* Optional: Makes the sample page fill the window. */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
/* TODO: Step 4A1: Make a generic sidebar. */
</style>
</head>
<body>
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- Map appears here -->
<div id="map"></div>
<!-- TODO: Step 1B, Add a map -->
</body>
</html>
- Abre el archivo
index.html
en tu navegador web.
open index.html
2. Agrega un mapa.
En esta sección, se muestra cómo cargar la API de Maps JavaScript en tu página web y escribir tu propio código JavaScript que use la API para agregar un mapa a la página web.
- Agrega este código de secuencia de comandos donde veas
<!-- TODO: Step 1B, Add a map -->
después de la etiquetamap
div y antes de la etiqueta de cierre</body>
.
step1/index.html
<!-- TODO: Step 1B, Add a map -->
<script>
/* Note: This example requires that you consent to location sharing when
* prompted by your browser. If you see the error "Geolocation permission
* denied.", it means you probably did not give permission for the browser * to locate you. */
/* TODO: Step 2, Geolocate your user
* Replace the code from here to the END TODO comment with new code from
* codelab instructions. */
let pos;
let map;
function initMap() {
// Set the default location and initialize all variables
pos = {lat: -33.857, lng: 151.213};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
}
/* END TODO: Step 2, Geolocate your user */
</script>
<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
3. Pega tu clave de API
- En la línea posterior a
<!-- TODO: Step 1C, Get an API key -->
, copia y reemplaza el valor del parámetro key en la URL de la fuente del script por la clave de API que creaste durante los requisitos previos.
step1/index.html
<!-- TODO: Step 1C, Get an API key -->
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
- Guarda el archivo HTML en el que has estado trabajando.
Pruébalo
Vuelve a cargar la vista del navegador del archivo que estuviste editando. Ahora deberías ver un mapa en el lugar donde antes estaba el rectángulo gris. Si ves un mensaje de error, asegúrate de haber reemplazado "YOUR_API_KEY
" en la etiqueta <script>
final por tu propia clave de API. Consulta la sección anterior para obtener una clave de API si aún no tienes una.
Código de muestra completo
El código completo de este proyecto hasta este punto está disponible en GitHub.
3. Cómo geolocalizar a tu usuario
A continuación, querrás mostrar la ubicación geográfica del usuario o el dispositivo en un mapa de Google Maps con la función de ubicación geográfica HTML5 de tu navegador y la API de Maps JavaScript.
Este es un ejemplo de un mapa que muestra tu ubicación geográfica si estuvieras navegando desde Mountain View, California:
¿Qué es la ubicación geográfica?
La ubicación geográfica permite identificar dónde se encuentran un usuario o un dispositivo a través de diferentes mecanismos de recopilación de datos. Generalmente, la mayoría de los servicios de ubicación geográfica usan direcciones de enrutamiento de red o dispositivos GPS internos para determinar la ubicación. Esta app usa la propiedad navigator.geolocation
estándar de ubicación geográfica de W3C del navegador web para determinar la ubicación del usuario.
Pruébalo
Reemplaza el código entre los comentarios TODO: Step 2, Geolocate your user
y END TODO: Step 2, Geolocate your user
por el siguiente:
step2/index.html
/* TODO: Step 2, Geolocate your user
* Replace the code from here to the END TODO comment with this code
* from codelab instructions. */
let pos;
let map;
let bounds;
let infoWindow;
let currentInfoWindow;
let service;
let infoPane;
function initMap() {
// Initialize variables
bounds = new google.maps.LatLngBounds();
infoWindow = new google.maps.InfoWindow;
currentInfoWindow = infoWindow;
/* TODO: Step 4A3: Add a generic sidebar */
// Try HTML5 geolocation
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(position => {
pos = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
bounds.extend(pos);
infoWindow.setPosition(pos);
infoWindow.setContent('Location found.');
infoWindow.open(map);
map.setCenter(pos);
/* TODO: Step 3B2, Call the Places Nearby Search */
}, () => {
// Browser supports geolocation, but user has denied permission
handleLocationError(true, infoWindow);
});
} else {
// Browser doesn't support geolocation
handleLocationError(false, infoWindow);
}
}
// Handle a geolocation error
function handleLocationError(browserHasGeolocation, infoWindow) {
// Set default location to Sydney, Australia
pos = {lat: -33.856, lng: 151.215};
map = new google.maps.Map(document.getElementById('map'), {
center: pos,
zoom: 15
});
// Display an InfoWindow at the map center
infoWindow.setPosition(pos);
infoWindow.setContent(browserHasGeolocation ?
'Geolocation permissions denied. Using default location.' :
'Error: Your browser doesn\'t support geolocation.');
infoWindow.open(map);
currentInfoWindow = infoWindow;
/* TODO: Step 3B3, Call the Places Nearby Search */
}
/* END TODO: Step 2, Geolocate your user */
/* TODO: Step 3B1, Call the Places Nearby Search */
Pruébalo
- Guarda el archivo.
- Vuelve a cargar la página.
Ahora, el navegador debería pedirte permiso para compartir tu ubicación con la app.
- Haz clic en Bloquear una vez para ver si controla el error correctamente y permanece centrado en Sídney.
- Vuelve a cargar la página y haz clic en Permitir para ver si la ubicación geográfica funciona y mueve el mapa a tu ubicación actual.
Código de muestra completo
El código completo de este proyecto hasta este punto está disponible en GitHub.
4. Busca lugares cercanos
Una búsqueda de sitios cercanos te permite buscar sitios dentro de un área especificada a través de palabras claves o tipos. En una búsqueda de sitios cercanos siempre debe incluirse una ubicación, que puede especificarse con dos métodos:
- Un objeto
LatLngBounds
que define un área de búsqueda rectangular - Un área circular definida como la combinación de la propiedad
location
(que especifica el centro del círculo como un objetoLatLng
) y un radio, medido en metros
Inicia una Búsqueda cercana con una llamada al método PlacesService
nearbySearch()
, que devolverá un array de objetos PlaceResult
.
A. Carga la biblioteca de Places
Primero, para acceder a los servicios de la biblioteca de Places, actualiza la URL de origen de tu secuencia de comandos para introducir el parámetro libraries
y agrega places
como valor.
step3/index.html
<!-- TODO: Step 3A, Load the Places Library -->
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places&callback=initMap">
B. Llama a la solicitud de Places Nearby Search y controla la respuesta
A continuación, crea una solicitud de PlaceSearch. Los campos obligatorios mínimos son los siguientes:
Los campos obligatorios mínimos son los siguientes:
bounds
: Debe ser un objetogoogle.maps.LatLngBounds
que defina el área de búsqueda rectangular, o unlocation
y unradius
. El primero toma un objetogoogle.maps.LatLng
y el segundo toma un número entero que representa el radio del círculo en metros. El radio máximo permitido es de 50,000 metros. Ten en cuenta que, cuandorankBy
se configura comoDISTANCE
, debes especificar una ubicación, pero no puedes especificar un radio ni límites.- Un
keyword
para el que se buscarán coincidencias con todos los campos disponibles, incluidos, sin limitaciones, el nombre, el tipo y la dirección, así como las opiniones de los clientes y otro contenido de terceros, o untype
, que restringe los resultados a los lugares que coinciden con el tipo especificado. Solo se puede especificar un tipo (si se proporciona más de un tipo, se ignoran todos los siguientes a la primera entrada). Consulta la lista de tipos admitidos.
En este codelab, usarás la posición actual del usuario como ubicación para la búsqueda y clasificarás los resultados por distancia.
- Agrega lo siguiente en el comentario
TODO: Step 3B1
para escribir dos funciones que llamen a la búsqueda y controlen la respuesta.
La palabra clave sushi
se usa como término de búsqueda, pero puedes cambiarla. El código para definir la función createMarkers
se proporciona en la siguiente sección.
step3/index.html
/* TODO: Step 3B1, Call the Places Nearby Search */
// Perform a Places Nearby Search Request
function getNearbyPlaces(position) {
let request = {
location: position,
rankBy: google.maps.places.RankBy.DISTANCE,
keyword: 'sushi'
};
service = new google.maps.places.PlacesService(map);
service.nearbySearch(request, nearbyCallback);
}
// Handle the results (up to 20) of the Nearby Search
function nearbyCallback(results, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
createMarkers(results);
}
}
/* TODO: Step 3C, Generate markers for search results */
- Agrega esta línea al final de la función
initMap
en el comentarioTODO: Step 3B2
.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
- Agrega esta línea al final de la función
handleLocationError
en el comentarioTODO: Step 3B3
.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);
C. Genera marcadores para los resultados de la búsqueda
Los marcadores identifican una ubicación en un mapa. De manera predeterminada, los marcadores llevan una imagen estándar. Para obtener información sobre cómo personalizar las imágenes de los marcadores, consulta Marcadores.
El constructor google.maps.Marker
toma un solo literal del objeto Marker options
, que especifica las propiedades iniciales del marcador.
Los campos siguientes tienen particular importancia y normalmente se configuran al construir un marcador:
position
(obligatorio) especifica un objetoLatLng
que identifica la ubicación inicial del marcador.map
(opcional) especifica el mapa en el que se debe colocar el marcador. Si no especificas el mapa al construir el marcador, este se creará, pero no se adjuntará al mapa (ni se mostrará en él). Puedes agregar el marcador más adelante llamando al métodosetMap()
del marcador.- Agrega el siguiente código después del comentario
TODO: Step 3C
para establecer la posición, el mapa y el título de un marcador por lugar que se muestre en la respuesta. También usas el métodoextend
de la variablebounds
para asegurarte de que el centro y todos los marcadores sean visibles en el mapa.
step3/index.html
/* TODO: Step 3C, Generate markers for search results */
// Set markers at the location of each place result
function createMarkers(places) {
places.forEach(place => {
let marker = new google.maps.Marker({
position: place.geometry.location,
map: map,
title: place.name
});
/* TODO: Step 4B: Add click listeners to the markers */
// Adjust the map bounds to include the location of this marker
bounds.extend(place.geometry.location);
});
/* Once all the markers have been placed, adjust the bounds of the map to
* show all the markers within the visible area. */
map.fitBounds(bounds);
}
/* TODO: Step 4C: Show place details in an info window */
Pruébalo
- Guarda y vuelve a cargar la página, y haz clic en Permitir para otorgar permisos de ubicación geográfica.
Deberías ver hasta 20 marcadores rojos alrededor de la ubicación central del mapa.
- Vuelve a cargar la página y, esta vez, bloquea los permisos de ubicación geográfica.
¿Aún obtienes resultados en el centro predeterminado de tu mapa (en el ejemplo, el valor predeterminado está en Sídney, Australia)?
Código de muestra completo
El código completo de este proyecto hasta este punto está disponible en GitHub.
5. Mostrar detalles del lugar a pedido
Una vez que tengas el ID de lugar de un lugar (que se entrega como uno de los campos en los resultados de tu Búsqueda cercana), puedes solicitar detalles adicionales sobre el lugar, como su dirección completa, número de teléfono y calificaciones y opiniones de los usuarios. En este codelab, crearás una barra lateral para mostrar Place Details enriquecidos y harás que los marcadores sean interactivos para que el usuario pueda seleccionar lugares y ver sus detalles.
A. Crea una barra lateral genérica
Necesitas un lugar para mostrar los detalles del lugar, por lo que aquí tienes un código simple para una barra lateral que puedes usar para deslizar y mostrar los detalles del lugar cuando el usuario hace clic en un marcador.
- Agrega el siguiente código a la etiqueta
style
después del comentarioTODO: Step 4A1
:
step4/index.html
/* TODO: Step 4A1: Make a generic sidebar */
/* Styling for an info pane that slides out from the left.
* Hidden by default. */
#panel {
height: 100%;
width: null;
background-color: white;
position: fixed;
z-index: 1;
overflow-x: hidden;
transition: all .2s ease-out;
}
.open {
width: 250px;
}
/* Styling for place details */
.hero {
width: 100%;
height: auto;
max-height: 166px;
display: block;
}
.place,
p {
font-family: 'open sans', arial, sans-serif;
padding-left: 18px;
padding-right: 18px;
}
.details {
color: darkslategrey;
}
a {
text-decoration: none;
color: cadetblue;
}
- En la sección
body
, justo antes del divmap
, agrega un div para el panel de detalles.
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- The slide-out panel for showing place details -->
<div id="panel"></div>
- En la función
initMap()
, después del comentarioTODO: Step 4A3
, inicializa la variableinfoPane
de la siguiente manera:
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');
B. Agrega objetos de escucha de clics a los marcadores
- En la función
createMarkers
, agrega un objeto de escucha de clics a cada marcador a medida que los creas.
El objeto de escucha de clics recupera detalles sobre el lugar asociado a ese marcador y llama a la función para mostrar los detalles.
- Pega el siguiente código dentro de la función
createMarkers
en el comentario de códigoTODO: Step 4B
.
El método showDetails
se implementa en la siguiente sección.
step4/index.html
/* TODO: Step 4B: Add click listeners to the markers */
// Add click listener to each marker
google.maps.event.addListener(marker, 'click', () => {
let request = {
placeId: place.place_id,
fields: ['name', 'formatted_address', 'geometry', 'rating',
'website', 'photos']
};
/* Only fetch the details of a place when the user clicks on a marker.
* If we fetch the details for all place results as soon as we get
* the search response, we will hit API rate limits. */
service.getDetails(request, (placeResult, status) => {
showDetails(placeResult, marker, status)
});
});
En la solicitud addListener
, la propiedad placeId
especifica un solo lugar para la solicitud de detalles, y la propiedad fields
es un array de nombres de campos para la información que deseas que se muestre sobre el lugar. Para obtener una lista completa de los campos que puedes solicitar, consulta la interfaz PlaceResult.
C. Cómo mostrar detalles del lugar en una ventana de información
Una ventana de información muestra contenido (por lo general, texto o imágenes) en un diálogo sobre una ubicación determinada en un mapa. La ventana de información tiene un área de contenido y un tallo cónico. La punta del tallo se conecta a una ubicación especificada del mapa. Por lo general, las ventanas de información se adjuntan a los marcadores, pero también puedes adjuntar una ventana de información a una latitud o longitud específica.
- Agrega el siguiente código en el comentario
TODO: Step 4C
para crear unInfoWindow
que muestre el nombre y la calificación de la empresa, y adjunte esa ventana al marcador.
Definirás showPanel
en la siguiente sección para mostrar detalles en una barra lateral.
step4/index.html
/* TODO: Step 4C: Show place details in an info window */
// Builds an InfoWindow to display details above the marker
function showDetails(placeResult, marker, status) {
if (status == google.maps.places.PlacesServiceStatus.OK) {
let placeInfowindow = new google.maps.InfoWindow();
placeInfowindow.setContent('<div><strong>' + placeResult.name +
'</strong><br>' + 'Rating: ' + placeResult.rating + '</div>');
placeInfowindow.open(marker.map, marker);
currentInfoWindow.close();
currentInfoWindow = placeInfowindow;
showPanel(placeResult);
} else {
console.log('showDetails failed: ' + status);
}
}
/* TODO: Step 4D: Load place details in a sidebar */
D. Cómo cargar detalles de un lugar en una barra lateral
Usa los mismos detalles que se devolvieron en el objeto PlaceResult
para completar otro div. En este ejemplo, usa infoPane
, que es un nombre de variable arbitrario para el div con el ID "panel
". Cada vez que el usuario hace clic en un marcador nuevo, este código cierra la barra lateral si ya estaba abierta, borra los detalles anteriores, agrega los detalles nuevos y abre la barra lateral.
- Agrega el siguiente código después del comentario
TODO: Step 4D
.
step4/index.html
/* TODO: Step 4D: Load place details in a sidebar */
// Displays place details in a sidebar
function showPanel(placeResult) {
// If infoPane is already open, close it
if (infoPane.classList.contains("open")) {
infoPane.classList.remove("open");
}
// Clear the previous details
while (infoPane.lastChild) {
infoPane.removeChild(infoPane.lastChild);
}
/* TODO: Step 4E: Display a Place Photo with the Place Details */
// Add place details with text formatting
let name = document.createElement('h1');
name.classList.add('place');
name.textContent = placeResult.name;
infoPane.appendChild(name);
if (placeResult.rating != null) {
let rating = document.createElement('p');
rating.classList.add('details');
rating.textContent = `Rating: ${placeResult.rating} \u272e`;
infoPane.appendChild(rating);
}
let address = document.createElement('p');
address.classList.add('details');
address.textContent = placeResult.formatted_address;
infoPane.appendChild(address);
if (placeResult.website) {
let websitePara = document.createElement('p');
let websiteLink = document.createElement('a');
let websiteUrl = document.createTextNode(placeResult.website);
websiteLink.appendChild(websiteUrl);
websiteLink.title = placeResult.website;
websiteLink.href = placeResult.website;
websitePara.appendChild(websiteLink);
infoPane.appendChild(websitePara);
}
// Open the infoPane
infoPane.classList.add("open");
}
E. Cómo mostrar una foto del lugar con los detalles del lugar
El resultado de getDetails
devuelve un array de hasta 10 fotos asociadas con el placeId
. Aquí, muestras la primera foto sobre el nombre del lugar en la barra lateral.
- Coloca este código antes de la creación del elemento
name
si quieres que la foto aparezca en la parte superior de la barra lateral.
step4/index.html
/* TODO: Step 4E: Display a Place Photo with the Place Details */
// Add the primary photo, if there is one
if (placeResult.photos != null) {
let firstPhoto = placeResult.photos[0];
let photo = document.createElement('img');
photo.classList.add('hero');
photo.src = firstPhoto.getUrl();
infoPane.appendChild(photo);
}
Pruébalo
- Guarda y vuelve a cargar la página en tu navegador, y permite los permisos de ubicación geográfica.
- Haz clic en un marcador para ver la ventana de información que aparece desde el marcador con algunos detalles y la barra lateral que se desliza desde la izquierda para mostrar más detalles.
- Prueba si la búsqueda también funciona si vuelves a cargar la página y rechazas los permisos de ubicación geográfica. Edita tu palabra clave de búsqueda para realizar una consulta diferente y explora el resultado que se muestra para esa búsqueda.
Código de muestra completo
El código completo de este proyecto hasta este punto está disponible en GitHub.
6. Felicitaciones
¡Felicitaciones! Usaste muchas funciones de la API de Maps JavaScript, incluida la biblioteca Places
.
Temas abordados
- Cómo crear un mapa con la clase google.maps.Map
- Usar el navegador del usuario para la ubicación geográfica y mostrar los resultados en un mapa
- Agregar marcadores a tu mapa y responder a los eventos de clic del usuario en ellos
- Agrega ventanas de información para mostrar más detalles cuando un usuario haga clic en un marcador.
- Cómo cargar la biblioteca de Places y realizar una búsqueda cercana
- Recuperar y mostrar detalles del lugar y fotos del lugar
Más información
Para hacer aún más con los mapas, explora la documentación de la API de Maps JavaScript y la documentación de la biblioteca de Places, que contienen guías, instructivos, la referencia de la API, más muestras de código y canales de asistencia. Algunas funciones populares son Importar datos a Maps, Comenzar a diseñar tu mapa y agregar el Servicio de Street View.
¿Qué tipo de codelab te gustaría que creáramos a continuación?
¿El codelab que quieres no figura arriba? Crea un nuevo problema aquí para solicitarlo.