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.
- Google Maps JavaScript API V3
- The Google Maps Javascript API V3 – Basics
- Google Map Javascript API V3 – Map Types
Check the next full commented sample application written in Delphi 2007, the source code is available on Github
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.
August 7, 2010 at 11:32 pm
nice, thank you!
August 8, 2010 at 3:45 pm
Any thoughts on how to get travel distance between 2 locations?
August 9, 2010 at 6:02 pm
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
August 14, 2010 at 5:51 pm
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 ,
August 14, 2010 at 6:47 pm
solux, the code was writen and tested in Delphi 2007, you must make only one small change to run this code in delphi 2009.
try changing this line
HTMLStr: String =
to
const HTMLStr :AnsiString =
August 15, 2010 at 1:53 pm
Hi Rodrigo,
Thanks a lot ! it work’s yet.
August 19, 2010 at 5:34 pm
Thanks a lot!
August 24, 2010 at 3:38 am
Run this code in Delphi2009
try changing this line
HTMLStr: String =
to
const HTMLStr :UTF8String =
Pingback: Anonymous
January 19, 2011 at 9:24 pm
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
January 19, 2011 at 10:19 pm
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.
January 20, 2011 at 11:16 am
Grandioso, excelente, que más decir.
Muchas gracias.
February 23, 2011 at 5:03 pm
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?
February 23, 2011 at 8:39 pm
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.
February 24, 2011 at 6:02 pm
Rodrigo, Thanks for your response. I am using Delphi XE Stater. Now It seem like there is limitation of those components on Starter version.
February 24, 2011 at 6:04 pm
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, Thanks for your response. I am using Delphi XE Stater. Now It seem like there is limitation of those components on Starter version.
March 17, 2011 at 6:54 am
Very nice app.
Don’t manage to compile it as ShDocvw.dcu and MSHTML.dcu are not found. Ideas where to compile/get it ?
Otherwise, i would like to inject instamapper datas. Ideas how to do it ?
Thanks alot
March 17, 2011 at 10:45 am
Gwenael, which version of delphi are you using?
March 17, 2011 at 11:00 am
Delphi 7 personnal.
Have installed TWebBrower component but no way to find the needed dcu.
Just have emailed u
Thanks
March 26, 2011 at 10:18 am
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
May 4, 2011 at 4:53 am
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.
May 4, 2011 at 1:56 pm
Mark, thanks for your comments, i just test the application and the street view works ok (the checkbox only show or hide the icon to activate the street view, you must drag and drop the person icon in the map to activate the street view), I made to a small change to the source code in order to deactivate the street view when the the application starts. try downloading again the source code, test and let me know the results.
May 17, 2011 at 5:39 am
This is a bug in the Google Maps API (http://code.google.com/p/gmaps-api-issues/issues/detail?id=3272). See also article http://www.delphipraxis.net/1099848-post48.html (in German).
May 25, 2011 at 11:55 pm
Great sample Thx!!, Works fine on Delphi 7 :D
June 9, 2011 at 11:46 am
Any news about how to get distance between two adress and how to display marquers on the google map in Delphi ????
June 9, 2011 at 3:20 pm
try these links
Google Maps Javascript API V3 Geometry Library
Finding the distance between two points using the Google Maps API v3
June 24, 2011 at 11:59 am
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 ?
June 24, 2011 at 9:33 pm
I just wrote a new post about this check this link https://theroadtodelphi.wordpress.com/2011/06/24/using-the-google-maps-api-v3-from-delphi-%E2%80%93-part-iii-getting-the-latitude-and-longitude-of-a-mouse-click/
June 26, 2011 at 8:06 pm
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.
August 29, 2011 at 5:54 am
It’s Great!!!
I like it!
Thanks a lot!
November 19, 2011 at 3:24 am
Nice tutorial!
November 23, 2011 at 1:46 am
hi
Please send me source code (*.dpr — *..dproj) in email address
Please Hint me …
November 23, 2011 at 1:29 pm
The full source code is located here http://dl.dropbox.com/u/12733424/Blog/GoogleMapsTest.rar
December 5, 2011 at 3:43 pm
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?
December 22, 2011 at 4:34 am
MANTAP PISAN EUY, THANK U
December 30, 2011 at 4:07 am
Hi Rodrigo,
Hope you are planning to start using XE2.
Pingback: /*Prog*/ Delphi-Neftalí /*finProg*/ » Una quincena más… (11/04/2012)
June 8, 2012 at 2:29 pm
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.
January 24, 2013 at 8:16 am
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.
January 30, 2013 at 3:55 pm
Hola Marcelo, me puedes dar un ejemplo (imagen) de lo que deseas realizar?
February 5, 2013 at 7:29 am
Hello Rodrigo
Any idea about using this wonderful tool behind a firewall.
What would be the entries (sites, URLs) to open on the firewall ?
September 13, 2013 at 2:05 am
This code compiled cleanly under EX2.
November 7, 2013 at 12:55 am
Nice info and thanks for sharing, how about if i click the map it will give a location in a textfield?
November 7, 2013 at 10:29 am
Try this article Using the Google Maps API V3 from Delphi – Part III Getting the latitude and longitude of a mouse click
November 8, 2013 at 8:58 am
thanks for the reply but this one is giving a latlon when mouse is being clicked, how about the location or what i mean was the address name?
February 20, 2014 at 12:17 pm
works for delphi xe5, thank you very much.
May 15, 2014 at 2:39 pm
The link for the source code no longer works
May 23, 2014 at 8:37 pm
The link was restored.
June 11, 2014 at 11:31 am
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
July 7, 2014 at 9:55 pm
Sorry, but for now I don’t have a Firemonkey equivalent of this code.
June 12, 2014 at 3:42 am
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.
June 13, 2014 at 1:50 pm
Check the FOLLOW BLOG VIA EMAIL option in the right bar of the blog.
November 14, 2014 at 6:53 am
Hello my friend, thank you very much! I was wondering if you can print the map you see??? can you do that? can you take a screen shot from delphi like a e.g png or jpeg?? I would appreciate, thank you very much
November 14, 2014 at 10:19 am
You can invoke the print command directly from the TWebBrowser component like so
February 18, 2015 at 6:16 am
Heya!
Broken since today (GMT+1)….
Looks like there was something changed on the google side regarding the map-object?
Chrome and IE 10+ are loading/initializing the external google scripts still fine, but the TWebbrowser component has problems, throwing an “property display not found bablabla” error.
Could it be anychronous loading the TWebbrowser cannot handle?
Greeting from Germany
Richard
February 18, 2015 at 6:26 am
PS.:
Just found out that the external script version 3.3 is working flawlessly:
http://maps.googleapis.com/maps/api/js?v=3.9&sensor=false
Beginning with version 4.0 the comp is broken for Delphi.
Cheers,
Richard
March 13, 2015 at 1:15 am
Can you explain ? because I just tested the sample exe and the code and works fine. (Win 8.1, IE 11)
February 19, 2015 at 5:33 am
I’m using your code in one application since 2 years but now we are getting Javascript errors and the map is not loaded.
Can you verify?
March 13, 2015 at 1:13 am
I just tested the sample exe and the code and works fine (Win 8.1, IE 11)
March 4, 2015 at 8:58 pm
Qué tal Rodrigo, excelente información para compartir. Aprovechando de tu conocimiento, es posible que una vez que le de una dirección pueda obtener los datos de Latitud y Longitud en Delphi para poder guardar esa información y en el futuro utilizarla en vez de la dirección ?, de antemano gracias.
March 13, 2015 at 1:23 am
Hola Hector, En este articulo explico como obtener los valores de las coordenadas desde javascript.
March 13, 2015 at 2:38 pm
Muchas gracias Rodrigo, con este ejemplo pude resolver mi duda. Saludos.
May 15, 2015 at 10:41 am
Primera vez que veo tu página, me bajé el código, lo cargué en XE/Win7, compiló y ejecutó con cero error a la primera. Impresionante. Gracias.
June 2, 2015 at 1:21 pm
Thank you Very much
August 6, 2015 at 10:58 pm
Uaaauuuu… Muito bom! Parabéns!
October 14, 2015 at 10:26 am
Can get example (( – 404
October 14, 2015 at 11:14 am
The source code now is hosted on Github https://github.com/RRUZ/blog/tree/master/Google/Maps/Google%20Maps%20Basic%20Sample
October 14, 2015 at 3:37 pm
Hi Rodrigo,
Some weeks ago I sent you a message for telling you that it seems that there is a problem with the StreetView option in your GoogleMaps in Delphi program: the close button doesn’t appear anymore. But I think you delete my message because I have not seen it here.
Now I have a more serious problem: the window where GoogleMaps must appear remains empty… I also tried your “GoogleMapsTest.exe” on various computer and it is the same everywhere…
Could you do something to help please? I use your powerful code for a long time but now have these problems.
Thank you very much!
October 19, 2015 at 3:54 pm
Juliann, this is an issue related to the rendering mode used by the TWebBrowser control, I just updated the project hosted on Github to fix this https://github.com/RRUZ/blog/tree/master/Google/Maps/Google%20Maps%20Basic%20Sample, for more info read this https://code.google.com/p/gmaps-api-issues/issues/detail?id=8750.
the workaround is add the v=3 parameter in the script tag.
October 19, 2015 at 4:44 pm
Thank you very much!
December 25, 2015 at 5:57 pm
Rodrigo,
Sorry to come once more with the same kind of issue but it seems that an error message appears once again even with the v=3 parameter when choosing the streetview frame.
Any idea?
Thank you in advance.
December 30, 2015 at 11:12 pm
Hi, I just tried the sample hosted on github and works just fine. If you are experiencing some problems you can report the issue on the issue page attaching the error which appears.
February 21, 2016 at 5:33 pm
Hi Rodrigo,
I answer only now but the proble still remains, with this error:
“Script error. URL: http://maps.google.com/maps-api-v3/api/js/23/7/intl/fr_ALL/onion.js”
I see on the internet that other softwares meet the same problem (see for example http://faq.pcsoft.fr/12194-faq-read.awp, in french. It is exactly the same error…).
PCSoft says that this error message coud be due to the fact that Google forbids some request depending on its “origin” (I don’t know what it means…)
PCSoft says than “il faut donc configurer l’ActiveX de Internet Explorer pour que les requêtes envoyées soient identifiées comme provenant de Internet Explorer 11″
In English: The Internet Explorer ActiveX must be configured in a way that the sent request are identified as sent from Internet Explorer 11” I use the TWebBrowser component in Delphi XE7.
Do you have an idea?
I report the same text on github.
Thank you.
Juliaan.
February 21, 2016 at 5:57 pm
Rodrigo,
It seems that with v=3.22, it runs (excepted the little problem to close the Street view window).
Juliaan.
Pingback: Important Note about using the Google Maps API from Desktop Apps | The Road to Delphi
October 4, 2016 at 2:08 pm
Rodrigo,
Es posible guardar la imagen del mapa en un archivo jpg , que uno le pueda asignar a las variables el folder donde se va a guardar y el nombre del archivo, de tal manera que no aparezca la caja de diaalogo. De antemano gracias por la atención que des al presente. Saludos
Fernando Vasquez
October 4, 2016 at 2:39 pm
Hola, un par de opciones, puedes guardar una imagen del TWebBrowser usando la funcion BitBlt y el Canvas del control. o bien puedes usar la API Google Static Maps.
October 4, 2016 at 3:59 pm
Rodrigo,
Gracias me funciono utilizando la función BitBlt
Saludos
Fernando Vasquez
October 13, 2016 at 4:07 pm
Rodrigo,
your tutorial is so clearly and easy to understand.
But, i have a trouble when I will run these. My problem is the “soFromBeginning”. My delphi said that variable hasn’t declare yet. So, where i can find that variable. I use delphi 7. win8.1 IE 11.
thank you very much..
October 13, 2016 at 4:20 pm
soFromBeginning is just a const with a value of 0.
October 13, 2016 at 4:57 pm
Thank you for your reply Rodrigo, the code can compiled now. But the next problem, I can not running the maps, because Google isn’t support IE anymore.. What should i do?
your suggestion is helpful for me
February 12, 2017 at 9:12 am
I was just wondering why the htmlstr has to be pushed by a stream. Isn’t it possible to just open ‘about:’+htmlstr?
February 18, 2017 at 12:47 pm
No you can’t pass the HTML content directly to the navigate method. Instead you must use a Stream because the WebBrowser control uses a stream-based interface (IPersistStreamInit) to load and save the documents.
March 21, 2017 at 2:41 pm
AT LAST, I figured out the problem.
Onion.js fires the error, because it calls JSON.parse.
JSON Parse isn’t supported by the web browser control.
You can test this by adding this to your JavaScript (already quoted for Delphi):
‘var code = ””\u2028\u2029″”; JSON.parse(code); ‘ +
Very browser should execute
var code = ‘”\u2028\u2029″‘; JSON.parse(code);
When executed in Delphi it fires an error instantly.
You can avoid the whole thing with a JSON3 polyfill:
‘https://cdn.jsdelivr.net/json3/3.3.2/json3.js‘ +
Then JSON will be defined and working as expected, causing the Onion.js error to never appear again!
July 8, 2017 at 2:47 am
See if this helps anyone:
https://stackoverflow.com/questions/33974901/google-maps-script-error-in-onion-js/36417825#36417825
put this just after ,head>
‘ ‘+
October 6, 2017 at 1:20 am
these codes result message could not complete the operation due to error 80020101,
for Delphi 7 or delphi xe8
October 6, 2017 at 6:00 pm
Hello, are you using the updated sample code from the Github repo https://github.com/RRUZ/blog/tree/master/Google/Maps/Google%20Maps%20Basic%20Sample ?
October 22, 2017 at 1:21 am
Hi, I get an error… ” You are using a browser that is not supported by the Google Maps JavaScript API. Consider changing your browser.” within the TWebBrowser, how do I change my default web browser within delphi?
March 6, 2018 at 11:13 pm
Hello Batman
What have you done in order to fix it? I have the same error
Regards!!
October 22, 2017 at 5:15 am
Nvm find it by changing my registry settings.
October 22, 2017 at 5:16 am
Fixed*