1. Antes de começar
Saiba como usar as APIs Maps e Places da Plataforma Google Maps para criar uma pesquisa de empresas locais que geolocaliza o usuário e mostra lugares interessantes nas proximidades. O app integra geolocalização, Place Details, Place Photos e muito mais.
Pré-requisitos
- Conhecimento básico de HTML, CSS e JavaScript
- Um projeto com uma conta de faturamento. Siga as instruções na próxima etapa se você não tiver isso.
- Para a etapa de ativação abaixo, é necessário ativar a API Maps JavaScript e a API Places.
- Uma chave de API para o projeto acima.
Comece a usar a Plataforma Google Maps
Se você nunca usou a Plataforma Google Maps, siga o guia Primeiros passos com a Plataforma Google Maps ou assista à playlist Primeiros passos na Plataforma Google Maps para concluir as seguintes etapas:
- Criar uma conta de faturamento
- Criar um projeto
- Ative as APIs e os SDKs da Plataforma Google Maps (listados na seção anterior).
- Gerar uma chave de API
O que você aprenderá
- Criar uma página da Web que mostre um mapa do Google
- Centralizar o mapa na localização do usuário
- Encontrar lugares por perto e mostrar os resultados como marcadores clicáveis
- Buscar e mostrar mais detalhes sobre cada lugar
O que é necessário
- Um navegador da Web, como Google Chrome (recomendado), Firefox, Safari ou Internet Explorer
- Seu editor de texto ou de código favorito
Fazer o download do exemplo de código
- Abra a interface de linha de comando (Terminal no macOS ou Prompt de comando no Windows) e baixe o exemplo de código com este comando:
git clone https://github.com/googlecodelabs/google-maps-nearby-search-js/
Se isso não funcionar, clique no botão abaixo para fazer o download de todo o código deste codelab e descompacte o arquivo:
- Mude para o diretório que você acabou de clonar ou baixar.
cd google-maps-nearby-search-js
As pastas stepN
contêm o estado final desejado de cada etapa deste codelab. Elas servem como referência. Faça todo o trabalho de codificação no diretório chamado work
.
2. Criar um mapa com um centro padrão
Estas são as três etapas para criar um mapa do Google na sua página da Web:
- Criar uma página HTML
- Adicionar um mapa
- Cole sua chave de API
1. Criar uma página HTML
Confira abaixo o mapa criado nesta etapa. O mapa está centralizado na Sydney Opera House, em Sydney, Austrália. Se o usuário negar a permissão para acessar a localização, o mapa vai usar esse local como padrão e ainda vai fornecer resultados de pesquisa interessantes.
- Mude os diretórios para a pasta
work/
. Durante o restante do codelab, faça as edições na versão da pastawork/
.
cd work
- No diretório
work/
, use seu editor de texto para criar um arquivo em branco chamadoindex.html
. - Copie o seguinte código em
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>
- Abra o arquivo
index.html
no navegador da Web.
open index.html
2. Adicionar um mapa
Nesta seção, mostramos como carregar a API Maps JavaScript na sua página da Web e escrever seu próprio JavaScript que usa a API para adicionar um mapa à página da Web.
- Adicione este código de script onde você vê
<!-- TODO: Step 1B, Add a map -->
após a divmap
e antes da tag de fechamento</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. Cole sua chave de API
- Na linha depois de
<!-- TODO: Step 1C, Get an API key -->
, copie e substitua o valor do parâmetro "key" no URL de origem do script pela chave de API criada durante os pré-requisitos.
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>
- Salve o arquivo HTML em que você estava trabalhando.
Realizar o teste
Atualize a visualização do navegador do arquivo que você estava editando. Agora vai aparecer um mapa no lugar do retângulo cinza. Se uma mensagem de erro aparecer, verifique se você substituiu "YOUR_API_KEY
" na tag <script>
final pela sua própria chave de API. Consulte acima como conseguir uma chave de API se você ainda não tiver uma.
Exemplo de código completo
O código completo deste projeto até este ponto está disponível no GitHub.
3. Geolocalizar o usuário
Agora, você quer mostrar a localização geográfica do usuário ou dispositivo em um mapa do Google usando o recurso de geolocalização HTML5 do navegador e a API Maps JavaScript.
Este é um exemplo de mapa que mostra sua localização geográfica se você estivesse navegando em Mountain View, Califórnia:
O que é geolocalização?
Geolocalização se refere à identificação do local geográfico de um usuário ou dispositivo de computação por vários mecanismos de coleta de dados. Normalmente, a maior parte dos serviços de geolocalização usam endereços de roteamento de rede ou dispositivos internos de GPS para determinar esse local. Esse app usa a propriedade navigator.geolocation
do padrão de geolocalização W3C do navegador da Web para determinar a localização do usuário.
Teste por conta própria
Substitua o código entre os comentários TODO: Step 2, Geolocate your user
e END TODO: Step 2, Geolocate your user
pelo seguinte:
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 */
Realizar o teste
- Salve o arquivo.
- Atualize a página.
O navegador vai pedir permissão para compartilhar sua localização com o app.
- Clique em Bloquear uma vez para ver se ele processa o erro normalmente e permanece centralizado em Sydney.
- Atualize novamente e clique em Permitir para ver se a geolocalização funciona e move o mapa para seu local atual.
Exemplo de código completo
O código completo deste projeto até este ponto está disponível no GitHub.
4. Pesquise lugares próximos
Uma Nearby Search permite pesquisar locais em uma área especificada por palavra-chave ou tipo. Uma Nearby Search deve sempre incluir uma localização, que pode ser especificada de duas formas:
- Um objeto
LatLngBounds
que define uma área de pesquisa retangular - Uma área circular definida como a combinação da propriedade
location
, especificando o centro do círculo como um objetoLatLng
, e um raio, medido em metros
Inicie uma Nearby Search com uma chamada para o método PlacesService
nearbySearch()
, que retorna uma matriz de objetos PlaceResult
.
A. Carregar a biblioteca Places
Primeiro, para acessar os serviços da biblioteca Places, atualize o URL de origem do script para incluir o parâmetro libraries
e adicione places
como um 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. Chame a solicitação da pesquisa por proximidade do Places e processe a resposta
Em seguida, crie uma solicitação PlaceSearch. Os campos obrigatórios mínimos são:
Os campos obrigatórios mínimos são:
bounds
, que precisa ser um objetogoogle.maps.LatLngBounds
definindo a área de pesquisa retangular, ou umlocation
e umradius
. O primeiro usa um objetogoogle.maps.LatLng
, e o segundo usa um número inteiro simples que representa o raio do círculo em metros. O raio máximo permitido é de 50.000 metros. QuandorankBy
é definido comoDISTANCE
, é necessário especificar um local, mas não é possível especificar um raio ou limites.- Um
keyword
que deve ser comparado com todos os campos disponíveis, incluindo, entre outros, nome, tipo e endereço, além de avaliações de clientes e outros materiais de terceiros, ou umtype
, que restringe os resultados aos lugares correspondentes ao tipo especificado. Só um tipo pode ser especificado (se mais de um tipo for fornecido, todos os outros após a primeira entrada vão ser ignorados). Consulte a lista de tipos compatíveis.
Neste codelab, você vai usar a posição atual do usuário como local para a pesquisa e classificar os resultados por distância.
- Adicione o seguinte ao comentário
TODO: Step 3B1
para escrever duas funções que chamam a pesquisa e processam a resposta.
A palavra-chave sushi
é usada como o termo de pesquisa, mas você pode mudar isso. O código para definir a função createMarkers
é fornecido na próxima seção.
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 */
- Adicione esta linha ao fim da função
initMap
no comentárioTODO: Step 3B2
.
/* TODO: Step 3B2, Call the Places Nearby Search */
// Call Places Nearby Search on user's location
getNearbyPlaces(pos);
- Adicione esta linha ao fim da função
handleLocationError
no comentárioTODO: Step 3B3
.
/* TODO: Step 3B3, Call the Places Nearby Search */
// Call Places Nearby Search on the default location
getNearbyPlaces(pos);
C. Gerar marcadores para resultados da pesquisa
Um marcador identifica uma localização no mapa. Por padrão, um marcador usa uma imagem padrão. Para informações sobre como personalizar imagens de marcadores, consulte Marcadores.
O construtor google.maps.Marker
usa um único literal de objeto Marker options
que especifica as propriedades iniciais do marcador.
Os campos a seguir são particularmente importantes e são normalmente definidos na construção de um marcador:
position
(obrigatório) especifica umLatLng
que identifica o local inicial do marcador.map
(opcional) especifica o mapa em que o marcador será colocado. Se você não especificar o mapa na construção do marcador, ele será criado, mas não anexado (ou mostrado) no mapa. É possível adicionar o marcador depois chamando o métodosetMap()
dele.- Adicione o código a seguir após o comentário
TODO: Step 3C
para definir a posição, o mapa e o título de um marcador por lugar retornado na resposta. Você também usa o métodoextend
da variávelbounds
para garantir que o centro e todos os marcadores estejam visíveis no 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 */
Realizar o teste
- Salve e recarregue a página. Clique em Permitir para conceder permissões de geolocalização.
Você vai ver até 20 marcadores vermelhos ao redor do local central do mapa.
- Atualize a página novamente e bloqueie as permissões de geolocalização desta vez.
Você ainda recebe resultados no centro padrão do mapa (no exemplo, o padrão é em Sydney, Austrália)?
Exemplo de código completo
O código completo deste projeto até este ponto está disponível no GitHub.
5. Mostrar detalhes do lugar sob demanda
Depois de ter o ID de um lugar (fornecido como um dos campos nos resultados da pesquisa por proximidade), você pode pedir mais detalhes sobre ele, como endereço completo, número de telefone, classificações e avaliações de usuários. Neste codelab, você vai criar uma barra lateral para mostrar detalhes avançados do lugar e tornar os marcadores interativos para que o usuário possa selecionar lugares e ver os detalhes.
A. Criar uma barra lateral genérica
Você precisa de um lugar para mostrar os detalhes do lugar. Por isso, aqui está um código simples para uma barra lateral que pode ser usada para deslizar e mostrar os detalhes do lugar quando o usuário clica em um marcador.
- Adicione o seguinte código à tag
style
após o comentárioTODO: 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;
}
- Na seção
body
, logo antes da divmap
, adicione uma div para o painel de detalhes.
<!-- TODO: Step 4A2: Add a generic sidebar -->
<!-- The slide-out panel for showing place details -->
<div id="panel"></div>
- Na função
initMap()
, depois do comentárioTODO: Step 4A3
, inicialize a variávelinfoPane
assim:
/* TODO: Step 4A3: Add a generic sidebar */
infoPane = document.getElementById('panel');
B. Adicionar listeners de clique aos marcadores
- Na função
createMarkers
, adicione um listener de clique a cada marcador à medida que eles são criados.
O listener de clique busca detalhes sobre o lugar associado ao marcador e chama a função para mostrar os detalhes.
- Cole o seguinte código dentro da função
createMarkers
no comentário do códigoTODO: Step 4B
.
O método showDetails
é implementado na próxima seção.
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)
});
});
Na solicitação addListener
, a propriedade placeId
especifica um único lugar para a solicitação de detalhes, e a propriedade fields
é uma matriz de nomes de campos para as informações que você quer receber sobre o lugar. Para uma lista completa de campos que podem ser solicitados, consulte a interface PlaceResult.
C. Mostrar detalhes do lugar em uma janela de informações
Uma janela de informações mostra conteúdo (geralmente texto ou imagens) em uma caixa de diálogo acima de um determinado local em um mapa. A janela de informações tem uma área de conteúdo e uma ponta afunilada. A extremidade da ponta é conectada a uma localização especificada no mapa. Normalmente, as janelas de informações são anexadas a marcadores, mas também é possível fazer isso com uma latitude/longitude específica.
- Adicione o código a seguir no comentário
TODO: Step 4C
para criar umInfoWindow
que mostre o nome e a classificação da empresa e anexe essa janela ao marcador.
Você define showPanel
na próxima seção para mostrar detalhes em uma 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. Carregar detalhes do lugar em uma barra lateral
Use os mesmos detalhes retornados no objeto PlaceResult
para preencher outra div. Neste exemplo, use infoPane
, que é um nome de variável arbitrário para a div com o ID "panel
". Cada vez que o usuário clica em um novo marcador, esse código fecha a barra lateral se ela já estiver aberta, apaga os detalhes antigos, adiciona os novos detalhes e abre a barra lateral.
- Adicione o seguinte código após o comentário
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. Mostrar uma foto do lugar com os detalhes dele
O resultado getDetails
retorna uma matriz de até 10 fotos associadas ao placeId
. Aqui, você mostra a primeira foto acima do nome do lugar na barra lateral.
- Coloque esse código antes da criação do elemento
name
se quiser que a foto apareça na parte de cima da 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);
}
Realizar o teste
- Salve e atualize a página no navegador e permita as permissões de geolocalização.
- Clique em um marcador para ver a janela de informações aparecer com alguns detalhes e a barra lateral deslizar da esquerda para mostrar mais detalhes.
- Teste se a pesquisa também funciona se você recarregar e negar as permissões de geolocalização. Edite a palavra-chave da pesquisa para uma consulta diferente e confira o resultado retornado.
Exemplo de código completo
O código completo deste projeto até este ponto está disponível no GitHub.
6. Parabéns
Parabéns! Você usou muitos recursos da API Maps JavaScript, incluindo a biblioteca Places
.
O que aprendemos
- Criar um mapa com a classe google.maps.Map
- Usar o navegador do usuário para geolocalização e mostrar os resultados em um mapa
- Adicionar marcadores ao mapa e responder a eventos de clique do usuário neles
- Adicionar janelas de informações para mostrar mais detalhes quando um usuário clica em um marcador
- Carregar a biblioteca Places e realizar uma pesquisa por proximidade
- Buscar e mostrar detalhes do lugar e fotos do lugar
Saiba mais
Para fazer ainda mais com mapas, confira a documentação da API Maps JavaScript e a documentação da biblioteca Places. Ambas contêm guias, tutoriais, a referência da API, mais exemplos de código e canais de suporte. Alguns recursos conhecidos são Importar dados para o Maps, Começar a estilizar seu mapa e adicionar o Serviço Street View.
Que tipo de codelab você gostaria que criássemos em seguida?
O codelab que você quer ver não está listado acima? Solicite-o aqui.