O Google disponibiliza duas formas para acesso as imagens dos mapas da ferramenta Maps através da sua API: estáticas e dinâmicas.
A ferramenta Maps é livre para uso em sites e sistemas gratuitos, mas o grande problema é que o Google não aceita que esta ferramenta fique fechada em uma aplicação desktop, assim, caso você deseje realmente utilizar esta ferramenta dentro de uma aplicação desktop será necessário entrar em contato com o escritório que representa a empresa no Brasil.
Veremos que pouca programação em Fox será utilizada, mesmo porque a API do Google Maps utiliza outras linguagens como, por exemplo, o JavaScript para realizar as operações e exemplos que serão mostrados.
No Visual FoxPro iremos criar um formulário com um controle Textbox (para a pesquisa do endereço) e um controle button que irá disparar a pesquisa. Além disso, vamos adicionar um componente OLE WebBrowserControl que irá exibir o mapa de forma dinâmica.
Para isso, na janela de comandos do Visual FoxPro digite o comando:
Com este comando garantimos que o novo formulário irá derivar da classe básica de formulários do Visual FoxPro. Podemos ver como ficou o formulário na Figura 1.
Agora vamos adicionar os controles Label, Textbox e CommandButton ao formulário. Para isso vamos usar os passos da Listagem 2.
Listagem 2. Nomeie os controles da seguinte forma.
Agora formate o layout do formulário para que fique conforme a Figura 2.
Figura 2. Formatando layout do formulário
Até o momento nosso formulário já tomou a forma básica, mas ainda falta o componente OLE com o controle WebBrowser que irá exibir o mapa. Por isso, na guia tools do VFP 9 acesse o item Component Gallery e selecione o controle WebBrowser Control, conforme mostra a Figura 3.
Figura 3. Selecionando controle
Arraste o controle para o formulário e o mesmo deverá ficar conforme a Figura 4.
Figura 4 - Resultado do Formulário
Agora dê um duplo clique no cmdPesquisar e acrescente o código da Listagem 3.
Listagem 3. Comando cmdPesquisar
Local endereco As String
If !Empty(endereco)
endereco = ''
#DEFINE FLAG_ICC_FORCE_CONNECTION  1
lcUrl = "http://www.google.com.br"
LOCAL lResultado
lResultado = (InternetCheckConnection(lcUrl, FLAG_ICC_FORCE_CONNECTION, 0)=1)
IF !lResultado
Messagebox("Conexão com a Internet não disponível!")
With Thisform.pasta.page1
endereco = '"'+Alltrim(.enderecoText.Value) +'"'
endereco = Strtran(endereco,'ã','a')
endereco = Strtran(endereco,'õ','o')
endereco = Strtran(endereco,'é','e')
endereco = Strtran(endereco,'ê','e')
endereco = Strtran(endereco,'í','i')
endereco = Strtran(endereco,'ó','o')
endereco = Strtran(endereco,'ú','u')
endereco = STRTRAN(end_, ' ', '+')
This.Parent._WEBBROWSER41.Navigate(SYS(5)+SYS(2003)+"\mapas\index.htm"+"?"+endereco)
Para explicar o código acima, temos alguns trechos que precisam ser comentados para trazer maior clareza do que está acontecendo. Observe a Listagem 4.
Listagem 4. Declarando variável endereço como string.
No trecho acima declaramos uma variável endereço como string e, em seguida, realizamos a verificação para saber se a mesma já está preenchida: caso sim igualamos a vazio.
Listagem 5. Verificando conexão com a internet.
*--------------------------------------------------- VERIFICA A CONEXÃO COM A INTERNET
Na Listagem 5 realizamos a verificação de conexão com a internet. Lembrando que para solicitar as imagens dos mapas é necessário conexão com a internet, por isso a variável lResultado de ter seu valor igual a .T..
Listagem 6. Resultado se a conexão com não existir.
endereco = '"'+Alltrim(.enderecoText.Value)+'"'
endereco = Strtran(end_,'ã','a')
endereco = Strtran(end_,'õ','o')
endereco = Strtran(end_,'é','e')
endereco = Strtran(end_,'ê','e')
endereco = Strtran(end_,'í','i')
endereco = Strtran(end_,'ó','o')
endereco = Strtran(end_,'ú','u')
endereco = STRTRAN(endereco, ' ', '+')
Na Listagem 6 estamos realizando a verificação do acesso a internet: se o mesmo não existir, uma mensagem é exibida ao usuário; do contrário, retiramos os acentos da variável endereco que será utilizada na busca da imagem do mapa.
Listagem 7. Solicitando mapa para o endereço informado.
ThisForm._WEBBROWSER41.Navigate(Sys(5)+Sys(2003)+"\index.htm"+"?"+endereco)
Na Listagem 7 realizamos a solicitação do mapa para o endereço informado.
Bom, até aqui fizemos a parte fácil (claro, para quem programa em Fox), ou seja toda programação do lado do VFP 9.
Temos então que partir para o lado web e criar um Web Site com JavaScript que vai instanciar a API do Google Maps e exibir os mapas e controles dentro do ambiente que criamos acima no VFP.
Para isso, você vai precisar de um editor HTML ou pode utilizar o famoso bloco de notas mesmo. Para criar a página, use o código da Listagem 8.
Listagem 8. Página HTML
<title>Google Maps JavaScript API v3 Examplo: Drawing Biblioteca</title>
font-family: "Trebuchet MS", Arial,Helvetica,Sans Serif;
width: length(titulo);
Acima definimos o tipo de documento "HTML" e a folha de estilos o CSS.
Listagem 9. Código JavaScript
<script type="text/javascript"    src="http://maps.googleapis.com/maps/api/js?key=sua_chave_api&sensor=false&libraries=drawing" type="text/javascript">
var rectangle = [];
var circleCount = 0;
var rectangleCount = 0;
var polylineCount = 0;
var markerMode = false;
Na Listagem 9 estamos instanciando a API do Google Maps e as váriaveis que serão utilizadas na página para manipular o mapa.
No código key=sua_chave_api você deve obter uma chave da API do Google e substituir no local marcado.
Para obter uma chave acesse o link https://developers.google.com/maps/documentation/javascript/tutorial?hl=pt-br#api_key
Para acessar esta tela (mostrada na Figura 5) você deve estar devidamente logado com sua conta do Google.
Figura 5. Tela de serviços
Abaixo habilite o componente da API como mostra a Figura 6.
Figura 6. Habilitando componente da API
Lembre -se de consultar os termos de uso no link a seguir: https://developers.google.com/maps/terms?hl=pt-br
Listagem 10. Função que inicializa a chamada do mapa.
var url = location.href.replace(location.href.split("?")[0] + "?", "");
mapMarker: false,
Note que estamos recuperando o endereço da variavel "var url" que será tratado adiante. Logo em seguida definimos o geocoder.
Dentro de "var mapOptions" definimos o estilo no qual o mapa será inicializado:
Zoom: 18 - significa que a propriedade zoom será iniciada como valor 18, mas você pode ajustar como bem quiser.
mapTypeControl : false - indica que os controles do mapa não serão exibidos.
mapTypeId : google.maps.MapTypeId.SATELLITE - define o tipo de mapa que será inicializado.
streetviewControl : false - desabilita o controle streetView.
panControl : false
scaleControl : false
disableDoubleClickZoom - true : Habilita o evento duplo clique do mouse para dar zoom no mapa.
zoomControl : true - Habilita o controle de zoom no mapa.
zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL } - define o estilo do controle zoom.
Na Listagem 11 tratamos o endereço que será recuperado na URL e definimos a variável de controle do mapa
Listagem 11. Tratamento da URL.
endereco(url);
google.maps.drawing.OverlayType.NULL,
Em "endereco(url);" -> tratamos o endereço passado na função endereço e retornamos o geocode. Já a variável map recebe a instância do mapa com as opções definidas na variavel mapOptions.
Em drawingManager estamos instanciando o controle de desenhos no mapa e suas propriedades e habilitamos os estilos e formas de desenhos. Mais abaixo podemos notar as configurações de cada item de desenho habilitado na ferramenta DrawingManager.
No item drawingManager.setMap(map); estamos habilitando o controle e as propriedades definidas nele no mapa.
Na Listagem 12 vamos guardar as posições do clique de cada desenho para podermos limpar o mapa depois.
Listagem 12. Posições de cliques
circle[circleCount] = event.overlay;
rectangle[rectangleCount] = event.overlay;
polygon[polygonCount] = event.overlay;
if (event.type == google.maps.drawing.OverlayType.POLYLINE) {
polyline[polylineCount] = event.overlay;
polylineCount++;
mapClick(e.latLng, map, markermode);
Note no código que as posições são armazenadas nas variáveis definidas no início do código.
Já na Listagem 13 definimos a função endereco utilizada para traduzir o endereço passado na URL para o GeoCode.
Listagem 13. Função endereco
//Busca o endereço para exibir no mapa
function endereco(url) {
geocoder.geocode({ 'address': url }, function(results, status) {
'<p><b>"O ponto informado encontra-se neste local:"</b>' +
'<br>' + url + '</br>' + ' Latitude/Longitude: ' + '<br>' +                results[0].geometry.location + '</br>' + '<br>' + '</br>' +
alert('Não foi possivel encontrar o endereço!');
Note que também acrescentamos uma InfoWindow, que é um balão que aparece com a descrição "O ponto informado encontra-se neste local : Latitude/Longitude : " . Esta mensagem somente é exibida quando clicamos no marcador, que por sua vez, inicializa o mapa quando chamamos o mesmo, assim, ele já vem fixado no endereço informado na URL.
Na Listagem 14 definimos a função deleteOverlays utilizada para limpar o mapa.
Listagem 14. Função deleeteOverlays.
function deleteOverlays(a){
for (var i = 0; i < markerCount1; i++) {
marker2[i].setMap(null);
circle[i].setMap(null);
for (var i = 0; i < rectangleCount; i++) {
rectangle[i].setMap(null);
for (var i = 0; i < polygonCount; i++) {
for (var i = 0; i < polylineCount; i++) {
polyline[i].setMap(null);
Note que utilizamos as posições guardadas anteriormente nos arrays para deletar os pontos alterados no mapa.
Com isso, na Listagem 15 finalizamos o arquivo HTML.
Listagem 15. Arquivo HTML.
<body  scroll="no" topmargin="0" leftmargin="0" onload="initialize()">
<table border ="1" cellpadding ="1" cellspacing ="1" width ="100% " id="toptable" class="normal">
<form action="#" name="teste">
<td  align="center" style="font-size:12px" title="Apaga todas a alterações feitas no mapa..." onmouseover="this.className='over'" onmouseout="this.className='out'" onclick="a = confirm('Confirma a limpeza do Mapa?');deleteOverlays(a);this.className='click';">
<img id="delete" title="Apaga todas a alterações feitas no mapa..." onclick="a = confirm('Confirma a limpeza do Mapa?');deleteOverlays(a);" src="" width="18" height="18"/>
<br />Limpar o Mapa
<table border ="0" width ="100%">
<tr style="vertical-align:top"></tr>
Podemos notar o resultado final na Figura 7.
Figura 7. Resultado final do Formulário Mapas
Neste pequeno tutorial foram abordados apenas conceitos básicos na operação com a API do Google e o Visual Fox. É possível ainda criar mais ferramentas como, por exemplo: captura de imagem do mapa, marcadores com títulos, trocar as imagens e configurações das formas de desenhos, criar uma função para limpar o mapa, desfazer alterações e muito mais.