The Road to Delphi – a Blog about programming

Delphi – Free Pascal – Oxygene

Using the Google Maps API V3 from Delphi – Part I Basic functionality

52 Comments

The Google Maps Javascript API Version 2 has been officially deprecated, so it’s time to update to the new version 3, this post shows how you can use the new Google maps V3 API from Delphi.

in this sample application you can use the traffic layer , Bicycling layer and the street View Control to activate the panorama view.

for additional info about the Google maps api v3 you can check these links.


Check the next full commented sample application written in Delphi 2007, the source code is available in this location

unit fMain;

interface 

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, OleCtrls, SHDocVw, StdCtrls, ExtCtrls, XPMan, ComCtrls,MSHTML;

type
  TfrmMain = class(TForm)
    WebBrowser1: TWebBrowser;
    LabelAddress: TLabel;
    PanelHeader: TPanel;
    ButtonGotoLocation: TButton;
    XPManifest1: TXPManifest;
    MemoAddress: TMemo;
    ButtonGotoAddress: TButton;
    LabelLatitude: TLabel;
    LabelLongitude: TLabel;
    Longitude: TEdit;
    Latitude: TEdit;
    CheckBoxTraffic: TCheckBox;
    CheckBoxBicycling: TCheckBox;
    CheckBoxStreeView: TCheckBox;
    procedure FormCreate(Sender: TObject);
    procedure ButtonGotoAddressClick(Sender: TObject);
    procedure ButtonGotoLocationClick(Sender: TObject);
    procedure CheckBoxTrafficClick(Sender: TObject);
    procedure CheckBoxBicyclingClick(Sender: TObject);
    procedure CheckBoxStreeViewClick(Sender: TObject);
  private
    { Private declarations }
    HTMLWindow2: IHTMLWindow2;
  public
    { Public declarations }
  end;

var
  frmMain: TfrmMain;

implementation

uses
   ActiveX;

{$R *.dfm}

const
HTMLStr: String = //i put The code for the web page page wich load the google maps in a string const, you can use an external html file too or embed the page in a resource and then load in a stream
'<html> '+
'<head> '+
'<meta name="viewport" content="initial-scale=1.0, user-scalable=yes" /> '+
'<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script> '+
'<script type="text/javascript"> '+
''+
''+//Declare the globals vars to be used in the javascript functions
'  var geocoder; '+
'  var map;  '+
'  var trafficLayer;'+
'  var bikeLayer;'+
''+
''+
'  function initialize() { '+
'    geocoder = new google.maps.Geocoder();'+
'    var latlng = new google.maps.LatLng(40.714776,-74.019213); '+ //Set the initial coordinates for the map
'    var myOptions = { '+
'      zoom: 13, '+
'      center: latlng, '+
'      mapTypeId: google.maps.MapTypeId.ROADMAP '+ //Set the default type map
'    }; '+
'    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); '+
'    trafficLayer = new google.maps.TrafficLayer();'+ //Create the traffic Layer instance
'    bikeLayer = new google.maps.BicyclingLayer();'+ //Create the Bicycling Layer instance
'  } '+
''+
''+
'  function codeAddress(address) { '+ //function to translate an address to coordinates and put and marker.
'    if (geocoder) {'+
'      geocoder.geocode( { address: address}, function(results, status) { '+
'        if (status == google.maps.GeocoderStatus.OK) {'+
'          map.setCenter(results[0].geometry.location);'+
'          var marker = new google.maps.Marker({'+
'              map: map,'+
'              position: results[0].geometry.location'+
'          });'+
'        } else {'+
'          alert("Geocode was not successful for the following reason: " + status);'+
'        }'+
'      });'+
'    }'+
'  }'+
''+
''+
'  function GotoLatLng(Lat, Lang) { '+ //Set the map in the coordinates and put a marker
'   var latlng = new google.maps.LatLng(Lat,Lang);'+
'   map.setCenter(latlng);'+
'   var marker = new google.maps.Marker({'+
'      position: latlng, '+
'      map: map,'+
'      title:Lat+","+Lang'+
'  });'+
'  }'+
''+
''+
'  function TrafficOn()   { trafficLayer.setMap(map); }'+ //Activate the Traffic layer
''+
'  function TrafficOff()  { trafficLayer.setMap(null); }'+
''+''+
'  function BicyclingOn() { bikeLayer.setMap(map); }'+//Activate the Bicycling layer
''+
'  function BicyclingOff(){ bikeLayer.setMap(null);}'+
''+
'  function StreetViewOn() { map.set("streetViewControl", true); }'+//Activate the streeview control
''+
'  function StreetViewOff() { map.set("streetViewControl", false); }'+
''+
''+'</script> '+
'</head> '+
'<body onload="initialize()"> '+
'  <div id="map_canvas" style="width:100%; height:100%"></div> '+
'</body> '+
'</html> ';

procedure TfrmMain.FormCreate(Sender: TObject);
var
  aStream     : TMemoryStream;
begin
   WebBrowser1.Navigate('about:blank'); //Set the location to an empty page
    if Assigned(WebBrowser1.Document) then
    begin
      aStream := TMemoryStream.Create; //create a TStem to load the Page from the string
      try
         aStream.WriteBuffer(Pointer(HTMLStr)^, Length(HTMLStr)); //Copy the string to the stream
         //aStream.Write(HTMLStr[1], Length(HTMLStr));
         aStream.Seek(0, soFromBeginning);
         (WebBrowser1.Document as IPersistStreamInit).Load(TStreamAdapter.Create(aStream));//Load the page from the stream
      finally
         aStream.Free;
      end;
      HTMLWindow2 := (WebBrowser1.Document as IHTMLDocument2).parentWindow; //Set the instance of the parentWindow to call the javascripts functions
    end;
end;

procedure TfrmMain.ButtonGotoLocationClick(Sender: TObject);
begin
   HTMLWindow2.execScript(Format('GotoLatLng(%s,%s)',[Latitude.Text,Longitude.Text]), 'JavaScript');//Call the function GotoLatLng to go the coordinates
end;

procedure TfrmMain.ButtonGotoAddressClick(Sender: TObject);
var
   address    : string;
begin
   address := MemoAddress.Lines.Text;
   address := StringReplace(StringReplace(Trim(address), #13, ' ', [rfReplaceAll]), #10, ' ', [rfReplaceAll]);
   HTMLWindow2.execScript(Format('codeAddress(%s)',[QuotedStr(address)]), 'JavaScript');//Call the function codeAddress to go the address
end;

procedure TfrmMain.CheckBoxStreeViewClick(Sender: TObject);
begin
    if CheckBoxStreeView.Checked then
     HTMLWindow2.execScript('StreetViewOn()', 'JavaScript') //Activate the Street View option
    else
     HTMLWindow2.execScript('StreetViewOff()', 'JavaScript');//Deactivate the Street View option

end;

procedure TfrmMain.CheckBoxBicyclingClick(Sender: TObject);
begin
    if CheckBoxBicycling.Checked then
     HTMLWindow2.execScript('BicyclingOn()', 'JavaScript')//Activate the Bicycling View option
    else
     HTMLWindow2.execScript('BicyclingOff()', 'JavaScript');//Deactivate the Bicycling View option
 end;

procedure TfrmMain.CheckBoxTrafficClick(Sender: TObject);
begin
    if CheckBoxTraffic.Checked then
     HTMLWindow2.execScript('TrafficOn()', 'JavaScript')//Activate the Traffic View option
    else
     HTMLWindow2.execScript('TrafficOff()', 'JavaScript');//Deactivate the Traffic View option
 end;

end.
About these ads

Author: Rodrigo

Just another Delphi guy.

52 thoughts on “Using the Google Maps API V3 from Delphi – Part I Basic functionality

  1. Any thoughts on how to get travel distance between 2 locations?

  2. Being pretty terrible in javascript and I sometimes wonder about my abilities in Delphi, I know that when one views maps.google.com and then enters;

    void(prompt(”,gApplication.getMap().getCenter()))

    One will retrieve the latitude and longitude of the center of the shown map.

    Played with this in Delphi and your sample code, and cannot get it towork. Ideally, it would be GREAT to show the lat and long in the tEdits in the form. Can any of this be done?

    Thanks for the tutorial! Nice to start learning this stuff!

    John J

  3. Thank you for this code,
    I use delphi 2009 and I get a java script error when I run the program after I compile it.
    Could you please help me ?
    Do you already test you code with delphi 2009 ?
    Thank you ,

  4. Thanks a lot!

  5. Run this code in Delphi2009

    try changing this line
    HTMLStr: String =
    to
    const HTMLStr :UTF8String =

  6. Pingback: Anonymous

  7. Estimado, como siempre muy buenos artículos.

    Le cuento, por cada búsqueda sale un marcador. ¿Como puedo eliminar o los marcadores anteriores en cada búsqueda o hacer que solo se muestre el último?.

    De antemano muchas gracias

    • MAXIUM, acabo de actualizar el proyecto . si lo descargas ahora podras ver que tienes la opcion “clear markers”, que limpia los marcadores de la pantalla. basicamente lo que se hace (en javascript) es crear una variable global (de tipo array) que contiene los marcadores y cuando se presiona el boton antes mencionado se limpia la variable, lo que hace desaparacer los marcadores. espero que te sirva.

      Saludos.

  8. Hi,
    Good job and keep it up.
    Trying to run the code and I got error of TwebBrowser is not found. Where can I find TwebBrowser component?

    • Ade, which version of delphi are you using? the TWebBrowser component is a standard component included in the internet palette and is part of the SHDocVw unit.

      • Rodrigo, Thanks for your response. I am using Delphi XE Stater. Now It seem like there is limitation of those components on Starter version.

  9. Rodrigo, Thanks for your response. I am using Delphi XE Stater. Now It seem like there is limitation of those components on Starter version.

    Rodrigo :
    Ade, which version of delphi are you using? the TWebBrowser component is a standard component included in the internet palette and is part of the SHDocVw unit.

    Rodrigo, Thanks for your response. I am using Delphi XE Stater. Now It seem like there is limitation of those components on Starter version.

  10. Delphi 7 personnal.
    Have installed TWebBrower component but no way to find the needed dcu.
    Just have emailed u
    Thanks

  11. Hi Rodrigo,

    Thank you for the excellent tutorial. I am using Delphi 2010, there was an complication error at HTMLWindow2.execScript(). but it is fixed by edit code HTMLStr: String = to const HTMLStr :UTF8String

  12. Nice tutorial … thanks.

    I’ve noticed that the street view no longer works. (I think google has pushed a new version)
    Any idea how to fix it?
    I’ve been trying to add the doctype tag to the html, but still no joy.

  13. Great sample Thx!!, Works fine on Delphi 7 :D

  14. Any news about how to get distance between two adress and how to display marquers on the google map in Delphi ????

  15. Hi, seems to be a great application. Any idea how to convert a mouse click on the map into corresponding coordinates ? i.e. longitude and latitude of the point clicked ?

  16. Hi all,
    For “Delphi7 users like me”, you simply make a little modification in the projects source “GoogleMapsTest.pas” :

    program GoogleMapsTest;

    uses
    Forms,
    fMain in ‘fMain.pas’ {frmMain};

    {$R *.res}

    begin
    Application.Initialize;

    //Begin
    //Remove -or comment- the following line
    Application.MainFormOnTaskbar := True;
    //End

    Application.CreateForm(TfrmMain, frmMain);
    Application.Run;
    end.

  17. It’s Great!!!

    I like it!

    Thanks a lot!

  18. Nice tutorial!

  19. hi
    Please send me source code (*.dpr — *..dproj) in email address
    Please Hint me …

  20. hi !

    this is a great code. i am using delphi 7 Ent. Everything is running fine except one minor – big problem. i try to automatically go to an address (lat,lon) that is saved in a database, when the user opens a form with the map. When i use the code on ButtonGotoLocationClick on a Button, it is ok. when i try to do the same e.g. on a tab change, i get an error 80020101. anyone knows why?

  21. Hi Rodrigo,

    Hope you are planning to start using XE2.

  22. Pingback: /*Prog*/ Delphi-Neftalí /*finProg*/ » Una quincena más… (11/04/2012)

  23. Thanks for this series of tutorials; they really help to explain the Delphi/Google workings. I have it running in both D7 and D5 (only three modifications). A question about clearing all the markers: After clearing, then adding a new marker, the sequence number starts at the highest previous number. Is there any way to initialize the marker to “number 1″ after clearing? Thanks for any help.

  24. Rodrigo ante todo muy bueno lo tuyo, una consulta cuando agrego los marcadores le el titulo del mismo solo se ve con un hint , como se puede hacer para que aparesca como una etiqueta como esta en el earth.

    Saludos.

  25. Hello Rodrigo
    Any idea about using this wonderful tool behind a firewall.
    What would be the entries (sites, URLs) to open on the firewall ?

  26. This code compiled cleanly under EX2.

  27. Nice info and thanks for sharing, how about if i click the map it will give a location in a textfield?

  28. works for delphi xe5, thank you very much.

  29. The link for the source code no longer works

  30. Hi Rodrigo,

    great stuff, thx for great help.

    I have a question: Do you have the same example for Delphi-firemonkey? I tried to use some code-snippets in firemonkey, but obviously I failed in converting the code to fmx-code.

    Thx a lot and

    best wishes from Germany,

    Lars

  31. I’ll right away seize your rss feed as I can not to find
    your email subscription hyperlink or e-newsletter
    service. Do you have any? Please allow me recognize in order
    that I could subscribe. Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 704 other followers