はじめに
Delphi にはモバイルプラットフォーム向けに TMapView
というコンポーネントがあるのですが 1、デスクトッププラットフォームあるいは VCL 用には用意されていません。
VCL アプリケーションでも Google Map を表示したい事があるのでどうにかしてみようと思いました。
Maps Static API
Maps Static API の仕様はこちらで確認できます。
API キーの取得方法についてはミガロさんの技術 Tips が詳しいです。
- Google Maps Platform API キー取得手順と使用回数制限設定 (Migaro. 技術Tips)
- Google Maps Platform コアサービスの料金リスト (Google Maps Platform)
ソースコード
Maps Static API を使った URL を生成するためのサポートユニットです。
{ ---------------------------------------------------------------------------- }
{ Google Maps Static API Support unit }
{ ---------------------------------------------------------------------------- }
unit uGoogleMapStatic;
interface
uses
System.SysUtils, System.Math, System.NetEncoding;
const
DEFAULT_LANG = 'ja';
DEFAULT_WIDTH = 640;
DEFAULT_HEIGHT = 480;
type
TImageFormat = (ifPng, ifPng8, ifPng32, ifGif, ifJpg, ifJpgBaseline);
TMapType = (mtRoadmap, mtSatellite, mtHybrid, mtTerrain);
TGMSRec = record
API_KEY: string;
Signature: string;
Center: string;
Center_latitude: Single;
Center_longitude: Single;
Zoom: Byte;
Width: Integer;
Height: Integer;
Scale: Byte;
ImageFormat: TImageFormat;
Maptype: TMapType;
Language: string;
Region: string;
Map_id: string;
Markers: string;
Path: string;
Visible: string;
style: string;
procedure Init;
function GenerateURL: string;
end;
implementation
const
INVALID_VALUE = $BEEF;
URL_TEMPLATE = 'https://maps.googleapis.com/maps/api/staticmap';
strImageFormat: array [TImageFormat] of string =
('png ', 'png8', 'png32', 'gif', 'jpg', 'jpg-baseline');
strMapType: array [TMapType] of string =
('roadmap', 'satellite', 'hybrid', 'terrain');
{ TGMSRec }
procedure TGMSRec.Init;
begin
Self := Default(TGMSRec);
with Self do
begin
Center_Latitude := NaN;
Center_Longitude := NaN;
Zoom := 15;
MapType := mtRoadmap;
Language := DEFAULT_LANG;
Width := DEFAULT_WIDTH;
Height := DEFAULT_HEIGHT;
end;
end;
function TGMSRec.GenerateURL: string;
begin
var Params: string := '';
// key (required)
Params := Params + Format('?key=%s', [API_KEY]);
// signature (recommended)
if signature <> '' then
Params := Params + Format('&zoom=%d', [Zoom]);
// center ((required if markers not present)
if Center <> '' then
Params := Params + Format('¢er=%s', [TNetEncoding.URL.Encode(Center)])
else
begin
if (not IsNan(Center_Latitude)) and (not IsNan(Center_Longitude)) then
Params := Params + Format('¢er=%f,%f', [Center_Latitude, Center_Longitude]);
end;
// zoom ((required if markers not present)
if zoom in [0..21] then
Params := Params + Format('&zoom=%d', [Zoom]);
// size (required)
Params := Params + Format('&size=%dx%d', [Width, Height]);
// scale
if zoom in [1..2] then
Params := Params + Format('&scale=%d', [scale]);
// format
if ImageFormat <> ifPng then
Params := Params + Format('&format=%s', [strImageFormat[ImageFormat]]);
// maptype
if Maptype <> mtRoadmap then
Params := Params + Format('&maptype=%s', [strMapType[MapType]]);
// language
if Language <> '' then
Params := Params + Format('&language=%s', [Language]);
// region
if Region <> '' then
Params := Params + Format('®ion=%s', [TNetEncoding.URL.Encode(Region)]);
// map_id
if Map_id <> '' then
Params := Params + Format('&map_id=%s', [TNetEncoding.URL.Encode(Map_id)]);
// markers
if Markers <> '' then
Params := Params + Format('&markers=%s', [TNetEncoding.URL.Encode(Markers)]);
// path
if Path <> '' then
Params := Params + Format('&path=%s', [TNetEncoding.URL.Encode(Path)]);
// visible
if Visible <> '' then
Params := Params + Format('&visible=%s', [TNetEncoding.URL.Encode(Visible)]);
// Style
if Map_id <> '' then
Params := Params + Format('&style=%s', [TNetEncoding.URL.Encode(Style)]);
// Generate URL
result := URL_TEMPLATE + Params;
end;
end.
使い方
高度なレコード型である TGMSRec
を初期化し、フィールドに値を格納して GenerateURL()
を呼ぶだけです。
例えば TEdgeBrowser
2 に表示するには、次のようなコードになります。
uses
..., uGoogleMapStatic;
procedure TForm1.FormCreate(Sender: TObject);
begin
EdgeBrowser1.CreateWebView;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
var GMSRec: TGMSRec;
with GMSRec do
begin
Init;
API_KEY := '(あなたの取得したAPI キー)';
// Center_latitude := 35.7100627;
// Center_longitude := 139.8107004;
Center := '東京スカイツリー';
Width := EdgeBrowser1.Width - 16;
Height := EdgeBrowser1.Height - 16;
end;
EdgeBrowser1.Navigate(GMSRec.GenerateURL);
end;
実行するとこんな感じになります。
uGoogleMapStatic.pas
は URL を生成しているだけなので、従来の TWebBrowser
等に表示するのも難しくないと思います。
See also:
- TEdgeBrowser (DocWiki)
- TEdgeBrowser コンポーネントの利用と TWebBrowser コンポーネントへの変更点 (DocWiki)
- TEdgeBrowserを使用してスクリプトを実行する方法 (blogs.embarcadero.com)
使い方 (その2)
Maps Static API では画像が返ってきてるので、TImage
に画像を表示させればブラウザコンポーネントを使わずに地図を表示する事もできます。モノによってはこちらの方法で事足りるかもしれませんね。
uses
..., System.Net.HttpClient, Vcl.Imaging.pngimage;
procedure TForm1.Button2Click(Sender: TObject);
begin
var GMSRec: TGMSRec;
with GMSRec do
begin
Init;
API_KEY := '(あなたの取得したAPI キー)';
// Center_latitude := 35.7100627;
// Center_longitude := 139.8107004;
Center := '東京スカイツリー';
Width := Image1.Width - 16;
Height := Image1.Height - 16;
end;
with THTTPClient.Create do
try
Image1.Picture.LoadFromStream(Get(GMSRec.GenerateURL).ContentStream);
finally
Free;
end;
end;
See also:
- 【Delphi】そこそこ短いコードで Web サイトのデータを持ってくる (Qiita)
- THttpClient の落とし穴1 (Qiita:@pik)
- THttpClient の落とし穴2 (Qiita:@pik)
- THttpClient の落とし穴(解決編) (Qiita:@pik)
- 簡単に HTTPS 通信ができる THTTPClient (Qiita:@vram)
おわりに
簡単なテストしかしていないのでバグがあるかもしれません。
不具合を見つけたらコメント欄で教えてください m(_ _)m
Maps Embed API 版と Maps JavaScript API 版はこちらです:
- 【Delphi】Google Map を表示するための HTML を生成する【Maps Embed API】(Qiita)
- 【Delphi】Google Map を表示するための JavaScript を生成する【Maps JavaScript API】(Qiita)
See also: