Commonly we use the TWebBrowser component to access Google maps, but there is another option, using the Google Static Map service.
The Google Static Map service allows you get an static image from a location without requiring JavaScript or any dynamic page loading. The Google Static Map service creates your map based on URL parameters sent through a standard HTTP request.
So the code to interact with this service is fairly easy. all we need is an TIdHTTP and a TImage component.
First we need to set the TIdHTTP property UserAgent (the UserAgent is what a browser uses to identify itself to the HTTP server
) to an valid Agent, if you use the default value Mozilla/3.0 (compatible; Indy Library)
you will get a awful message like this HTTP 1.1/ 403 Forbidden
. so we can change this value to Mozilla/3.0
or to another valid agent.
then we need build the url to request the image from an location. a valid URL look like this
http://maps.google.com/maps/api/staticmap?center=40.714728,-73.998672&zoom=12&size=400x400&sensor=false
You can see the full syntax for build a valid URL on this page.
Now using the TIdHTTP component, we send the request and get the image
var StreamData :TMemoryStream; JPEGImage : TJPEGImage; begin EditURL.Text:=buildUrl;//build the url with the params StreamData := TMemoryStream.Create; JPEGImage := TJPEGImage.Create; try try idhttp1.Get(EditURL.Text, StreamData); //Send the request and get the image StreamData.Seek(0,soFromBeginning); JPEGImage.LoadFromStream(StreamData);//load the image in a Stream ImageMap.Picture.Assign(JPEGImage);//Load the image Except On E : Exception Do MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0); End; finally StreamData.free; JPEGImage.Free; end; end;
finally a very important note from google
Use of the Google Static Maps API is subject to a query limit of 1000 unique (different) image requests per viewer per day. Since this restriction is a quota per viewer, most developers should not need to worry about exceeding their quota. However, note that we enforce an additional request rate limit to prevent abuse of the service. Requests of identical images, in general, do not count towards this limit beyond the original request.
If a user exceeds the limit as proscribed above, the following image will be displayed indicating that the quota has been exceeded:
This limit is enforced to prevent abuse and/or repurposing of the Static Maps API, and this limit may be changed in the future without notice. If you exceed the 24-hour limit or otherwise abuse the service, the Static Maps API may stop working for you temporarily. If you continue to exceed this limit, your access to the Static Maps API may be blocked.
Static Map URLs are restricted to 2048 characters in size. In practice, you will probably not have need for URLs longer than this, unless you produce complicated maps with a high number of markers and paths. Note, however, that certain characters may be URL-encoded by browsers and/or services before sending them off to the Static Map service, resulting in increased character usage.
…Note that static maps may only be displayed within browser content; use of static maps outside of the browser is not allowed. (Google Maps API Premier users are waived of this requirement.)
check the source code for educational use only (do you need a API Premier account to use the Static maps ouside of an browser), you can download the full project from this location.
unit UnitMain; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, IdHTTP, StdCtrls, ExtCtrls, XPMan, ComCtrls; type TFormMain = class(TForm) ImageMap: TImage; IdHTTP10: TIdHTTP; XPManifest1: TXPManifest; ScrollBoxMap: TScrollBox; Panel1: TPanel; EditURL: TEdit; ButtonGet: TButton; CheckBoxRealTime: TCheckBox; Panel2: TPanel; Panel3: TPanel; EditWidth: TEdit; UpDown3: TUpDown; UpDown2: TUpDown; UpDown1: TUpDown; ComboBoxMapType: TComboBox; EditZoom: TEdit; ComboBoxFormat: TComboBox; EditHeight: TEdit; EditLongitude: TEdit; EditLatitude: TEdit; Label7: TLabel; Label6: TLabel; Label5: TLabel; Label4: TLabel; Label3: TLabel; Label2: TLabel; Label1: TLabel; CheckBoxMarker: TCheckBox; ProgressBar1: TProgressBar; IdHTTP1: TIdHTTP; procedure ButtonGetClick(Sender: TObject); procedure EditZoomChange(Sender: TObject); procedure ComboBoxMapTypeChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure ImageMapMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure ImageMapMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); procedure IdHTTP10WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer); procedure IdHTTP10Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer); procedure IdHTTP10WorkEnd(ASender: TObject; AWorkMode: TWorkMode); private { Private declarations } SX: Integer; SY: Integer; LX: Integer; LY: Integer; function buildUrl:string; procedure GetMapImage; public { Public declarations } end; var FormMain: TFormMain; implementation uses jpeg; //this project only supports jpg, you can add addtional units to support gif and png {$R *.dfm} const UrlPrefix='http://maps.google.com/maps/api/staticmap?'; function TFormMain.buildUrl: string; //build the url based in the user input begin Result:=UrlPrefix+'center='+EditLatitude.Text+','+EditLongitude.Text+'&zoom='+EditZoom.Text+'&size='+EditWidth.Text+'x'+EditHeight.Text+'&maptype='+ComboBoxMapType.Text+'&sensor=false&format='+ComboBoxFormat.Text; if CheckBoxMarker.Checked then Result:=Result+'&markers=color:blue|'+EditLatitude.Text+','+EditLongitude.Text; end; procedure TFormMain.ButtonGetClick(Sender: TObject); begin GetMapImage; end; procedure TFormMain.ComboBoxMapTypeChange(Sender: TObject); begin if CheckBoxRealTime.Checked then GetMapImage; end; procedure TFormMain.EditZoomChange(Sender: TObject); begin if CheckBoxRealTime.Checked then GetMapImage; end; procedure TFormMain.FormCreate(Sender: TObject); begin ScrollBoxMap.DoubleBuffered := True; //avoid the flicker when the pan effect is activated end; procedure TFormMain.GetMapImage; //Get the image from the Google Service var StreamData : TMemoryStream; JPEGImage : TJPEGImage; begin EditURL.Text:=buildUrl; StreamData := TMemoryStream.Create; JPEGImage := TJPEGImage.Create; try try idhttp1.Get(EditURL.Text, StreamData); StreamData.Seek(0,soFromBeginning); ImageMap.Top := 0; ImageMap.Left := 0; JPEGImage.LoadFromStream(StreamData); LX := (ImageMap.Width - ScrollBoxMap.ClientWidth) * -1; LY := (ImageMap.Height - ScrollBoxMap.ClientHeight) * -1; ImageMap.Picture.Assign(JPEGImage); Except On E : Exception Do MessageDlg('Exception: '+E.Message,mtError, [mbOK], 0); End; finally StreamData.free; JPEGImage.Free; end; end; procedure TFormMain.IdHTTP10Work(ASender: TObject; AWorkMode: TWorkMode; AWorkCount: Integer); begin ProgressBar1.Position := AWorkCount; end; procedure TFormMain.IdHTTP10WorkBegin(ASender: TObject; AWorkMode: TWorkMode; AWorkCountMax: Integer); begin ProgressBar1.Position := 0; ProgressBar1.Max := IdHTTP1.Response.ContentLength; end; procedure TFormMain.IdHTTP10WorkEnd(ASender: TObject; AWorkMode: TWorkMode); begin //ProgressBar1.Position := 0; end; procedure TFormMain.ImageMapMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin SX := X; SY := Y; end; procedure TFormMain.ImageMapMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); //Allow pannig over the image var NX: Integer; NY: Integer; begin if not (ssLeft in Shift) then Exit; NX := ImageMap.Left + X - SX; NY := ImageMap.Top + Y - SY; if (NX < 0) and (NX > LX) then ImageMap.Left := NX; if (NY < 0) and (NY > LY) then ImageMap.Top := NY; end; end.
August 11, 2010 at 1:04 am
The terms and conditions of the static API states:
“Note that static maps may only be displayed within browser content; use of static maps outside of the browser is not allowed. (Google Maps API Premier users are waived of this requirement.)”
You may want to indicate that in order to legally use your example code, you need a Premier account.
August 13, 2010 at 6:47 am
Thank you!
December 16, 2013 at 2:49 am
can you provide a zip file for this?
December 17, 2013 at 10:19 am
https://dl.dropboxusercontent.com/u/12733424/Blog/Google_Maps__Static.zip
October 10, 2016 at 1:03 pm
me manda o exemplo desse projeto
October 10, 2016 at 10:43 pm
Check the repository for this article https://github.com/RRUZ/blog/tree/master/Google/Maps/Google%20Maps%20Static