google-maps-api-parte-5-autocompletar-enderecos-e-locais-com-google-places

Hoje usaremos a library Google Places para prover uma melhor experiência de usuário com um auto-completar de endereços lindão e bem fácil de implementar.


Todas as partes da série Google Maps API:


Demo: Resultado do artigo de hoje

Ao final do artigo de hoje, devemos ter construído em nossa série Google Maps API até agora algo mais ou menos assim:
(clique em inciar, depois digite e avalie alguns endereços ou locais (ex: parque barigui, jardim botanico, etc))

See the Pen Google Maps: Autocompletar google Places + custom markers by Romulo_Ctba (@romuloctba) on CodePen.

Continuando de onde paramos

Você pode pegar o código, como ficou ao final da Parte III clicando aqui, ou continuar de onde parou.

Se pegar acima, não esqueça de rodar o npm install na pasta do projeto, com o terminal.
Também deve ter o Gulp e Nodejs instalados.
Se tiver dúvidas, veja este post.

Para começar a trabalhar, abra a pasta do projeto com o terminal e rode:

1
gulp

Isso deve abrir o browser, com liveReload. Caso não abra automaticamente, acesse http://localhost:1337


API Google Places - O que é e como usar.

API Google Places permite consultas à locais, como endereços, empresas, pontos turísticos - e muito mais - de forma fácil e simples.

Com a API do google places não é necessário informar coordenadas (Latitude e Longitude) para localizar pontos no mapa. Ela, por sí só, faz a conversão geocode , e retorna um Local (que contém diversas informações), nao apenas coordenadas.

Além disso, a API do Google Places tem integração com eventos e Ações no Local.

Ela é bem maneira, e nos permite expandir o nível de interação usuário x mapa de forma incrível.

Google Places oferece uma api própria, mas que pode ser incluída como library na API do Google Maps V3.

A API do Google Places oferece autocomplete facílimo de implementar, que agrega muito na Experiência do Usuário.

Incluindo Google Places em sua aplicação

Para incluir, adicionaremos o parâmetro &libraries=places na url do Javascript do google maps.
Edite o arquivo index.html da pasta src, alterando a url da tag <script> conforme segue:

index.html (altere a url da tag script)
1
2
3
4
(...)
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=places"></script>
(...)

Agora, você pode fazer uso da biblioteca places.

Iremos utilizar o autocompletar para melhorar nossa interface (que por sinal, tá bem descuidada né? hehe tento manter simples pra não confundir ninguém)

Google Places - Autocompletar endereços e locais

Vamos instanciar o google.maps.places.Autocomplete() na variável autoComplete.

A google.maps.places.Autocomplete() recebe 2 parâmetros: 1. o elemento onde será criado, e 2. um objeto com opcoes.

As seguintes opções estão disponíveis:

  • componentRestrictions
    A única opção disponível para esta configuração é ‘country’, que recebe código do país, com 2 letras (ex: br, us, au, etc).
    Normalmente não usamos pois é automaticamente definido.

  • bounds
    Região máxima em que o local deve ser pesquisado. Recebe como valor um LatLngBounds(sw?:LatLng, ne?:LatLng), conforme vimos no último artigo

  • types
    Esta é a option mais utilizada: define os tipos de locais que devem ser pesquisados.
    Veja uma lista de tipos de local suportados aqui.

Iremos instanciar um google.maps.Autocomplete() em nosso input de endereço. Isso será feito dentro da function initialize().

Altere a function initialize, do arquivo js/maps.js , incluindo as linhas à seguir ao final dela (após as instancias map e geocode:

maps.js (insira ao final da funcao initialize())
1
2
3
4
5
6
7
(...)
var autoCompleteInput = document.getElementById('endereco');
var autoCompleteOpcoes = {
types: ['geocode']
}
autocomplete = new google.maps.places.Autocomplete(autoCompleteInput,autoCompleteOpcoes);
(...)

Note que definimos a variável autoCompleteInput com o elemento do id #endereco, que é nosso input já existente no HTML (hoje usado para geocode).

Dica: Ao utilizar o places.Autocomplete(), você pode querer aumentar a largura do seu input (via css), para melhorar a visibilidade.

A variável autoCompleteOpcoes com o objeto, definindo types como geocode.

Salvando, o liveReload deve atualizar sua página. Comece a digitar um endereço, e veja o autocomplete em ação.


Eventos e Métodos do Google Places Autocompletar

Existem 4 métodos que podem ser usados em uma instância do google.maps.places.Autocomplete():

  • getBounds()
  • getPlace()
  • setBound(objetoBoundsLatLng)
  • setTypes(arrayComTiposDeLocais)

Os 2 primeiros retornam os limites (bounds) e local encontrado, respectivamente.
O terceorp, define o limite, e pede um objeto Bounds, conforme vimos no artigo anterior.
O último método acima define o(s) tipo(s) de locais para pesquisar. Seu parãmetro é um array.

O Evento que o places.Autocomplete() dispara é um só: place_changed. Ele é disparado toda vez que um resultado é escolhido pelo usuário (com enter, ou click). Pode ser utilizado assim:
google.maps.event.addListener(autocomplete, 'place_changed', funcaoAqui), mas não usaremos isso agora.

Usar o local escolhido no autocompletar

Para isso, usaremos o método getPlace(). Estamos colocando-o dentro de uma função, e usando para criar um marcador com a função criaMarcador (basicamente a mesma coisa que a função converte(), que já tinhamos. Ela, aliás, vai sair fora).

Ao final do arquivo src/maps.js, insira o seguinte código:

maps.js (insira ao final do arquivo)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
(...)

function novoLocal() {
var local = autocomplete.getPlace();
var seletor = document.getElementById("avaliacao");
var avaliacao = seletor.options[seletor.selectedIndex].value;
var imagemMarcador = imgArray[avaliacao];
var marcador = {
latitude: local.geometry.location.k
, longitude: local.geometry.location.D
, titulo: local.name
, imagem: imagemMarcador
}
criaMarcador(marcador, map);
map.setCenter(local.geometry.location)
}

```

E agora sete a função novoLocal() como ação do onClick do botão que fica logo após o select, no **index.html**.

Mude o texto também, que estava 'converter', para 'avaliar':

```html index.html (altere o atributo onclick do botão, conforme abaixo)
(...)
</select>
<button onclick="novoLocal()">Avaliar</button>
(...)

Agora você pode criar marcadores avaliados com base nos places do autocompletar!

Experimente digitar alguns pontos turísticos da sua cidade.
Se quiser brincar com Curitiba, recomendo avaliar: parque Barigui, Jardim Botanico, Passeio Publico, Aeropoto Afonso Pena.

Veja como digitar algumas letras logo tráz resultado!

Lendo e listando os marcadores criados

Para fechar por hoje, iremos ler o array marcadores, criando um botão para cada marcador, de modo que possamos acessá-los com 1 click:

Coloque ao final do maps.js

maps.js (adicione, ao final do arquivo)
1
2
3
4
5
6
7
8
9
10
11
12
(...)
function listaMarcadores(){
var qtdMarcadores = marcadores.length;
var listaDeMarcadores = document.getElementById('listaDeMarcadores');
listaDeMarcadores.innerHTML = "";
for (var i = 0; i < qtdMarcadores; i++) {
var btn = document.createElement('button');
btn.setAttribute("onclick","map.setCenter(marcadores["+i+"].position);map.setZoom(20);")
btn.appendChild(document.createTextNode(marcadores[i].title));
listaDeMarcadores.appendChild(btn);
}
}

Com essa função, chamada listaMarcadores(), primeiro vemos quantos temos com marcadores.length, na variavel qtdMarcadores.

Aí, pegamos um elemento com id #listaDeMarcadores, limpamos seu conteúdo com innerHtml = "",. (Jájá vamos criar esse elemento, calma)

Nosso for() vai executar para cada item do marcador, criando um <button> com createElement().

Aí definimoss o onClick deste button para executar o método do objeto mapa setCenter() para a propriedade position do marcador ‘da vez’.

Por último, inserimos com createTextNode() o título do marcador como texto do botão, e inserimos o botão ao final.

“Chamando” a função listaMarcadores()

Iremos executar a função que cria o botão logo após criar um novo marcador, portanto iremos inserir listaMarcadores() ao final da função criaMarcador.

A função criaMarcador() deve ficar assim: (incluir APENASlistaMarcadores()`)

maps.js (a função criaMarcador() deve ficar assim:)
1
2
3
4
5
var criaMarcador = function(marcador, mapa) {
(...)
map.setCenter(novoMarcador.position)
listaMarcadores();
}

Criando a div que recebe os botões

No index.html, vamos criar a div com o id #listaDeMarcadores, que receberá os botões criados pela função listaMarcadores().

index.html (insira logo após a div com id map_canvas)
1
2
3
4
5
(...)
<div id="map_canvas" style="width:600px; height:300px"></div>
<div id="listaDeMarcadores">
</div>
(...)

Apagando código obsoleto - limpando um pouco o projeto.

Para nosso código ficar menos bagunçado possível - lembre que estamos sacrificando algumas best pratices (quando inevitável), em pról da didática - devemos excluir duas funções que não serão mais usadas:

  1. Exclua toda a function adiciona() no maps.js

  2. Exclua toda a function converte() no maps.js (agora usamos ela na novoLocal(), né)

  3. Exclua o <button> com o texto adiciona!, pois ele não é mais necessário (index.html)

Testando nosso código

Com a task gulp já rodando, e seu navegador aberto, clique em inciar. Agora, digite uns pontos turísticos de sua cidade, ou de curitiba, avalie cada um deles, e clique em avaliar.

Após criar alguns, navegue entre eles nos botões abaixo do mapa!

Conclusão

Esse autocompletar do google places é Melzinho na Chupeta mesmo!

Imagine o tanto de coisas bacanas que da pra fazer, como filtrar por types/tipos de locais….

No próximo artigo, veremos como chamar o StreetView e descobrir o que é POV (hehehe), entre outras coisinhas legais.

Ah, para ver o que foi alterado em nosso projeto, acesse este commit no github ou clique aqui para baixar