O post Delphi e Google Maps JavaScript API teve relativo sucesso, recebendo vários acessos. Nele, utilizei um exemplo pronto em vez de utilizar diretamente a API do Google Maps. A ideia era ganhar tempo (ou seria preguiça? :) ).

Recebi muitos pedidos, como por exemplo: utilizar o Delphi7 (o que no exemplo proposto ficou inviável); alterar rotas em tempo de execução clicando diretamente no mapa; e alguns ajustes adicionais que, mesmo sendo possível aplicar no exemplo, acaba exigindo consulta à documentação do Google. Já que temos que olhar o help da API porque não passar a utilizá-la diretamente? É o que iremos fazer neste post.

Não será dessa vez que irei estrear o meu XE2 novinho em folha – vou deixar para o próximo artigo. Neste post, irei utilizar o bom e velho Delphi 7, e assim demonstrar que é possível utilizar a função mesmo numa versão antiga da ide.

Para trabalhar diretamente com a API, devemos antes entender o funcionamento da mesma. Acesse:
https://developers.google.com/maps/documentation/javascript/tutorial?hl=pt-BR. Lá você terá muitas informações. Sugiro que você comece por “Getting Started” para se familiarizar um pouco com os termos que serão abordados aqui.

Dando continuidade ao nosso artigo, clique em Services e depois em Directions:

Descendo até “Displaying the DirectionsResult” temos o código que servirá de base para o nosso projeto:

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var chicago = new google.maps.LatLng(41.850033, -87.6500523);
  var mapOptions = {
    zoom:7,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: chicago
  }
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  directionsDisplay.setMap(map);
}

function calcRoute() {
  var start = document.getElementById("start").value;
  var end = document.getElementById("end").value;
  var request = {
    origin:start,
    destination:end,
    travelMode: google.maps.TravelMode.DRIVING
  };
  directionsService.route(request, function(result, status) {
    if (status == google.maps.DirectionsStatus.OK) {
      directionsDisplay.setDirections(result);
    }
  });
}

Faremos o seguinte procedimento:

  • Iremos criar uma página chamada google.html (pode utilizar o notepad ou qualquer outro editor de texto) e inserir este código (javascript);
  • Feito isso, iremos fazer com que o Delphi chame a função acima calcRoute. O resultado será visto em 3 divs: uma para receber o mapa, uma que mostrará o caminho a ser percorrido e uma para o total da distância;
  • Ao clicar no mapa, utilizaremos eventos para capturar a posição em latitude/longitude do click, e assim alterar a rota.

Então mãos à obra!

Crie uma nova aplicação no delphi (file/new/application). Salve o projeto.

Crie uma página html chamada google.html no diretório da aplicação. Tem que ficar no mesmo diretório do executável.

Coloque o seguinte código:

<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no">
    <meta charset="utf-8">
    <title>Cálculo Rota</title>
    <script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
    <script>
		var directionsDisplay;
		var directionsService = new google.maps.DirectionsService();
		var map;
 
		function initialize() {
		  directionsDisplay = new google.maps.DirectionsRenderer();
		  var mapOptions = {
			zoom:10,
			mapTypeId: google.maps.MapTypeId.ROADMAP
		  }
		  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
		  directionsDisplay.setMap(map);
		}
		 
		function calcRoute() {
		  var request = {
			origin:arguments[0],
			destination:arguments[1],
			travelMode: google.maps.TravelMode.DRIVING
		  };
		  directionsService.route(request, function(result, status) {
			if (status == google.maps.DirectionsStatus.OK) {
			  directionsDisplay.setDirections(result);
			}
		  });
		}
	</script>
  </head>
<body style="overflow: hidden; width: 100%; height: 100%" onload="initialize()">
 <div id="map_canvas" style="width: 780px; height: 580px;"></div>
 <div id="directionsPanel"></div>
 <div id="divTotal"></div>
</body>
</html>

Observações:

  • Tirei a variável “chicago”;
  • Tirei a opção center de mapOptions, que centralizaria o mapa em Chicago;
  • Em calcRoute/request, origin recebe o primeiro argumento e destination, o segundo. Eles são responsáveis pelos endereços de início e fim da rota;
  • Note que em body tem um div com o nome ‘map_canvas’ e na criação do objeto “map” (linha 19) informamos o nome da div, ou seja, definimos o local onde o mapa será renderizado.
  • Em body temos 3 divs: map_canvas (que receberá o mapa), directionsPanel (o percurso) e divTotal.

No Delphi, altere o formulário para que fique parecido com este:

Irei disponibilizar os fontes no fim do artigo.

No OnShow do form, coloque:

  Web.Navigate(ExtractFilePath(Application.ExeName) + 'google.html');

Assim, quando abrir o form, irá carregar a página google.html.

No OnResize, coloque:

var
  r: TRect;
const
  SB_GETRECT = WM_USER + 10;
begin
  // Definindo onde ficará a progressbar, neste caso será
  //Na barra de Status, no painel 1
  Statusbar1.Perform(SB_GETRECT, 1, Integer(@R));
  ProgressBar1.Parent := Statusbar1;
  ProgressBar1.SetBounds(r.Left, r.Top,
    r.Right - r.Left - 5, r.Bottom - r.Top);
end;

Acima, configuramos o progressbar para ficar na barra de status.

No evento OnProgressChange do WebBrowser:

  if (Progress >= 1) and (ProgressMax > 1) then
  begin
    ProgressBar1.Position := Round((Progress * 100)
      div ProgressMax);
    ProgressBar1.Visible := True;
  end
  else
  begin
    ProgressBar1.Position := 1;
    ProgressBar1.Visible := False;
  end;

Mostra progresso da abertura da página.

No click do botão “OK” coloque o seguinte código:

var
   JSFn: string ;
begin
  if (Trim(edEnd1.text)='') or (Trim(edEnd2.text)='') then exit;

  JSFn := Format( 'calcRoute("%s","%s")', [edEnd1.Text, edEnd2.Text]);

   with Web.Document as IHTMLDocument2 do
     parentWindow.execScript(JSFn, 'JavaScript' );
end ;

Este código é responsável por executar a função calcRoute da página html carregada na inicialização do form, o google.html.

Compile e execute. Preencha os edits (cidade e Estado) e clique em Ok. Exemplo:

Vamos agora, colocar o caminho a ser percorrido. Para isso, será necessário utilizar o método setPanel do directionsDisplay que irá definir a div que receberá o caminho percorrido em “initialize”, conforme abaixo:

function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();
    var mapOptions = {
    zoom:10,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
   map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
   directionsDisplay.setMap(map);
   directionsDisplay.setPanel(document.getElementById("directionsPanel")); // <---AQUI		  
}

Através do getElementById (linha 9) definimos o nome da div, que no caso é directionsPanel. Note que no código completo do html, temos em body uma div com esse nome.

Vamos pegar o total. Em calcRoute, devemos alterar directionsService.route:

directionsService.route(request, function(result, status) {
var distanciaTotal;
var i;
var etapa;
var rotas = result.routes[0];
var divTotal = document.getElementById('divTotal');

distanciaTotal = 0;

if (status == google.maps.DirectionsStatus.OK) {

  directionsDisplay.setDirections(result);

  for (i = 0; i < rotas.legs.length; i++)
  {
	etapa = rotas.legs[i];
	distanciaTotal += etapa.distance.value;
  }
  distanciaTotal = Math.round(distanciaTotal / 1000);
}

divTotal.innerHTML = '<br/><b>Distância Total: ' +
  distanciaTotal.toString() + '</b>';
  
});

Observações;

  • Foi adicionado algumas variáveis: distanciaTotal, rotas (para pegar todas etapas encontradas no percurso – legs), etapa (passo atual), divTotal (um alias para a div ‘divTotal’);
  • Através do loop, percorremos todas as etapas, somando a distância de cada etapa na variável distanciaTotal;
  • Por fim, inserimos o resultado na div ‘divTotal’.

Veja que, ao executar a aplicação e inserir nova rota, abaixo do mapa aparece o percurso e no rodapé aparece o total da distância:

Utilização de eventos

Finalmente chegamos na parte mais cobrada no post anterior: a alteração da rota clicando diretamente no mapa.

À primeira vista, pode-se achar que seja uma tarefa complicada. Porém, não é tão complicado assim, na verdade é bem simples graças a um recurso que a API nos oferece: os eventos!

No help, eventos está assim definido:

O JavaScript no navegador é orientado por eventos, ou seja, o JavaScript responde a interações gerando eventos e espera que um programa escute os eventos relevantes. O modelo de evento da API do Google Maps V3 é parecido com o usado na V2 da API, embora muita coisa tenha mudado em segundo plano. Há dois tipos de eventos:

Eventos de usuário (como eventos de “clique” do mouse) são propagados do DOM para a API do Google Maps. Esses eventos são separados e diferenciados dos eventos DOM padrão.
As notificações de alteração de estado do MVC refletem as alterações nos objetos da API do Google Maps e são nomeadas usando uma convenção property_changed

Cada objeto da API do Google Maps exporta vários eventos nomeados. Os programas interessados em determinados eventos registrarão escutas de evento do JavaScript para esses eventos e executarão o código quando esses eventos forem recebidos registrando manipuladores de evento addListener() no namespace google.maps.event. Desenvolvedores da v2 da API do Google Maps estarão familiarizados com esse uso.

O evento que nos interessa é o clique do mouse, onde iremos colher a posição (latitude/longitude) exata de onde o mapa recebeu o clique.

Na página google.html, antes de initialize, definimos 3 novas variáveis:

var endInicial = '';
var endFinal = '';
var way = '';

function initialize() {
...

Em initialize, após criar o objeto map, iremos inserir o código que irá ficar “escutando” o clique, google.maps.event.addListener: :)

function initialize() {
  directionsDisplay = new google.maps.DirectionsRenderer();
  var mapOptions = {
	zoom:10,
	mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  
  google.maps.event.addListener(map, 'click', function(event) {
    way = event.latLng;
    calcRoute(endInicial, endFinal, way);
   });
			
  directionsDisplay.setMap(map);
  directionsDisplay.setPanel(document.getElementById("directionsPanel"));		  
}

Agora, quando clicar no mapa, irá pegar a posição do clique e armazenar na variável way e depois, executar a função calcRoute (linha 11).

Em calcRoute, devemos fazer a seguinte alteração:

function calcRoute() {
    if ((endInicial != arguments[0]) || (endFinal != arguments[1])) {
	endInicial = arguments[0];
	endFinal = arguments[1];
	way = '';
   }
  var request = {
	origin:endInicial,
	destination:endFinal,
	travelMode: google.maps.TravelMode.DRIVING
   };		  
  if (way != '') {
    request.waypoints = [{location:way}]; 
  }
		  
  directionsService.route(request, function(result, status) {
...
  • Primeiro, verificamos se houve alteração na rota. Se sim, define endInicial e endFinal com os parâmetros passados na função;
  • A variável “way” será a responsável por definir a rota intermediária. Limpamos se houver alteração na rota;
  • A variável “request” continua da mesma forma;
  • Na linha 13, se way tem posição definida, então adiciona ao request um waypoints, que será a nossa rota intermediária. O “waypoints” é um array onde poderíamos passar vários pontos intermediários para se chegar ao endereço final da rota. Porém, neste artigo, estou passando apenas um waypoint.

Teste:

1- Após compilar e executar a aplicação, insira no endereço inicial ‘BALSAS, MA’ e no final ‘IMPERATRIZ, MA’. Clique OK.
2- O mapa será atualizado, com a rota passando por Carolina, MA.
3- Clique no mapa em cima de Grajaú, MA. Veja o resultado:

Resultado do percurso:

Mostrar a distância total em nossa aplicação

Para pegar a distância total, poderíamos obter o conteúdo de uma div, como por exemplo:

with web.Document as IHTMLDocument2 do
    with body.all as IHTMLElementCollection do
      with item('divTotal', 0) as HTMLDivElement do
        edDistancia.Text := innerText;

Porém, vou demonstrar como você pode pegar um valor de campo input, visto que nem sempre é interessante ter o resultado visível atrapalhando o layout da página. Eu sei, podemos ocultar uma div, ok! Mas para todos os efeitos, utilizaremos o input para pegar o total da dinstância da rota.

Em google.html, directionsService.route, abaixo de “distanciaTotal = Math.round(distanciaTotal / 1000);“, coloque:

  document.getElementById('inputTotal').value = distanciaTotal;

Estamos definindo o valor de um campo input chamado ‘inputTotal‘.

Agora, em body, insira o input:

<body style="overflow: hidden; width: 100%; height: 100%" onload="initialize()">
 <input type='hidden' id='inputTotal' value='' />
 <div id="map_canvas" style="width: 780px; height: 580px;"></div>
 <div id="directionsPanel"></div>
 <div id="divTotal"></div>
</body>

No Delphi, insira uma nova procedure:

procedure TfrmMain.PegaTotal;
begin
  try
    edDistancia.Text := GetElementIdValue(web, 'input', 'inputTotal', 'value') +
      ' Km';
  except
    // silêncio... 
  end;
end;

E uma nova function:

function TfrmMain.GetElementIdValue(WebBrowser: TWebBrowser;
  TagName, TagId, TagAttrib: string):string;
var
  Document: IHTMLDocument2;
  Body: IHTMLElement2;
  Tags: IHTMLElementCollection;
  Tag: IHTMLElement;
  I: Integer;
begin
  Result:='';
  if not Supports(WebBrowser.Document, IHTMLDocument2, Document) then
    raise Exception.Create('Documento HTML inválido');
  if not Supports(Document.body, IHTMLElement2, Body) then
    raise Exception.Create('Não foi possível encontrar o elemento <body>');
  Tags := Body.getElementsByTagName(UpperCase(TagName));
  for I := 0 to Pred(Tags.length) do
  begin
    Tag:=Tags.item(I, EmptyParam) as IHTMLElement;
    if Tag.id=TagId then Result := Tag.getAttribute(TagAttrib, 0);
  end;
end;

Basicamente, o que este método faz é percorrer o html em busca da “id” passada no parâmetro, retornando o valor da mesma.

No clique do botão Pega Total, coloque:

  PegaTotal;

E finalmente, no evento ONStatusTextChange do Webbrowser:

  StatusBar1.Panels[0].Text := Text;
  if Text = 'Concluído' then
    PegaTotal;

Chegamos ao final deste artigo. Baixe os fontes aqui.

Se gostou, clique em curtir abaixo.

Desenvolvedor de software desde 1995. Em 1998, abriu sua própria empresa, a Lukas Sistemas, desde então passou a atender diversas empresas, principalmente autopeças. Apaixonado por Delphi, porém não o impede de flertar com outras linguagens sempre que possível. Mora na cidade de Balsas/MA com sua esposa e dois filhos.

50 thoughts on “Delphi e Google Maps Javascript API V3 – Parte 2”

  1. Muitooo bom esse artigo..Puxa vida fiquei muito contente quando achei-o…
    Será que tem como você abordar como fazer modulos no delphi xe2, tipo chamar formularios de um bpl?

  2. Queria saber se é possivel quando eu traçar a rota mostra somente o resumo.
    Exemplo:

    A ) Rua Jaru – Carrão.
    0,7 km- cerca de 1 min.
    B ) Rua Lutécia – Carrão

    Sem o trajeto total. Tipo. Vire a esquerda e depois siga até.
    É possivel?

    Grato

    1. Olá Richard.

      Sim! Neste caso, você mesmo montaria o panel do percurso, em vez de setar o percurso no panel como foi feito no artigo:


      directionsDisplay.setPanel(document.getElementById("directionsPanel"));

      Da forma como está acima, foi definido o panel que receberá o percurso, e a própria API se encarrega de montar o html na div.

      Para o que você quer, seria algo muito parecido como o que foi feito para pegar o total, onde você percorreria todas etapas filtrando os resultados, mostrando apenas aquilo que você deseja. Ao pegar o resultado, você deverá montar o html de saída utilizando o innerHTML.

    1. O modo mais simples de se fazer isso é por meio do método innerText. Desta forma, você será capaz de buscar o conteúdo do html, como por exemplo o conteúdo de uma ‘div’.

      Coloque um novo botão e um memo no form. No clique do botão coloque:

        memo1.Clear;
        with web.Document as IHTMLDocument2 do
          with body.all as IHTMLElementCollection do
            with item('directionsPanel', 0) as HTMLDivElement do
            begin
              memo1.Lines.Add(innerText);
            end;
      

      Após gerar a rota, clique neste botão. Veja que o conteúdo da rota foi para o Memo. Utilizei o TMemo, visto que o retorno do innerText é um WideString.

      Caso seja realmente necessário colocar numa listbox, você pode criar uma variável Stringlist. Colocar o conteúdo da rota nesta variável e depois fazer um loop para percorrer todas as linhas da Stringlist e ir adicionando cada etapa à sua Listbox.

      1. Parabéns pelo post! muito bom, está me ajudando com meu trabalho da faculdade.
        Gostaria de perguntar uma coisa, essa variável “innerText” é alimentada aonde?

    1. No html, em inicializate, crie uma nova polyline:

      function initialize() {
      			var polylineOculta = {
      			strokeColor: '#F00000',
      			strokeOpacity: 0.0,
      			strokeWeight: 6
      			};	
      ...
      

      Na criação do directionsPanel, coloque a polyline criada acima:

      directionsDisplay = new google.maps.DirectionsRenderer({polylineOptions: polylineOculta});
      ...
      

      Pronto, como na criação da polyline passei opacidade zerada, a linha não aparece.

      Código completo da inicialização:

      function initialize() {
      			var polylineOculta = {
      			strokeColor: '#F00000',
      			strokeOpacity: 0.0,
      			strokeWeight: 6
      			};		
      		  directionsDisplay = new google.maps.DirectionsRenderer({polylineOptions: polylineOculta});
      		  var mapOptions = {
      			zoom:10,
      			mapTypeId: google.maps.MapTypeId.ROADMAP
      		  }
      		  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
      		  
      		  google.maps.event.addListener(map, 'click', function(event) {
      			  way = event.latLng;
      			  calcRoute(endInicial, endFinal, way);
      		    });
      			
      		  directionsDisplay.setMap(map);
                directionsDisplay.setPanel(document.getElementById("directionsPanel"));		  
      		}
      
      

      Abraços.

      1. blz, show de bola, so mais uma coisinha, eu quero passar as informações (endereços) logo no show,
        exemplo:

        with Web.Document as IHTMLDocument2 do
        parentWindow.execScript(‘calcRoute(“‘ + ‘Rua teste 614, Recife, Pernambuco’ + ‘”,”‘ +
        ‘Rua teste 2569, Recife, Pernambuco’ + ‘”)’, ‘javascript’);

        mas acontece um erro de script com a seguinte mensagem: O valor da propriedade ‘calcRoute’ é nulo ou não definido; não é um objeto de Funcao.

        O que devo fazer ?

          1. resolvi o problema de carregar no show.

            outra coisa, como tira a rota ? deixar so o mapa, deculpe pelo incomodo mas é por sou iniciante

  3. é eu sei o problema e que preciso disso pra hoje, e não estou conseguindo desenrolar, mas com certeza vou ler a documentação, mas se você poder me ajudar agrade muito

  4. Desculpe pela insistencia, lendo a documentao vi que poderia passar mais uma parametro na funcao calcRoute que seria um array com os outros endereços, que será usado na propriedade Waypoints,

    a minha duvidade é como passar esse parametro, Tentei dessa forma:

    with Web.Document as IHTMLDocument2 do
    parentWindow.execScript(‘calcRoute(“‘ + ‘Endereço 1 , Recife, pernabunco’ + ‘”,”‘ +
    ‘Endereco 2, Recife, Pernabuco’ + ‘”,”‘ + ‘[{Edereco 3, Recife, Pernabuco}’+ ‘”,”‘ + ‘{Endereco 4, Recife, Pernabuco}’ ‘”)’, ‘javascript’);

    mais não deu certo.

    então você poderia me ajudar como posso fazer isso ?

    1. Vamos lá… Primeiro, você deve entender que a função calcRoute que você viu não é a mesma que usei no exemplo, ou seja, calcRoute não é uma palavra reservada da API, mas sim uma função, onde você pode personalizar da forma que desejar.

      No meu exemplo, eu não uso um parâmetro array na chamada do método, mas sim, busco o way point no clique do mouse. Etendido?

      Outro ponto que deverá entender é que, um waypoint é um ponto por onde a rota deverá passar para chegar no destino… se é isto que você está querendo, bastará criar sua própria função com array de waypoints. Abaixo um exemplo.

      Vamos começar, alterando o calcRoute. Vamos tirar os parâmetros, endereço inicial e final, ficará da seguinte forma:

      	function calcRoute() {
      		  var pontos = new Array();
      				  
      		  var request = {
      			origin:arguments[0],
      			destination:arguments[1],
      			travelMode: google.maps.TravelMode.DRIVING
      		  };
      		  
      		  /* aqui, pegamos os waypoints, que começam em 2 porque o 0 e 1 são
      		     os endereços iniciais e finais
      		  */
      		  for(var i = 2; i < arguments.length; i++){
      		     pontos[i-2] = {location:arguments[i]};
      	      }
      			
      		  //adicionamos os pontos formatados aos waypoints	
                request.waypoints = pontos;
      		  
      		  
      		  directionsService.route(request, function(result, status) {
      		    var distanciaTotal;
      		    var i;
      		    var etapa;
        		    var rotas = result.routes[0];
      			var divTotal = document.getElementById('divTotal');
      			
        		    distanciaTotal = 0;
      			
      			if (status == google.maps.DirectionsStatus.OK) {
      			
         		      directionsDisplay.setDirections(result);
      
      			  for (i = 0; i < rotas.legs.length; i++)
      			  {
      				etapa = rotas.legs[i];
      				distanciaTotal += etapa.distance.value;
      			  }
      			  distanciaTotal = Math.round(distanciaTotal / 1000);
      			  document.getElementById('inputTotal').value = distanciaTotal;
      			}
      			
      			divTotal.innerHTML = '<br/><b>Distância Total: ' +
      			  distanciaTotal.toString() + '</b>';
      			  
      		  });
      		}
      

      Através do array de argumentos “arguments”, eu pego o endereço inicial (0) e o final (1). Depois faço um loop, para pegar os waypoints.

      No Delphi, altere a chamada da função calcRoute:

      procedure TfrmMain.Button1Click(Sender: TObject);
      var
         JSFn: string ;
      begin
        if (Trim(edEnd1.text)='') or (Trim(edEnd2.text)='') then exit;
      
        JSFn := Format( 'calcRoute("%s","%s","%s", "%s", "%s")' ,
          [edEnd1.text, edEnd2.text, 'Carolina, MA', 'Araguaína, TO', 'Araguatins, TO']);
      
         with Web.Document as IHTMLDocument2 do
           parentWindow.execScript(JSFn, 'JavaScript' );
      end ;
      

      Assim, posso passar quantos waypoints eu desejar.

      Resultado:
      waypoints

      É isso, Paulo?

  5. passe o script depois de formatado dessa forma:

    calcRoute(“RUA TIBURCIO CAVALCANTE 2469,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 124,FORTALEZA,CE”,”RUA CONRADO CABRAL 5445,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 154,FORTALEZA,CE”,”RUA CONRADO CABRAL 5445,FORTALEZA,CE”,”RUA EDUARDO GARCIA 548,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 548,FORTALEZA,CE”,”RUA FREI VIDAL 845,FORTALEZA,CE”,”RUA EDUARDO GARCIA 154,FORTALEZA,CE”,”RUA FREI VIDAL 124,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 185,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 154,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 124,FORTALEZA,CE”,”RUA PERO COELHO 1234,Fortaleza,CE”,”RUA PADRE LUIS FIGUEIRA 215,FORTALEZA,CE”,”RUA EDUARDO GARCIA 1542,FORTALEZA,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,”TESTE 4,FORTALEZA,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22652,FORTALEZA/CE,CE”,”RUA CAPITAO GUSTAVO 9878,FORTALEZA,CE”,”RUA CAPITAO GUSTAVO 9878,FORTALEZA,CE”,”TESTE 1,FORTALEZA,CE”,”AV SANTOS DUMONT 22316,FORTALEZA/CE,CE”,”R SILVA PAULET 21980,FORTALEZA/CE,CE”,”RUA CAPITAO GUSTAVO 9878,FORTALEZA,CE”,”AV ROGACIANO LEITE 29516,FORTALEZA/CE,CE”,”R ANA BILHAR 29708,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22316,FORTALEZA/CE,CE”,”R SILVA PAULET 22268,FORTALEZA/CE,CE”,”RUA CAPITAO GUSTAVO 9878,FORTALEZA,CE”,”AV ROGACIANO LEITE 29516,FORTALEZA/CE,CE”,”R ANA BILHAR 29708,FORTALEZA/CE,CE”,”R SILVA PAULET 28412,FORTALEZA/CE,CE”,”R SILVA PAULET 27740,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22316,FORTALEZA/CE,CE”,”R SILVA PAULET 23948,FORTALEZA/CE,CE”,”RUA CAPITAO GUSTAVO 9878,FORTALEZA,CE”,”AV ROGACIANO LEITE 29516,FORTALEZA/CE,CE”,”R ANA BILHAR 29708,FORTALEZA/CE,CE”,”AV SANTOS DUMONT 22316,FORTALEZA/CE,CE”,”R SILVA PAULET 20636,FORTALEZA/CE,CE”,”RUA FREI MARCELINO 177,FORTALEZA,CE”,”ENDERECO 12,FORTALEZA,CE”,”RUA CONRADO CABRAL 788,FORTALEZA,CE”,”RUA DOS COQUEIROS 182,AQUIRAZ,CE”,”RUA DOS COQUEIROS 182,AQUIRAZ,CE”,”RUA FREI MARCELINO 177,AQUIRAZ,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,”RUA FREI MARCELINO 177,FORTALEZA,CE”,”TESTE 10,TESTE,CE”,”RUA FREI VIDAL 845,FORTALEZA,CE”,”RUA CONRADO CABRAL 788,FORTALEZA,CE”,”RUA PADRE LUIS FIGUEIRA 845,FORTALEZA,CE”,”RUA FREI MARCELINO 177,FORTALEZA,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,”RUA FREI MARCELINO 177,FORTALEZA,CE”,”RUA DAS TANTAS CONDADO 13,FORTALEZA,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,”RUA TIBURCIO CAVALCANTE 2569,FORTALEZA,CE”,” ,FORTALEZA,CE”,”TESTE 10,TESTE,CE”,”TESTE 10,TESTE,CE”,” ,FORTALEZA,CE”)’

  6. O que você tem que ter em mente é que, ao utilizar waypoints, com base na função calcRoute que lhe passei, nos argumentos o primeiro e o segundo endereços deve ser o início e o final da rota. Os demais endereços devem ser pontos por onde a rota deve passar.

    1. Acho que entendi o que você está querendo: marcar apenas os pontos no mapa.

      Neste caso, traçar rotas não é o mais indicado. Estou de saída agora para uma viagem, mas quando voltar, coloco aqui alguma coisa referente ao que você está querendo.

        1. Antes de mais nada parabéns Luiz pelo Blog, pela disposição em ajudar e principalmente por esse brilhante artigo.
          Coincidentemente minha necessidade é a mesma do Paulo Roberto, marcar “N” pontos no mapa.
          Parcialmente vou usar a solução dos waypoints sem a linha de rota, mas quando fosse possível, seria perfeito aprender a maneira mais correta de fazer isso.
          Obrigado e sucesso.

  7. Tenho uma outra dúvida, não sei se aconteceu com algum de vocês que baixou o fonte desse exemplo.
    Quando eu executo tanto pelo Delphi quanto pelo .exe ele abre o programa mas no OnClick do botão “OK”
    ‘Acesso Negado.”
    na linha parentWindow.execScript(JSFn, ‘JavaScript’ );

    O problema é que não existe nenhuma restrição nos diretório no meu computador, inclusive tentei jogar a pasta pro C:\. Meu usuário é administrador, já verifiquei propriedades de segurança e não tem nada disso.
    Uso Windows XP, alguém passou por isso?

    1. Olá Guilherme

      o Google.html está no mesmo diretório da aplicação? Se sim, realmente não sei o que pode estar acontecendo. Atualmente, estou com o Windows 7 e na época em que fiz o artigo, utilizava o Windows XP. Em ambos funcionou sem problemas.

      1. Deve ser culpa da “Lei de Murphy”…
        O arquivo está sim no mesmo diretório da aplicação e acredito não ser problema com o carregamento do arquivo, pois o problema é só no momento de enviar o comando JavaScript (OnClick do botão).

        De qualquer forma muito obrigado pela resposta.
        (Apropósito, caso eu abra direto o arquivo google.html o mapa deveria aparecer? Porque no meu caso quando ele abre pelo Chrome e fica um quadrado cinza no lugar do mapa, acredito que seja por não estar passando os parâmetros de EndInicial e EndFinal, ou não?)

        1. Da forma que eu fiz, o mapa só irá aparecer após clicar no botão. Eu poderia já entrar no mapa quando executada a aplicação.

          No momento estou sem tempo, mas assim que possível, posso dar uma olhada nisso.

  8. O Codigo
    with WebBrowser1.Document as IHTMLDocument2 do
    with body.all as IHTMLElementCollection do
    with item(‘divTotal’, 0) as HTMLDivElement do
    edDistancia.Text := innerText;

    Nao traz o valor para o campo. o que fazer

  9. Bom dia,
    Me interessei muito por este artigo e gostaria muito do fonte, tentei baixar mais deu erro, será que tem como me enviar por e-mail?

    Aguardo retorno

  10. Olá Luiz Carlos, estou com um problema para aumentar o zoom do mapa automaticamente em um guia comercial que estou trocando o maps do v2 para o v3, quando existem marcadores fora dos limites do zoom. Um exemplo é o do script http://br.ai/maps/ onde eu fiz um exemplo do problema que tenho (veja o script para visualizar como estou usando o maps v3). Tenho definido um zoom defaut para casos de não retornar nenhum endereço e o mapa esta com zoom de 15, mas quando existem vários marcadores e alguns deles ficaram para fora dos limites do zoom defaut no v2 eu tinha uma função que ajustava os limites mas no v3 não achei em lugar nenhum esta função, por isso agradeceria muito se você me desse uma luz.

  11. Luiz, parabéns pelo seu site, show de bola. Este artigo então, está ajudando mtas pessoas, inclusive a mim. Como eu poderia apenas marcar diversos pontos no mapa, sem a necessidade da rota? Não entendo mto de javascript, mas estou precisando recuperar no delphi as coordenadas desses pontos plotados para então armazenar no banco de dados. Obrigado e mais uma vez, parabéns!

  12. Ola Luiz…
    vi seu site a tempos atras e consegui fazer muitas coisas, mas tive que parar meu projeto e agora vou tentar reativar esse projeto…. vc saberia me dizer como faço para pegar dados do GPS (tanto de celular quanto um para controle de carros) ou outro e jogar para que fique um controle online de um veículo mostrando no mapa? ou algo que me indique como faça isso?
    Fico agradecido por alguma indicação…
    Obrigado

  13. muito bom esse exemplo Luiz, baixei aqui e testei e funcionou tranquilo, ainda sou iniciante em delphi mas me viro bem rsrs porem tenho uma duvida: é possível colocar este codigo dentro de uma dll? assim eu poderia por exemplo programar a dll em delphi mas usar num programa em C# por exemplo, afinal esse é o objetivo das dll certo? serem usadas por qualquer programa feito em qualquer linguagem

    obrigado e fico no aguardo…

    1. duas coisas: no caso da duvida do paulo em que você adiciona pontos dentro da roda diretamente no código, teria como fazer isso no clique do mouse? exemplo: dou origem e destino da rota mas clico numa ou mais cidades no meio do caminho. percebi que ele já faz isso porem só para 3 pontos. E como eu colocaria para iniciar já com o mapa mostrando em cima do brasil como no seu exemplo anterior?
      obrigado

      1. Primeiro, é necessário que se entenda o seguinte: o exemplo proposto é apenas uma introdução, limitada, e que demonstra apenas algumas funções e métodos da API. E esta é bem mais abrangente do que o que foi visto aqui. Portanto, a partir do exemplo, procure entender sobre os eventos e a marcação dos pontos no mapa e daí gerar suas próprias soluções.

        Mostrei como iniciar. Agora, é com vocês! Explorem a API e entendam como o framework pode ajudá-los a manipular os mapas da forma que desejarem.

    1. Olá

      Eu atualizei o link no post e agora está ok.

      Só lembrando que este arquivo data de 29/09/2012. Ou seja, muita coisa foi implementada na API do Google de lá pra cá e pode ser que o código não funcione como antes. Portanto, sugiro que entre no site do Google e se atualize.

    1. Olá

      Eu atualizei o link no post e agora está ok.

      Só lembrando que este arquivo data de 29/09/2012. Ou seja, muita coisa foi implementada na API do Google de lá pra cá e pode ser que o código não funcione como antes. Portanto, sugiro que entre no site do Google e se atualize.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.