Incorporating Maps into your application

As everyone knows, Google provides a web mapping service application that allows maps to be embedded into third-party websites via the Google Maps API.These APIs can be used to incorporate static maps into your Delphi applications. (Refer to Google’s terms of use for these APIs here.)

The APIs are essentially HTTP requests that return a PNG or JPEG image, so we need

  1. A HTTP client component,
  2. a memory stream to hold the result,
  3. a graphic component to decode the result and
  4. a canvas to display the graphic

For the HTTP client, we can use the ICS HttpCli component (ICS suite available from www.overbyte.be); for the graphic component, the TPngImage that is incorporated into XE (and others) and for the canvas the standard TImage.

type
TForm1 = class(TForm)
  HttpCli1: THttpCli;
  Image1: TImage;
  Button1: TButton;
  procedure HttpCli1RequestDone(Sender: TObject; RqType: THttpRequest;
    ErrCode: Word);
  procedure Button1Click(Sender: TObject);
  procedure FormCreate(Sender: TObject);
  procedure FormDestroy(Sender: TObject);
private
  { Private declarations }
public
  { Public declarations }
  FData : TMemoryStream;
  FPng : TPngImage;
end;

The only event we need on the HtpCli component is the OnRequestDone which fires when the result has been received. We also need to create and destroy the memory stream and png image via the FormCreate and FormDestory events.

procedure TForm1.FormCreate (Sender: TObject);
begin
  FData := TMemoryStream.Create;
  FPng := TPngImage.Create;
end;
procedure TForm1.FormDestroy (Sender: TObject);
begin
  FData.Free;
  FPng.Free;
end;

To get the map image, we need to send a request to the appropriate URL. The basic URL format for maps is

http://maps.google.com/maps/api/staticmap?center=<location>&zoom=<zoom>&size=<h>x<w>&sensor=false

where <location>, <zoom>, <h> and <w> are replaced with actual values For eample

http://maps.google.com/maps/api/staticmap?center=Sydney&zoom=14&size=320×240&sensor=false

procedure TForm1.Button1Click (Sender: TObject);
begin
  FData.Clear;
  with HttpCli1 do
    begin
      RcvdStream := FData;
      URL := 'http://maps.google.com/maps/api/staticmap?center=Sydney&amp;zoom=14&amp;size=320x240&amp;sensor=false';
      GetASync;
    end;
 end;

When finished the OnRequestDone event will fire. Here we need to decode the returned image and display it on the form.

procedure TForm1.HttpCli1RequestDone (Sender: TObject; RqType: THttpRequest;
 ErrCode: Word);
begin
  if (Error = 0) and (FData.Size &gt; 4) then
    begin
      if HttpCli1.ContentType = 'image/png' then
        begin
          FData.Seek (0, soFromBeginning);
          try
            FPng.LoadFromStream (FData);
            Image1.Picture.Assign (FPng);
          except
          end;
          FData.Clear;
        end;
    end;
end;

With any luck, and an Internet connection, you should get the following result :-

More URL options can be found at http://code.google.com/apis/maps/documentation/staticmaps/

Posted in Tools, VCL
6 comments on “Incorporating Maps into your application
  1. The only problem with this is that you need an enterprise license to be able to use Google maps in non-public websites, this was about $11,000 per year last time I looked. The best free solution that I have found (at least for New Zealand) is to use openstreetmap.org – which has a creative commons license – the maps aren’t as complete but free.

  2. AndréFM says:

    Everyone case use Google Maps and add at own software, but the must be FREE and you must make it available for everyone to download (e.g. from your website). If you implement in a commercial software, then you must acquire the enterprise license.
    There are some other limitations, but only if you use it heavily.
    Additional information about the limits:
    http://googlegeodevelopers.blogspot.com/2011/10/introduction-of-usage-limits-to-maps.html

  3. marcocantu says:

    I prefer embedding a TWebBrowser with a “live” map, rather than use the static tiles… but similar licences restrictions apply.

  4. David M says:

    The API also seems to be built around a zoom level and image pixel size. More useful would be a way to get the actual (and request an image with) specific geolocated bounding coordinates for its edges / corners.

    I’ve found resources online where Google’s zoom levels etc are reverse-engineered, so from a zoom level and centre coordinate you can figure out the geolocation of the returned tile. It seems fragile and dependent on Google’s internal code though.

    • zeroc8 says:

      Google and OSM use the same projection and tiling scheme.
      The only difference is that Google coordinate origin is on the upper left, while OSM is on the lower left. You can easily create your own tilesets from georeferenced raster files, using a tool like Globalmapper (commerical but quite cheap, around 150 Euro). If you are on Linux, you can use gdal2tiles and similar tools for free. Globalmapper has other features too, you can easily georeference any maps for example and then directly export to OSM. That way you won’t have to pay the Google licencse fee and you can keep your stuff offline.