... Pague apenas R$67,00 uma única vez e tenha acesso por 1 ano aos vídeos e arquivos exemplos do site ...

Clique aqui e obtenha mais detalhes.


Navegação em Mapas com três ambientes

Paulo Sergio Sarraino

Das tecnologias que vejo na WEB, uma das mais impressionantes para mim é a possibilidade de usar mapas.   Google Maps, Earth e Bing Maps confirmam isso, colocando uma quantidade de informações e possibilidades de pesquisa inimagináveis pelo preço (não) cobrado.  Ao mesmo tempo em que podemos navegar pelo mundo, podemos rastrear um simples endereço de forma bem mais dinâmica do que o velho guia de ruas de papel.

Como analista e desenvolvedor em ambiente Microsoft Office (especialmente Microsoft Access há quase 20 anos), acredito que muitos projetos podem surgir a partir da viabilidade de uso e integração dessas tecnologias.  Para explorar essa capacidade, pensei em desenvolver um pequeno projeto aonde, a partir de um cadastro de Locais (base de endereços da forma mais completa possível) pudesse exibir o mapa da região, utilizando alguns recursos de geoprocessamento e o controle ActiveX Microsoft Web Browser (que permite exibir qualquer página web num aplicativo).  Aproveito também para demonstrar algumas rotinas que utilizo em vários projetos, em especial uma que configura o ambiente do Microsoft Access de tal forma que um aplicativo compilado (ACCDE) pareça um executável.

Trabalhar com mapas envolve duas palavras mágicas: Latitude e Longitude.  Elas nos dão as coordenadas de qualquer endereço no planeta. Eu sei que quando pesquisamos no Google Maps, informamos endereços da forma como conhecemos, mas acredite, internamente tudo é convertido para latitude e longitude (a propósito, o ambiente de mapas do Bing só entende endereços dessa forma). Pesquisando a respeito, achei um serviço gratuito do Google que converte um endereço válido em coordenadas de latitude e longitude, usando um arquivo XML de retorno.

No final, esse projeto, além de demonstrar os mapas da web num aplicativo, possibilitou a visualização de como a estrutura XML pode ser aplicada em outras situações que envolvam um banco de dados.

Bom, passemos ao projeto!

Devido ao controle ActiveX Microsoft Web Browser e as tecnologias que serão utilizadas, precisamos incluir algumas Referências no ambiente do VBA (marcados em vermelho):

Usando Access - Referências Maps

 

Para registrar e organizar os endereços que consultaremos, foi criada a tabela tbl_Locais:

Usando Access - tabela dos endereços

 

Aproveitamos e já cadastramos alguns dados de exemplo:

Usando Access - Endereços

 

Percebam que a tabela é bem simples, visto que a idéia é demonstrar a facilidade de desenvolvimento com qualquer banco de dados que possua dados relevantes. Os mapas tentam entender o endereço da melhor forma possível, seja completo ou usando pontos de referência.

Os mapas são exibidos através do formulário frm_Mapa. Duas propriedades dos controles que merecem destaque são: “Âncora Horizontal” e “Âncora Vertical”. Em conjunto com a propriedade "Estilo da borda" do formulário como "Ajustável", permitem que o formulário do mapa possa ser ajustado ao monitor do usuário ou a área disponível e os controles sejam redimensionados automaticamente.  Veja a estrutura:

Usando Access - Google maps

 

Alguns detalhes sobre os controles utilizados:

Usando Access - Controles Acive X Navegador

 

Para melhor performance do ambiente Silverlight, recomendo que você baixe e instale a sua versão mais recente (5.1.10411.0) no site http://www.microsoft.com/silverlight/

Agora só falta o código!

Há um módulo chamado bas_Geral que possui quatro funções utilizadas no projeto:

Usando Access - Funções

 

No formulário frm_Mapa há as rotinas:

Usando Access - Rotinas

 

Como percebemos, a parte mais importante do processo está na rotina MapUpdate. Ela solicita e retorna o processamento do arquivo XML gerado. Esse arquivo é gerado através de um serviço do Google que permite identificar as coordenadas de latitude e longitude para um endereço válido. A sintaxe do endereço deve seguir dois tratamentos:

• O endereço não pode ter letras acentuadas

• O endereço deve ter todos os espaços entre palavras substituídos pelo sinal de "+".

Para realizar esses tratamentos utilizei a minha função personalizada TratAcentos e a função interna Replace:

strURL = "http://maps.googleapis.com/maps/api/geocode/xml?" & _
         "address=" & Replace(TratAcentos(Nz(Me.txtLocal, "")), " ", "+") & "" & _
         "&sensor=false"

O parâmetro address informa o endereço solicitado e sensor indica se estamos utilizando algum aparelho de GPS (conforme pesquisa na internet).   Vejam um exemplo do arquivo retornado no anexo SGeoMaps (Paulista).xml.

Com o arquivo processado e a referência à estrutura de dados XML, podemos processar sua estrutura e utilizar os métodos e propriedades adequados para nosso projeto:

Usando Access - Estrutura Xml

 

E há diversas outras propriedades que podem ser utilizadas.   Ao final do processo, com as variáveis de Latitude e Longitude definidas, só falta chamar a página do Mapa solicitado com as coordenadas identificadas e outros parâmetros necessários. Cada mapa exibirá suas opções disponíveis, como Zoom, legendas e visualização em 3D.

Veja a rotina completa a seguir:

Function MapUpdate()
'processa parâmetros e solicita mapa conforme coordenadas identificadas
Dim strXML As New DOMDocument
Dim strURL As String
Dim strLat As String
Dim strLng As String
            
'processa endereço no serviço Google Maps API e recebe XML
strURL = "http://maps.googleapis.com/maps/api/geocode/xml?" & _
       "address=" & Replace(TratAcentos(Nz(Me.txtLocal, "")), " ", "+") & "" & _
       "&sensor=false"

 'processa XML e identifica latitude e longitude do endereço
 With strXML
    .Load strURL
     Do While .readyState <> 4  'completed
         DoEvents
     Loop
    
     If .SelectSingleNode("//GeocodeResponse/status").Text = "OK" Then
         strLat = .SelectSingleNode("//GeocodeResponse/result/geometry/location/lat").Text
         strLng = .SelectSingleNode("//GeocodeResponse/result/geometry/location/lng").Text
      Else
         strLat = ""
         strLng = ""
      End If
 End With
    
 Set strXML = Nothing
    
 'processa o mapa conforme tipo informado
 If (strLat = "") Or (strLng = "") Then
    strURL = "about:blank"
 Else
    Select Case Me.grpMapas
       Case 1: strURL = "http://maps.google.com.br/maps?" & _
                         "q=loc:" & strLat & "," & strLng & _
                         "&z=16" & _
                         "&t=h" & _
                         "&output=embed" & _
                         "&iwloc=0"
                      
       Case 2: strURL = "http://dev.virtualearth.net/embeddedMap/v1/ajax/" & _
                         "AerialWithLabels?" & _
                         "zoomLevel=16" & _
                         "¢er=" & strLat & "_" & strLng & _
                         "&pushpins=" & strLat & "_" & strLng
            
       Case 3: strURL = "http://dev.virtualearth.net/embeddedMap/v1/silverlight/" & _
                         "AerialWithLabels?" & _
                         "zoomLevel=16" & _
                         "¢er=" & strLat & "_" & strLng & _
                         "&pushpins=" & strLat & "_" & strLng
    End Select
End If
    
'exibe coordenadas e o mapa processado
Me.txtLatitude = Replace(strLat, ".", ",")
Me.txtLongitude = Replace(strLng, ".", ",")
Me.ctlWebBrowser.Navigate strURL
    
End Function

O formulário frm_Sobre exibe algumas informações sobre o projeto e permite realizar manutenções na base de Locais.

Prá finalizar e proteger o código fonte, devemos gerar o ACCDE do projeto, conforme o comando Criar ACCDE na guia Ferramentas de Banco de Dados.   Ao abrir o novo arquivo GeoMaps.accde, a função ConfigSystem entra em ação para, apenas uma vez, realizar todas as configurações de ambiente necessárias que permitirão visualizar o aplicativo como um executável (sem acesso ao código fonte).

Com isso, terminamos o projeto que é resultado de muita pesquisa e integração de tecnologia. Acredito que há muito mais a ser explorado e várias idéias que poderão ser aplicadas em outros projetos.

Essa matéria, assim como outras que já escrevi, e seus anexos estarão disponíveis também no meu site.

Atenção:  Houve uma mudança no Google Maps em outubro/2013 que inviabiliza a navegação pelo controle web browser.   Uma explicação e a solução você encontra neste link.  (use o tradutor do google).

Arquivo exemplo

Algumas Referências:

Até a próxima!


 

Paulo Sergio Sarraino

Analista Desenvolvedor em ambiente Microsoft Office há quase 20 anos, com especialização 
em Integração de Sistemas e Implantação de Dashboards usando Tecnologias Web e 
Report Server (SQL Server 2008 R2).
 
http://www.sarraino.com.br 
 
pss@sarraino.com.br

 


 

 


38 comentários

Marcos Silva   18/12/2012 11:53:04

Show !

Samuel   18/12/2012 12:39:28

Parabéns!! Muito bom! É muito útil principalmente para empresas de transportes e distribuição. Caso possa elaborar um artigo complementar para roteirização das entregas através dos endereços, seria ótimo!

Abs.

Welson Zeferino De Oliveira Junior   18/12/2012 12:51:50

Excelente, ótimo, muito bom.

Elias   18/12/2012 13:08:40

Caraca esse site é muito fda. Google Maps no Acces... quem diria... Show de bola.

Filipe Bacelar   18/12/2012 13:32:01

Simplesmente fantástico.

Show Avelino.

Fernando   18/12/2012 13:48:17

Pelos comentários parece ótimo, mas comigo da um erro, variavel não definida no bloco with...

Paulo Sergio   18/12/2012 14:16:08

Fernando,

Consegue identificar em qual linha aparece esse erro?

Ederson Garcia   18/12/2012 14:25:45

Muito bom Avelino Parabens pelo otimo trabalho

Caso tenha algum artigo que aborde uma forma onde relizamos a carga de muitos pedidos de compra de clientes e o access possa agrupar os pedidos em zonas para otimização da utilização de veiculos seira otimo

parabens



Rui Sérgio   18/12/2012 14:48:35

Nota 20 Avelino, você inventa coisas que à primeira vista parecem impossiveis :)
Erá interessante poder calcular roteiros quando se tem tarefas em vários destinos.
Parabéns você tem todo o mérito.

Lucas   19/12/2012 06:40:56

Muito bom o programa... Nesse exemplo tem como adicionar o street view?

Emília   19/12/2012 14:58:14

Quem é Avelino? Os créditos não deveriam ser para o Paulo Sarraino?

Junior   19/12/2012 16:00:15

Testado e mais que aprovado!

Henrique   19/12/2012 16:38:33

No meu da um erro Variavel do objeto ou variavel do bloco "With" não foi definida

Linha : If .SelectSingleNode("//GeocodeResponse/status").Text = "270OK" Then

Avelino Sampaio   19/12/2012 16:47:21

Henrique,

verifique se está faltando alguma das referências, listadas no artigo.

Informe a versão do seu Access e do seu Windows, inclusive se é de 32 ou 64 bits.

No aguardo

Marcelo David   20/12/2012 00:04:11

Perfeito Avelino, muito bom mesmo!! Parabéns!!!

Henrique   20/12/2012 09:17:20

Avelino,
Todas referencias ok.
Access 2007 Windows 32 bits.

Avelino Sampaio   20/12/2012 09:22:24

Henrique,

Atualize seu Office 2007 com o pacote sp3. Biaxe do site do Microsoft.

Qual o Windos ? XP, Vista, 7 ou 8 ?



Paulo Sergio Sarraino   20/12/2012 12:32:59

Henrique,

Muito estranho, na linha que vc colou esse "270OK"...isso não está no programa... acho que o código foi alterado... deve estar apenas "OK"...

Rui Sérgio   20/12/2012 17:07:54

Parabéns também para você Paulo Sergio Sarraino, está demais.
Tendo várias moradas numa tabela, seria optimo poder calcular o roteiro mais adequado :)
Parabéns

danilo   29/01/2013 17:01:02

ja não aguento mais tirar o chapeu para você!

Como pode ser tão bom rs


Danielly Guinhazi   10/02/2013 11:25:16

Muito útil. No entanto, gostaria de saber se existe uma forma de acrescentar marcadores no mapa. Eu tenho as coordenadas (lat e long) e gostaria que o ponto fosse apresentado no mapa, tem como? Levando em consideração que eu não tenho o endereço, é zona rural.
Obrigada! E parabéns pelas dicas brilhante que vc dá.

Danielly Guinhazi   10/02/2013 13:35:15

Com relação a pergunta feita anteriormente, tem como usar a coordenada em grau, minuto e segundo. SAD 69?

Marcos Fábio   20/03/2013 14:42:24

Nota 1.000, parabéns!

Como faço para agrupar várias coordenadas latitude e longitude e ou endereços ao mesmo tempo?

MARIO CESAR    29/03/2013 00:22:16

Gostei muito, porém gostaria de saber se existe alguma aplicação para a visualização de todos os registros cadastrados, a partir de suas coordenadas e sendo possível a visualizando dos dados ao clicar no ícone que também seja modificado para o ícone desejado pelo usuário, ficando apenas a caixa de texto de localização para busca de endereço.
E também se é possível na mesma aplicação a inclusão de outras tabelas com nomes e campos diferentes porem no mesmo formato (contendo latitude e longitude).

Henrique Nepomuceno   18/07/2013 08:56:12

Parabéns, pelo post. Muitíssimo útil. A pergunta que não quer calar. Há como se marcar todos os endereços no mapa? Talvez com um Loop? Pois no exemplo dado, marca-se apenas uma localização por vez, quando o que preciso é uma marcação de vários endereços, para ver a distribuição geográfica dos meus dados. Já é uma linha mais de geoprocessamento mesmo. Se alguém puder me ajudar.... obrigado.

Marlon Dias   22/07/2013 19:42:09

Pelos comentários positivos acima, dou parabéns ao autor. Infelizmente para mim não funcionou. Quando tento executar Form_frm_Mapa ele abre o editor de código com a seta apontando para "Function MapUpdate()" . Mensagem "Erro de compilação. O tipo definido pelo usuário não foi definido"
Meu S.O. é Win8 64 bits, VBA 7.0.

Gostaria que você me ajudasse na solução de deste problema.

Obrigado.

Avelino Sampaio   23/07/2013 07:49:49

Marlon Dias,

Abra o aplicativo no modo estrutura.
Abra o VBA e no menu Ferramentas e clique em "Referências"
Verique se está faltando alguma das referências citadas no artigo.

Sucesso!

William   20/08/2013 14:20:05

Caros, boa tarde...

Gostaria de saber como implementar nesta aplicação a função de ler as cidades a partir de uma tabela e criar um mapa de todas...

Ex... Uberlandia MG, Araguari MG, Belo Horizonte MG, Monte Carmelo MG....

E quando abrir o mapa, ele montar com todas as cidades da tabela...

Obrigado...

William
tiuila@yahoo.com.br

Bruno   26/10/2013 17:59:30

Não sei o que esta acontecendo porem quando executo no modo Google maps.... o programa congela.... e os comandos não respondem.....
Aí é só mudar para o BING, e volta tudo a funcionar....

Talvez seja em função da nova versão do google maps.

Bruno   06/11/2013 20:55:43

Erro no script desta página

Linha: 719
Caractere : 172
Erro: InvalidCharacter error
Código: 0
URL: https://maps.gstatic.com/cat_js/intl/pt-BR_br/mapfiles/468d/maps2/%7Bmain,mod_util,mod_act,mod_act_s,mod_actbr,mod_adf,mod_appiw,mod_mssvt,mod_pphover,mod_rst,mod_stars,mod_strr%7D.js

Deseja continuar executando o Script desta página?

Se clicar em SIM ou NÃO ... o mouse não arrasta o mapa

Gilmar Caetano   12/11/2013 13:45:46

Caro Bruno,

Vou te dar um conselho:
- Nunca use o Web Browser em aplicativos.
Digo isso porque sempre tive problemas em usar este componente.
Na verdade este componente não tem suporte, ou melhor dizendo não acompanha e evolução dos scripts em sites.

No entanto, a forma que deve ser feita é criar um objeto do Internet Explorer e customizar conforme a sua necessidade.
Ou simplesmente executar diretamente no navegador.

No Visual Basic é possível criar o Objeto dentro de um formulário, não sei se o Access tem este recurso...

Quanto a função acima eu prefiro simplificar, para que o código fique mais enxuto.

Se a intenção e usar o Google Maps, não tem necessidade de usar Latitude ou Longitude.
Basta enviar o endereço para a URL e executar no navegador.

Veja abaixo o meu exemplo:
Public Declare Function ShellExecute Lib "shell32.dll" _
Alias "ShellExecuteA" _
(ByVal Hwnd As Long, _
ByVal lpOperation As String, _
ByVal lpFile As String, _
ByVal lpParameters As String, _
ByVal lpDirectory As String, _
ByVal nShowCmd As Long) _
As Long




Public Function webMaps(rua As String, bairro As String, cidade As String, UF As String, CEP As String) As String
'Autor: Gilmar Caetano
'Data: 12/11/2013
webMaps = "http://maps.google.com/maps?q="
Dim strURL As String, i As Integer
Dim ArreyURL() As String
strURL = rua & ", " & bairro & ", " & cidade & "-" & UF & "," & CEP
ArreyURL = Split(strURL, ",")
For i = 0 To UBound(ArreyURL)
If ArreyURL(i) <> vbNullString Then
ArreyURL(i) = Replace(ArreyURL(i), Chr(32), "+")
webMaps = webMaps & ArreyURL(i)
End If
Next i
Debug.Print webMaps
'Aqui eu chamo a API para abrir a URL diretamente no navegador, porém pode-se criar o objeto.
dim oIE as object

Set oIE = CreateObject("InternetExplorer.Application")
É possível configurar vários parâmetros do objeto para tirar barra de titulo, status e etc....

Ou carregando diretamente no navegador pela API.


Dim iret
iret = ShellExecute(1000, vbNullString, webMaps, vbNullString, "c:\", SW_SHOWNORMAL)
End Function

Espero que isso te ajude!



Miro   15/11/2013 17:09:56

Ao executar o programa deu o mesmo erro narrado pelo Marlon Dias (23/07/2013) - "Function MapUpdate()" . Mensagem "Erro de compilação. O tipo definido pelo usuário não foi definido".
Verifiquei todas as referências e está tudo ok.
Meu Win é 8.1 - 64 bits access 2007.
Alguma sugestão?
Obrigado

Avelino Sampaio   18/11/2013 06:47:55

Miro,

Troque a referência de MICROSOFT XML, V6.0 para MICROSFT XML, V5.0. Se ainda assim não der certo , continue trocando esta referência para versões inferiores e testando.

No aguardo

Miro   21/11/2013 18:57:24

Grande Avelino. Funcionou perfeitamente.

Rui   23/02/2015 13:47:31

Viva
Será possível ver todos os endereços da tabelas ao mesmo tempo no mapa?

Marcos Silva   19/03/2015 13:31:53

Avelino, primeiramente parabéns pelo site. Acompanho a alguns anos e acho excelente.
Gostaria de saber se voce poderia me ajudar com o seguinte problema.
Eu precisava subir uma tabela com enderecos/locais e capturar suas latitudes e longitudes e ir salvando na tabela. Voce já fez isso antes ? é dificil ? tem algum código +/- para me indicar ? Obrigado !!

Marcaorov   02/06/2015 10:59:57

Execente projeto.
Testei no W7 64 e funcionou perfeitamente.
Parabens!

Robson Quirino   29/07/2015 11:34:35

Tem como mostra mais de um endereço? A ideia é mostrar os clientes próximos que vou separar em uma consulta por cidade ou por latitude e longitude.


Envie seu comentário: