Google Maps – endereços próximos

Nesse post do começo de Maio, falei sobre como usar a API do Google Maps para colocar numa página um mapa que traça uma rota entre dois endereços.

Dando continuidade, usei aquele html como base para exemplificar como usar a API se você necessitar encontrar o endereço mais próximo de uma lista de endereços; no caso abaixo, o que fiz foi plotar na tela 3 endereços (usei como exemplo os endereços de 3 SESCs aqui da capital paulista) e, quando o usuário digitar um endereço e clicar no botão, um listener para o evento onclick do mesmo busca o endereço pela API do Google Maps, faz a comparação entre as coordenadas da latitude e longitude desse endereço com os 3 dos SESCs e, aquele que for mais perto, é usado para traçar um ponto-a-ponto.

Segue, abaixo, o código html totalmente funcional. Ele está todo comentado, e fala por si só; o funcionamento é simples. *aconselho uma lida no post ao qual me referi no começo do post, caso você não esteja familiarizado com a API do Google Maps

[update]parece que havia um problema em alguns browsers dependendo da configuração dele, com o charset utilizado (os endereços com acentuação não eram localizados). Alterei para UTF-8 e upei o html para download[/update]

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Google Maps - encontrando o endereço mais próximo</title>
<script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAM3tYiYBfOKmhuRiSYzXlxRSolT9dJHhqkNrIgFq9Znypr0iOlhQeBdhVvDQuPJy4hxdG187GklHLbA" type="text/javascript"></script>
<script type="text/javascript">
    var geocoder = new GClientGeocoder();
    var map;
    var directionsPanel;
    var directions;
    var gdir = new GDirections();
    var addr = new Array(3);
    var distances = new Array(3);
   
    window.onload = function() {
        //seta o país que será usado pela API
        geocoder.setBaseCountryCode("pt_BR");
        map = new GMap2(document.getElementById(´map´), { size: new GSize(710,480) })
        map.addControl(new GLargeMapControl());
        map.setCenter(new GLatLng(-23.547779, -46.639366), 12); //centro da cidade de São Paulo
       
        //mostra o endereço de 3 Sescs no mapa
        showAddress("Sesc Paulista - São Paulo/SP", 1);
        showAddress("Rua Amador Bueno, 505 - São Paulo/SP", 2); //Sesc Santo Amaro
        showAddress("Rua Clélia, 93 - São Paulo/SP", 3); //Sesc Pompéia
        //ao clicar no botão do formulário, faz a busca
        document.getElementById("trace-route").onclick = function() {
            //tenta encontrar o endereço digitado pelo usuário
            geocoder.getLocations(
                document.getElementById("from").value,
                    function(point) {
                        //marca no mapa o endereço citado
                        add_marker(point);
                        //se existir o endereço que o usuário digitou...
                        if(point.Placemark) {
                            //cria objeto GLatLng e grava a latitude/longitude do endereço digitado pelo usuário, para uso futuro
                            var b = new GLatLng(point.Placemark[0].Point.coordinates[1], point.Placemark[0].Point.coordinates[0]);
                            /*
                            variáveis que serão usadas para comparar distâncias entre coordenadas
                            de latitude e longitude
                            */
                            var smallestDist;
                            var smallestDistId;
                            //percorre lista dos 3 endereços do SESCs
                            for(var i=0; i<3; i++) {
                                var a = new GLatLng(addr[i][1], addr[i][0]);
                                /*
                                usa método da classe GLatLng() que retorna a distância, em metros, entre
                                duas coordenadas de latitude/longitude
                                */
                                var x = a.distanceFrom(b);
                                //lógica para marcar qual a menor distância entre o endereço digitado e os 3 endereços dados
                                if(x<smallestDist || i==0) {
                                    smallestDist = x;
                                    smallestDistId = i;
                                }
                            }
                            /*
                            cria um array de dois objetos GLatLng, com as coordenadas do endereço digitado pelo
                            usuário e o endereço do ponto mais próximo a esse endereço
                            */
                            var pointsArray = [new GLatLng(addr[smallestDistId][1], addr[smallestDistId][0]), b]
                            directions = new GDirections(map); //instancia objetos
                            //usa o array de pontos para traçar a rota entre os dois endereços (ou melhor, entre as duas coordenadas)
                            directions.loadFromWaypoints(pointsArray, {"locale":"pt_BR"});
                        }
                    }
              );
        }
       
    }
   
   
    function showAddress(address, k) {
      geocoder.getLocations(
        address,
        function(point) {
            add_marker(point, k);
        }
      );
    }
   
   
   
    function add_marker(response, k) {
        if(!response.Placemark) {
            return;
        }
        place = response.Placemark[0];
        if(k) {
            //grava a latitude/longitude do endereço
            addr[k-1] = place.Point.coordinates;
        }
        point = new GLatLng(place.Point.coordinates[1],
                            place.Point.coordinates[0]);
        var marker = createMarker(point, place.address, k);
        map.addOverlay(marker);
    }
   
    function createMarker(point,html, k) {
        var marker = new GMarker(point, false);
        return marker;
    }
   
</script>
</head>
<body>
<div id="map"></div>
<form action="#" method="POST">
    <fieldset>
        <label for="from">ponto de partida:</label>
        <input type="text" name="from" id="from" />
    </fieldset>
    <input type="button" class="button" id="trace-route" value="achar SESC mais próximo" />
</form>
</body>
</html>

Traçar um ponto-a-ponto usando o Google Maps

Usando a API do Google Maps como referência, fiz um html simples e funcional onde o usuário pode digitar dois endereços e traçar um ponto-a-ponto (muito semelhante ao que o Apontador disponibilizava e que lhe gerou muita fama) entre os mesmos.

O html é bem simples, contêm duas divs que receberão o mapa e as informações do ponto-a-ponto, e um formulário com os campos

<div id="map"></div>
<form action="#" method="POST">
    <fieldset>
        <label for="from">ponto de partida:</label>
        <input type="text" name="from" id="from" />
    </fieldset>
    <fieldset>
        <label for="from">ponto final:</label>
        <input type="text" name="to" id="to" />
    </fieldset>
    <input type="button" class="button" id="trace-route" value="traçar rota" />
</form>
<div id="route"></div>

O javascript, comentado, é o seguinte:

<script src="http://maps.google.com/maps?file=api&amp;v=2" type="text/javascript"></script>
<script type="text/javascript">
    //cria variáveis globais a serem usadas
    var map;
    var directionsPanel;
    var directions;
    //cria mapa quando página carregar
    window.onload = function() {
        //define que o mapa será desenhado dentro do elemento ´map´
        map = new GMap2(document.getElementById("map"), { size: new GSize(710,480) })
        //insere o controle que possibilita usuário aumentar/diminuir zoom
        map.addControl(new GLargeMapControl());
        //usando as coordenadas de latitude e longitude para São Paulo/SP
        map.setCenter(new GLatLng(-23.547779, -46.639366), 12);
        //define que o ponto-a-ponto será mostrado dentro do elemento ´route´
        directionsPanel = document.getElementById("route");
        directions = new GDirections(map, directionsPanel);
        //efetua a busca, quando usuário clicar no botão
        document.getElementById("trace-route").onclick = function() {
            var fromAddress = document.getElementById("from").value;
            var toAddress = document.getElementById("to").value;
            /*
            "locale":"pt_BR" é necessário ser colocado para forçar uma busca usando os maapas brasileiros
            se não for definido, será usado o padrão da conta do usuário que está usando o browser, o que
            pode provocar erros na busca
            */
            directions.load(fromAddress + " to " + toAddress, {"locale":"pt_BR"});
        }
   
    }
</script>

Observação: na primeira linha, há a chamada o javascript da API do Google Maps. Se você só for testar em um html na sua máquina, funcionará corretamente. Quando for colocar em produção, ou seja, passando por webserver, você terá que gerar uma chave pública do Google. Troque essa chamada pela chamad que será fornecida a você.

Se quiser, faça o download do html já pronto.

E não se esqueça de ver os exemplos do Google Maps, para que você possa ter mais idéias 😉