+55 (47) 3036.7700

contato@teclogica.com

Salvando pontos de interesse arrastáveis do Google Maps V3

Teclógica > Blog > Serviços de TI > Salvando pontos de interesse arrastáveis do Google Maps V3

Salvando pontos de interesse arrastáveis do Google Maps V3

Este artigo demonstra como criar no Google Maps com a API Directions pontos de interesse e salvá-los para que possam ser visualizados em um momento futuro na UI (interface do usuário).

O Google Maps V3 tem um serviço onde podemos mostrar a direção de um ponto de saída até um ponto chegada e que pode ser arrastada para alterar o trajeto. Com o mouse, o usuário poderá alterar a rota conforme sua necessidade. Isso significa alterar o trajeto padrão, direcionado pelo Google. O usuário então poderá criar pontos de interesse entre o trajeto padrão e mostrá-los para diferenciar a rota atual e a modificada. Para o uso em desenvolvimento a Google permite o máximo de oito pontos de interesse.

O visual da aplicação final será conforme abaixo:

 Figura 1As tecnologias adotadas para salvar o trajeto e os respectivos pontos de interesse são: HTML, Javascript, JQuery, JDK 1.7, Webservices (resteasy) e servidor de aplicações Glassfish. Ao final do artigo pode ser realizado o download do projeto para importá-lo no Eclipse.

Pré-requisitos: antes de começar, certifique-se que o JDK e Glassfish 3.1 estão instalados e configurados na sua máquina junto com a IDE Eclipse.

Execute a IDE Eclipse e selecione um workspace onde deseja criar o projeto.

1º Clique em File-> New-> Dynamic Web Project . (Figura 2)

Figura 2

2º Escolha um nome para o projeto (GDirections). Figura 3

Figura 3

Mantenha as configurações conforme Figura 4.

Figura 4

Finalize o projeto pelo botão Finish. Figura 5

Figura 5

Adicione ao diretório Web-Inflib todas as bibliotecas do resteasy. Figura 6

Figura 6

Crie a classe dentro da pasta src, br.com.rezende.map.services.DirectionsServices,  e adicione o arquivo index.jsp dentro de WebContent. Figura 7

Figura 7

Adicione uma pasta script em WebContent. Figura 8

Figura 8

Adicione na pasta script o arquivo json2.js. Figura 9

Figura 9

O mapa da esquerda (Figura 1) é onde foi criado o trajeto padrão, o qual permite alterar e adicionar 8 pontos de interesse. Para alterar esse trajeto e adicionar pontos de interesse, mova o mouse sobre a linha amarela e aguarde o círculo aparecer. Arraste o círculo para qualquer direção e solte o botão do mouse. Assim o usuário poderá alterar a rota somente arrastando o círculo com o mouse e criando novos pontos de interesse. Ao clicar sobre o botão “Salvar”, um serviço armazena a string “JSON” em uma variável para que possa ser recuperada posteriormente. Não estamos utilizando banco de dados neste momento, pois este artigo tem como foco somente demonstrar como se utiliza a API Google Directions.

Código e Explicação

Você pode usar o mesmo código escrito neste artigo.
É necessário que você tenha algum conhecimento com o Google Map V3, tal como mostrar o mapa dentro de uma <div> e centralizá-lo passando latitude e longitude como parâmetros para o objeto do mapa.
Veja abaixo a explicação do fluxo realizado.

No arquivo web.xml adicione as seguintes linhas:

      <context-param>
           <param-name>resteasy.scan</param-name>
           <param-value>true</param-value>
      </context-param>
      <listener>
           <listener-class>
                org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
           </listener-class>
      </listener>
      <servlet>
           <servlet-name>Resteasy</servlet-name>
           <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
      </servlet>
      <servlet-mapping>
           <servlet-name>Resteasy</servlet-name>
           <url-pattern>/rest/*</url-pattern>
      </servlet-mapping>

Na classe criada anteriormente, DirectionsServices, adicione o seguinte código.

 @Path("/rest/directionsWS")
 public class DirectionsServices {
      private static String gMapsJson;
      @GET
      @Produces("application/json")
      @Path("/render")
      public String render() {
           String resp = gMapsJson;
           System.out.println("Foi");
           return resp;
      }
      @GET
      @Path("/save/{param}")
      @Produces("application/json")
      public String save(@PathParam("param") String json) {
           this.gMapsJson = json;
           return gMapsJson;
      }
 }

Inclua o código abaixo na seção do cabeçalho de seu index.jsp. O primeiro irá incluir a API do Google Map V3 e o segundo é usado para criar uma string Json de um array de objetos.

 <script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=false"></script>
 <script src="json2.js"></script>

Esse array de objetos converte os pontos de interesse para o formato Json e então irá parar o servidor e salvar em nossa variável estática.

Ainda dentro do index.jsp crie uma div com o id igual a map_canvas e seu estilo. Crie também um botão para chamar uma função Javascript que irá salvar os pontos de interesse. Quando a página forma inicializada, esse mesmo irá chamar a função Javascript initialize() que carregará o mapa padrão, ao lado esquerdo Figura 1.

 <body onload="initialize()">
      <form id="form">
           <div class="contents" style="width: 90%; margin: 0px auto;">
                <div class="maindiv" style="width: 100%;">
                     <table width="100%" border="0" cellspacing="0" cellpadding="0">
                          <tr>
                               <td width="49%" style="padding: 3px; color: #993333;">Clique no trajeto em amarelo e arraste em outro local.</td>
                               <td width="2%" style="padding: 3px; color: #993333;">&nbsp;</td>
                               <td width="49%" style="padding: 3px; color: #993333;">Clique sobre o botão carregar para exibir o trajeto salvo.</td>
                          </tr>
                          <tr>
                               <td><div id="map_canvas" style="width: 100%; height: 250px;"></div></td>
                               <td>&nbsp;</td>
                               <td><div id="map_ren" style="width: 100%; height: 250px;"></div></td>
                          </tr>
                          <tr>
                               <td style="text-align: center; padding-top: 10px;">
                                             <input type="button" value="Salvar" id="save" name="save"/>
                               </td>
                               <td style="text-align: center;">&nbsp;</td>
                                <td style="text-align: center; padding-top: 10px;">
                                 <input type="button" id="render" name="render" value="Render" />
                               </td>
                          </tr>
                     </table>
                </div>
           </div>
      </form>
 </body>

Adicione no arquivo index.jsp as funções e variáveis Javascript que serão utilizadas para “plotar” os mapas e os trajetos.

 <script type="text/javascript">
      var directionDisplay;
      var directionsService = new google.maps.DirectionsService();
      var map;
      var data = {};
      var polylineOptionsActual = {
           strokeColor : '#FFF000',
           strokeOpacity : 1.0,
           strokeWeight : 6
      };
      var directionDisplay2;
      var directionsService2 = new google.maps.DirectionsService();
      var map2;
      var polylineOptionsActual2 = {
           strokeColor : '#FF0000',
           strokeOpacity : 1.0,
           strokeWeight : 6
      };
      function initialize() {
           var blumenau = new google.maps.LatLng(-26.889005, -49.070641);
           var florianopolis = new google.maps.LatLng(-27.566721, -48.551537);
           directionsDisplay = new google.maps.DirectionsRenderer({
                polylineOptions : polylineOptionsActual,
                'draggable' : true
           });
           directionsDisplay2 = new google.maps.DirectionsRenderer({
                polylineOptions : polylineOptionsActual2,
                'draggable' : false
           });
           var myOptions = {
                zoom : 12,
                mapTypeId : google.maps.MapTypeId.HYBRID,
                center : blumenau
           };
           map = new google.maps.Map(document.getElementById("map_canvas"),
                     myOptions);
           map2 = new google.maps.Map(document.getElementById("map_ren"),
                     myOptions);
           directionsDisplay.setMap(map);
           directionsDisplay2.setMap(map2);
           directionsService.route({
                'origin' : blumenau,
                'destination' : florianopolis,
                'travelMode' : google.maps.DirectionsTravelMode.DRIVING
           }, function(res, sts) {
                if (sts == 'OK') {
                     directionsDisplay.setDirections(res);
                }
           });
      }
 function setroute(os) {
           var wp = [];
           for ( var i = 0; i < os.waypoints.length; i++)
                wp[i] = {
                     'location' : new google.maps.LatLng(os.waypoints[i][0],
                               os.waypoints[i][1]),
                     'stopover' : false
                };
           directionsService2.route({
                'origin' : new google.maps.LatLng(os.start.lat, os.start.lng),
                'destination' : new google.maps.LatLng(os.end.lat, os.end.lng),
                'waypoints' : wp,
                'travelMode' : google.maps.DirectionsTravelMode.DRIVING
           }, function(res, sts) {
                if (sts == 'OK')
                     directionsDisplay2.setDirections(res);
           });
      }
      $(function() {
           $('#save').click(
                     function() {
                          var w = [], wp;
                          var rleg = directionsDisplay.directions.routes[0].legs[0];
                          data.start = {
                               'lat' : rleg.start_location.lat(),
                               'lng' : rleg.start_location.lng()
                          };
                          data.end = {
                               'lat' : rleg.end_location.lat(),
                               'lng' : rleg.end_location.lng()
                          };
                          var wp = rleg.via_waypoints;
                          for ( var i = 0; i < wp.length; i++) {
                               w[i] = [ wp[i].lat(), wp[i].lng() ];
                          }
                          data.waypoints = w;
                          var str = JSON.stringify(data);
                          $.get(
                                    'http://localhost:48080/GDirections/rest/directionsWS/save/'
                                              + str, function(data) {
                                    });
                          alert('Trajeto Salvo.');
                     });
           $('#render')
                     .click(
                               function() {
                                    $.get(
                                                        'http://localhost:48080/GDirections/rest/directionsWS/render',
                                                        function(data) {
                                                             setroute(data);
                                                        });
                               });
      });
 </script>

As variáveis declaradas para o Google Maps devem possuir informação de local de partida, local de chegada, pontos de interesse em latitude e longitude. Então o mapa deve ser inicializado passando o “id” de onde será mostrado, nível de zoom, tipo de mapa e centralização.

A função route de DirectionsService irá traçar uma rota do ponto de partida ao de chegada, no modo de “direção”. Ela enviará uma requisição para o servidor do Google e obterá o caminho como resultado, “plotando” a informação. Na função call-back, se a resposta for ok, então é atribuído para setdirections a função que irá desenhar o trajeto no Google Map por directionsDisplay.

Ao clicar no botão “Salvar”, a função save cria uma string Json e envia para ser armazenada na variável do Webservices.

Quando o usuário arrasta o trajeto, um novo ponto de interesse é criado no objeto, alterando o array de pontos de interesses.

Para atualizar essa lista, foi criado um “loop” que guarda somente latitude e longitude dos pontos de interesse. Então a informação de LatLng do ponto de interesse  é armazenada na propriedade “locations”. Por fim, o objeto data será convertido em uma string Json pelo método stringify.

O Webservices DirectionsServices irá receber através do método save a string Json enviada como parâmetro e armazenar a nova informação no objeto gMapsJson.

Quando o usuário clicar sobre o botão Render, a função Javascript associada irá requisitar ao Webservices um objeto do tipo string Json para desenhar a rota armazenada anteriormente.

A função javascript setroute irá receber o objeto string do tipo Json do servidor.

Será necessário criar um objeto que contém os pontos de latitude e longitude de partida e chegada, assim como os pontos de interesses.

Com esses pontos, criamos um objeto com origem e destino e dizemos para o mapa traçar as rotas. Após ser mapeado esse trajeto, é necessário exibi-lo através da chamada de setDirections dentro da função de call-back.

Conclusão

A API do Google Maps é bem simples de se utilizar e pode ser usada para desenvolvimento com um limite de acessos diários. Pode ser visualizado na documentação on-line: aqui.

Trabalhando em conjunto com a Google Directions API permitem rotear trajetos, calcular rotas antecipadamente e estilizar objetos que serão desenhados no mapa. É uma excelente alternativa para o mercado brasileiro. Ele tem um conjunto de  1397 municípios brasileiros em um serviço on-line, muitos deles atualizados com a data do ano de 2012.
Por ser um serviço on-line, as atualizações dos mapas estão inclusas.
Outra vantagem é que não é necessário armazenamento dos mapas em espaço local.

Download de código fonte e bibliotecas: O código fonte pode ser obtido Aqui

Andre Meirelles de Rezende
Arquiteto de Software