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:
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)
2º Escolha um nome para o projeto (GDirections). Figura 3
Mantenha as configurações conforme Figura 4.
Finalize o projeto pelo botão Finish. Figura 5
Adicione ao diretório Web-Inflib todas as bibliotecas do resteasy. 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
Adicione uma pasta script em WebContent. Figura 8
Adicione na pasta script o arquivo json2.js. 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;"> </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> </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;"> </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