• Google Maps API: Um exemplo prático e comentado

    by  • December 6, 2006 • Desenvolvimento

    Esta semana montei um serviço bem simples para poder testar o uso da API do Google Maps. O serviço foi oferecido aos congressistas do evento PHP Conference Brasil 2006 e era bem simples: cada um entrava e deixava marcado seu ponto de origem, com isso obteríamos um mapa demonstrando de onde os participantes vieram e quantos kilometros viajaram.

    Ainda restam aplicar algumas funções à este serviço, mas ele serviu como meu teste inicial. Resolvi então abrir o código fonte e o fluxo de dados do serviço para que vocês possam conhecer e quem sabe começar utilizar a Google Maps API também.

    Utilizando o Google Maps API para localizar congressistas

    Atenção: Para usar a API você deve registrar sua própria API Key: veja aqui

    Fluxo dos dados

    A primeira parte deste sistema, conforme o diagrama anterior, se trata do arquivo .htm onde colocamos o código do Google Maps API, que é todo escrito em javascript.

    Este arquivo se resume as seguintes funções:

    1. Inicializar o Mapa
    Neste ponto devemos inicializar o código do mapa, setando os controles que desejamos ter além de setar a posição (center) inicial do mapa e seu zoom.

    <script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=API_KEY" type="text/javascript"></script>
        <script type="text/javascript">
    
        //< ![CDATA[
        var zeroLat = new GLatLng(-23.588334358688655,-46.61230802536011); //Ponto central (local do evento)
        function load() {
          if (GBrowserIsCompatible()) {
            var map = new GMap2(document.getElementById("map"));
    		map.addControl(new GLargeMapControl()); //Controles de Zoom, movimento
    		map.addControl(new GMapTypeControl()); // Controle de tipo de mapa
    		map.addControl(new GOverviewMapControl()); //Mapinha pequeno no canto
            map.setCenter(zeroLat, 5); //Setar centro do mapa, com nivel 5 de zoom
    
        //... MORE CODE ...
       </script>
    

    2. Ler dados do XML
    Agora devemos criar uma função que fará a leitura de nosso arquivo XML e criará uma instância de cada item como um marker no Mapa. Note que para o evento, que é nosso ponto central, setamos um ponto (latitude,longitude) central e utilizamos um ícone especial para o mesmo.

    //Handle XML
    GDownloadUrl("phpconfbrasil2006.xml", function(data, responseCode) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker"); //Ler lista de pontos
    
      document.getElementById('count').innerHTML = "<b>Congressistas registrados: "+markers.length+"</b>"; //Publicar contagem
    
      for (var i = 0; i < markers.length; i++) {
    	var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
    							parseFloat(markers[i].getAttribute("lng")));
    
            if (markers[i].getAttribute("tit") == "PHP Conference Brasil 2006"){ //Exceção para ponto central
    		var myIcon = new GIcon(G_DEFAULT_ICON,'ev-icon.png');
    		myIcon.iconSize = new GSize(55, 54);
    		myIcon.iconAnchor = new GPoint(16, 52);
    	}else{
    		var myIcon = G_DEFAULT_ICON;
    	}
    
    	var dados = { title: markers[i].getAttribute("tit"), icon: myIcon}; //Dados
    	map.addOverlay(new GMarker(point,dados)); //Criar marker
    
    	//Adicionar Linha que liga ponto ao evento
    	var polyline = new GPolyline([
    		zeroLat,
    		point
    	], "#ff0000", 1);
    	map.addOverlay(polyline);
    
    	//Adicionar na Lista (HTML)
    	var ul = document.getElementById('ullista');
    	var li = document.createElement('li');
    	li.innerHTML = "<b>"+markers[i].getAttribute("tit")+" - \t\tDistância: "+ Math.round(point.distanceFrom(zeroLat)/1000)+ "km";
    	ul.appendChild(li);
      }
    });

    Estrutura do XML

    < ?xml version="1.0"?>
    <markers>
    	<marker lat="-23.588334358688655" lng="-46.61230802536011" tit="PHP Conference Brasil 2006"/>
    	<marker lat="-15.83783866346968" lng="-47.816104888916016" tit="Rafael Dohms - Brasilia,DF"/>
    </markers>

    3. Setar handler do Click
    Agora devemos dizer ao mapa que ao clicar sobre ele deve ser fornecida uma caixa de dialogo cujos dados serão usados para criar o marker. Após criar este marker o sistema deve instanciar uma conexão AJAX para um backend PHP. Caso o usuário clique sobre um marker o script deve fazer o calculo ate o ponto central e apresentar uma janela de informação com este dado.

    GEvent.addListener(map, "click", function(marker, point) {
      if (marker) { //Se estiver clicando sobre marker
    	var tpoint = marker.getPoint(); //pegar ponto lat por long
    	var distance = tpoint.distanceFrom(zeroLat)/1000;
    
    	var cnt = "<div id='popup'>";
    	cnt    += "<br />Distância: "+Math.round(distance)+" km"; //Calcular distancia
    	cnt    += "</div>";
    	marker.openInfoWindowHtml(cnt);
      } else { //Se estiver clicando em ponto em branco
    	var nome = window.prompt("Digite: NOME - Cidade,Estado"); //Pegar texto para nome do marker
    	if (!nome){
    		return false
    	}
    	var dados = { title: nome }
    	map.addOverlay(new GMarker(point,dados));
    
    	//Adicionar no XML via AJAX
    	var req = GXmlHttp.create();
    	req.open("POST", "addmarker.php", true);
    	req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    
            //Montar parâmetros
    	var param = 'tit=' + nome;
    	param 	 += '&lat=' + point.lat();
    	param 	 += '&lng=' + point.lng();
    	req.send(param);
      }
    });

    A segunda parte do sistema se trata de um arquivo PHP responsável por receber os dados do ponto criado e criar um registro no XML deste ponto. Cada ponto possui uma latitude, uma longitude e um título. Como este xml só será usado na próxima atualização o script não necessita de retornar dados ao script original.

    < ?
    //Recebe os dados e Cria um novo string no XML
    
    //Definir Arquivo XML
    define('FILE',"phpconfbrasil2006.xml");
    
    //Abrir XML
    $xmlDoc = new DOMDocument('1.0','utf-8');
    $xmlDoc->load(FILE);
    $xmlDoc->formatOutput = true;
    
    //Criar novo item
    $nLocation = $xmlDoc->createElement('marker');
    $nLocation->setAttribute('lat',$_POST['lat']);
    $nLocation->setAttribute('lng',$_POST['lng']);
    $nLocation->setAttribute('tit',$_POST['tit']);
    
    //Adicionar ao nó markers
    $nLocation = $xmlDoc->firstChild->appendChild($nLocation);
    
    //Salvar arquivo
    $xmlDoc->save(FILE);
    
    ?>

    Assim temos um script completo. Neste caso pedimos para que além de mostrar o mapa com os marker o script deve também imprimir uma LIST com o texto de todos registros e uma contagem de quantos estes são.

    O exemplo é bem simples, mas acho que passa uma idéia inicial do que pode ser feito e como pode ser feito utilizando o Google Maps API. Toda documentação pode ser encontrada nos link abaixo:

    Google Maps API
    Google Maps API – Documentation

    About

    Rafael Dohms is a PHP Evangelist, Speaker and contributor. He is a very active member of the PHP Community, having helped create and manage two PHP User Groups in Brazil. He shared the lead of PHPSP for 3 wonderful years making a positive mark on the local market. Developer, gamer and lover of code he also hosts Brazil’s first PHP Podcast: PHPSPCast, as well as contributing to well known projects. He moved to the Netherlands in search of new challenges and is now part of the team at WEBclusive, sharing his passion for quality code and working on new awesome ideas with the team. You can always find him at the nearest Community events, speaking, sharing, talking or just learning from the rest.

    http://doh.ms