sábado, 1 de outubro de 2011

Map Control

Não tenho duvidas que o mundo ficou menor quando a Google lançou seu produto Maps e Earth, pois nunca foi tão simples conhecer locais famosos e interessantes navegando através do globo. Essas ferramentas não trouxeram apenas uma nova visão de como deveríamos enxergar o mundo, mas também novos hábitos, como procurar o endereço de destino antes mesmo de sair de casa, localizar os principais pontos de interesse, e por ai afora.

Acredito que todo mundo tenha interesse em incluir o controle Google Map em sua aplicação, tanto que na versão Evolution 2 um domínio chamado Address já fará todo o trabalho sozinho. Por exemplo, não seria interessante colocar o endereço físico de um determinado cliente em um mapa?

Desbravamos a selva com uma bussola para obtermos o norte correto, e com um GPS para ter a latitude e longitude, chegamos a algumas trilhas mais simples que levam a utilização deste controle em aplicações Web, com facilidade e qualidade.

O controle MAP

Esse controle do Javier Luis Larrosa (Artech) e já possui dois anos de existência, está na versão 5.1 para o Evolution 1 U3, e sofreu excelentes evoluções. O Map já é incluído na instalação do Genexus, portanto a primeira coisa a fazer é atualizar sua versão do próprio Genexus.

O controle pode ser instalado manualmente o que não recomendamos, pois o mesmo se encontra em um diretório especifico em /UserControls/GXGoogleVisualizationLibrary/MAP, e já é atualizado pelo próprio instalador do Genexus, mas se, mesmo assim, for necessário pode ser obtido em: Genexus Market Place: Map. A documentação do controle em  Wiki: Map Control, que recomendamos uma boa lida porque existem muitos assuntos que não abordamos aqui.

Esse controle permite visualizar mapas providos pelo Google ou Yahoo, e aqui trataremos apenas os do Google.

A API Google

Essa versão programa a versão V2 da API do Google cuja documentação pode ser estudada em: Google Map API V2. Os servicos disponibilizados podem ser visualizados em Google Map API V2 ServicesPara dispositivos moveis utiliza-se a V3 da API, Google Map API V3, que será a versão do Evolution 2.

Para iniciar no controle o primeiro passo é gerar uma chave para que se incorpore o Maps na aplicação Web, o processo é muito simples e gratuito: Google Map SignUp. O Google Maps API permite que você incorpore-o às suas páginas da web, e a chave gerada válida para um único "diretório" ou domínio, e isso significa que um registro para HTTP://www.projeto.com.br aceitará HTTP://www.projeto.com.br/teste , HTTP://www.projeto.com.br/outro, na sessão de perguntas freqüentes na pagina signup apresenta maiores informações relevantes sobre o tema.

O Endereço

Esse é o ponto fundamental para se obter as coordenadas geográficas corretas, porque o Google disponibilizou um WebService que retorna as informações geográficas a partir de um determinado endereço, e a resposta pode ser obtida em dois formatos distintos JSON ou XML. A questão é como devemos passar o endereço para esse WebService? Como funciona esse WebService?

O WebService chama-se geocode e seu endereço fica em http://maps.google.com/maps/api/geocode, e para seu correto funcionamento é necessário informar o tipo de retorno desejado xml ou json, e mais dois parâmetros: address e sensor

A informação provida por sensor=false indica que a aplicação não possui um dispositivo com sensor de navegação (GPS, Smartdevice, ...)
Um bom exemplo de URL para a chamada do serviço geocode chamada seria: http://maps.google.com/maps/api/geocode/xml?address=Fernando+Prestes+120+Bom+Retiro+Sao+Paulo&sensor=false&sensor=false
E pelo fato de ser XML o retorno seria algo semelhante a:
As dicas fundamentais para a geração de address corretos são:
  • Não colocar acentuação nos endereços (São ..., Praça ...,
  • Não colocar espaços em branco, substituir pelo símbolo +
Um exemplo ruim seria: http://maps.google.com/maps/api/geocode/xml?address=Praça Fernando Prestes, 120, Bom Retiro, São Paulo&sensor=false&sensor=false, veja que temos aqui acentos e espaços em branco, e o resultado é algo como:


Informações a respeito dos caracteres válidos na formação correta de um endereço podem ser obtidas em Google Webservices

Programando o Controle

Ao arrastar o controle Map para um WebPanel, o gx já programa um exemplo para acessar o geocode, para obter os valores da latitude e longitude de um determinado endereço, bastando trocar o valor da variável &address, retornando em formato XML.

Sub 'Geocod'

      &address = 'Fernando+Prestes+120+Bom+Retiro+Sao+Paulo'

&httpclient.Host = 'maps.google.com'
      &httpclient.BaseUrl = '/maps/api/geocode/'
      &postvar = 'xml?address=' + &address + '&sensor=false'
      &httpclient.Execute('GET',&postvar)
      &var = &httpclient.ToString()
      &xmlreader.OpenFromString(&var)
      &xmlreader.Read()
      &xmlreader.ReadType(1,'lat')
      &lat = &xmlreader.Value
      &xmlreader.ReadType(1,'lng')
      &long = &xmlreader.Value
      GoogleMapControl1.Latitude = &lat
      GoogleMapControl1.Longitude = &long
EndSub


Em seguida, opcionalmente pode-se definir uma marca visual na coordenada, que também é apresentado no mapa.  Se necessário mais de uma marca, então é necessário adicionar na coleção &GxMapPoint  um novo item, new(), mas claro que para cada um é necessário definir um &lat e &long.

Sub 'MarkPoint'
           &GxMapPoint.PointLat                 = &lat
     &GxMapPoint.PointLong          = &long
     &GxMapPoint.PointInfowinTit    = 'titulo'
     &GxMapPoint.PointInfowinDesc   = "descricao"
     &GxMapPoint.PointInfowinLink   = "link"
     &GxMapPoint.PointInfowinLinkDsc = ""
     &GxMapPoint.PointInfowinImg    = ""
     &GxMapData.Points.Add(&GxMapPoint)
     &GxMapPoint = new()
EndSub

O resultado da marcação é a apresentação de um sinal na coordenada definida.


Specific Coordenate

Aqui a coisa pega um pouco, porque por alguma razão o mapa não funciona corretamente na primeira apresentação, mas não se desespere, funciona bem. Aparentemente somente nas cidades pré-determinadas no combo City do controle funcionam, e o resultado quando se tenta especificar uma coordenada nova é um mapa vazio que insiste em não carregar nada, e cinza só pra deixar a coisa mais triste.

A saída é uma opção que reconstrói o mapa, antes mesmo de ter sido construído, estranho? Mas é assim mesmo porque na pratica o mapa ainda não foi criado. Assim depois de ter carregado todas as informações, e definidos todas as propriedades, execute um comando.


 GoogleMapControl1.Clear_Overlay = True

E nas propriedades do controle programe a propriedade Specific Coordenate.


Conclusão

Para apontar corretamente na coordenada não é necessário fornecer todas as informações que se encontram no seu cadastro, mesmo porque podem ter inconsistências. Percebi que ao eliminar informações o Google se posicionava melhor. Por exemplo, ao remover a informação Bairro, era considerado o Endereço e Número, e o resultado era mais preciso. Não me pergunte por quê.


O Map também possui uma KB no Genexus Server que pode ser obtida e com esta se aprender um pouquinho mais a respeito deste controle (MapControlSample: http://public.genexusserver.com/gxserver/home.aspx?MapControlSample,0 ).

Só nos cabem aqui os agradecimentos ao Javier Larrosa pelo excelente controle.