5.4 Keyhole API接口介绍
从运行库中可以发现,Google Earth目前提供的COM API基本上都是基于Keyhole API的,不过Google做了大量的工作用于封装,特别是照相机接口,新的接口很大程度上方便了用户的使用。
以前版本的Keyhole API接口分类上虽然有些混淆,个别函数的功能特征也不是很明显,但是作为目前Google Earth API的基础,还是有一定的学习必要的。
5.4.1 Keyhole接口
Keyhole提供的接口一共包括4个部分,如表5-17所示。
表5-17 Keyhole组成部分
1 |
IKHFeature |
作用类似于IFeatureGE |
2 |
IKHInterface |
作用类似于IApplicationGE |
3 |
IKHViewExtents |
作用类似于IViewExtentsGE |
4 |
IKHViewInfo |
作用类似于ICameraInfoGE |
5.4.2 IKHInterface接口
IKHInterface接口类似于Google Earth API中的IApplicationGE,但所提供的属性和方法要少于后者。
1.IKHInterface属性
1)streamingProgressPercentage
streamingProgressPercentage介绍如下。
l 定义:Google Earth中当前地图流数据读取进度。
l 使用方式:读(Get)。
l 值类型:Integer。
l 方程式:property streamingProgressPercentage: Integer
read Get_streamingProgressPercentage;。
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnStreamProgressClick(Sender: TObject);
var
tmpProgress : integer;
begin
tmpProgress := FKHInterface.streamingProgressPercentage;
showmessage(inttostr(tmpProgress));
end;
类似于IApplicationGE中的方法,执行后的效果如图5-48所示。
图5-48 地图数据流读取百分比(单位%)
2)autopilotSpeed
autopilotSpeed介绍如下。
l 定义:描述了Google Earth照相机漫游“飞行”时的速度。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property autopilotSpeed: Double
read Get_autopilotSpeed
write Set_autopilotSpeed;。
注意 |
照相机飞行时的速度取值为0.0~5.0,数值越大速度越快。 |
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnGetClick(Sender: TObject);
begin
edSpeed.Text := floattostr(FKHInterface.autopilotSpeed);
end;
procedure TForm1.btnSetClick(Sender: TObject);
var
tmpSpeedStr : string;
begin
tmpSpeedStr := edSpeed.Text;
FKHInterface.autopilotSpeed := strtofloat(trim(tmpSpeedStr));
end;
autopilotSpeed所对应的是Google Earth的【Tools】→【Options】命令中“Fly-To Speed”设置框中心参数,通过本实例代码可以互操作这个参数,如图5-49和图5-50所示。
图5-49 飞行速度 图5-50 【Fly-To Speed】选项数值
3)currentViewExtents
currentViewExtents介绍如下。
l 定义:描述了当前Google Earth地图窗口的视场范围。
l 使用方式:读(Get)。
l 值类型:IKHViewExtents。
l 方程式:property currentViewExtents: IKHViewExtents
read Get_currentViewExtents;。
Delphi实例代码:
var FKHInter face : IKHInterface;
……
procedure TForm1.btnViewExtClick(Sender: TObject);
var
tmpStr : string;
tmpLatLng : double;
begin
tmpLatLng := FKHInterface.currentViewExtents.east;
tmpstr := '东:'+ floattostr(tmpLatLng) + #13#10 + tmpstr;
tmpLatLng := FKHInterface.currentViewExtents.west;
tmpstr := '西:'+ floattostr(tmpLatLng) + #13#10 + tmpstr;
tmpLatLng := FKHInterface.currentViewExtents.south;
tmpstr := '南:'+ floattostr(tmpLatLng) + #13#10 + tmpstr;
tmpLatLng := FKHInterface.currentViewExtents.north;
tmpstr := '北:'+ floattostr(tmpLatLng) + #13#10 + tmpstr;
showmessage(tmpstr);
end;
执行后的效果如图5-51所示。
图5-51 视场的四边
2.IKHInterface方法
1)currentView
currentView介绍如下。
l 定义:取得当前Google Earth的地图照相机,前面的表格说明了这个接口类似于Google Earth API 中的ICameraInfoGE接口。
l 方程式:function currentView(terrain: Integer): IKHViewInfo; safecall;。
Delphi实例代码:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
……
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses KEYHOLELib_TLB;
{$R *.dfm}
var FKHInterface : IKHInterface;
procedure TForm1.FormCreate(Sender: TObject);
begin
FKHInterface := CoKHInterface.Create;
end;
procedure TForm1.btnViewGetClick(Sender: TObject);
var
tmpView : IKHViewInfo;
begin
tmpView := FKHInterface.currentView(1);
edazimuth.text := floattostr(tmpView.azimuth);
edlatitude.text := floattostr(tmpView.latitude);
edlongitude.text := floattostr(tmpView.longitude);
edrange.text := floattostr(tmpView.range);
edtilt.text := floattostr(tmpView.tilt);
end;
procedure TForm1.btnViewSetClick(Sender: TObject);
var
tmpView : IKHViewInfo;
begin
try
tmpView := coKHViewInfo.Create;
tmpView.azimuth := strtofloat(edazimuth.Text);
tmpView.latitude := strtofloat(edlatitude.text);
tmpView.longitude := strtofloat(edlongitude.text);
tmpView.range := strtofloat(edrange.text);
tmpView.tilt := strtofloat(edtilt.text);
FKHInterface.setView(tmpView,0,5);
except
//……
end;
end;
end.
该程序可以操控Google Earth的地图窗口的焦点移动,稍加改动就可以实现互动效果,所以这个接口方法是很多目前Internet上Google Earth玩家喜欢的GE小游戏的基础。通过这个方法设置视点的参数,甚至可以实现如第一人称射击等游戏。
焦点参数设置如图5-52所示。
图5-52 焦点参数设置
从图5-53和图5-54的两幅图中可以看出Google Earth的视场随着照相机的参数改变而变动。
图5-53 焦点变动前 图5-54 焦点变动后
2)SaveScreenShot
SaveScreenShot介绍如下。
l 定义:将地图窗口当前的卫星图片内容保存成一个黑白图像文件。
l 方程式:procedure SaveScreenShot(const fileName: WideString; quality: Integer); safecall;。
其参数如表5-18所示。
表5-18 SaveScreenShot参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
fileName |
In |
WideString |
图片文件地址 |
quality |
In |
Integer |
图片精细程度 |
Delphi实例代码类似于Google版的IApplicationGE接口的截屏方法,在此不再赘述。
3)OpenFile
OpenFile介绍如下。
l 定义:停止播放。
l 方程式:procedure OpenFile(const fileName: WideString); safecall;。
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnOpenFileClick(Sender: TObject);
var
KMLpath: widestring;
begin
KMLpath := 'C:\Documents and Settings\Administrator\My Documents\placemark.kml';
try
FKHInterface.OpenFile(KMLpath);
except
//……
end;
end;
代码执行后的效果如图5-55所示。与Google版的OpentFile方法类似,也是在Google Earth中加载一个KML文件。
图5-55 OpenFile结果
4)QuitApplication
QuitApplication介绍如下。
l 定义:退出程序,关闭Google Earth。
l 方程式:procedure QuitApplication; safecall;。
关闭Google Earth的时候如果当前用户打开了KML或者没有保存地标文件,Google Earth会弹出提示。如果用户单击了【Cancel】按钮则Delphi程序会捕捉到错误。请用户在开发程序时注意容错。
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnQuitApplicationClick(Sender: TObject);
begin
try
FKHInterface.QuitApplication;
except
showmessage('关闭Google Earth程序被取消或出错。')
end;
end;
5)SetRenderWindowSize
SetRenderWindowSize介绍如下。
l 定义:设置地图窗口的大小。
l 方程式:procedure SetRenderWindowSize(width: Integer; height: Integer); safecall;。
其参数如表5-19所示。
表5-19 SetRanderWindowSize参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
Width |
In |
Integer |
窗口宽度 |
Height |
In |
Integer |
窗口高度 |
Delphi实例代码:
procedure TForm1.btnResizeMapClick(Sender: TObject);
var
ViewWidth, ViewHeight : integer;
begin
ViewWidth := 300;
ViewHeight := 200;
try
FKHInterface.SetRenderWindowSize(ViewWidth,ViewHeight);
except
//……
end;
end;
6)setView
setView介绍如下。
l 定义:根据给定的照相机参数、地形参数、速度参数,设置当前视场。
l 方程式:procedure setView(const view: IKHViewInfo; terrain: Integer; speed: Double); safecall;。
其参数如表5-20所示。
表5-20 setView参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
view |
In |
IKHViewInfo |
视场对象 |
terrain |
In |
Integer |
地形值 |
speed |
In |
Double |
速度值 |
Delphi实例代码:
procedure TForm1.btnSetViewClick(Sender: TObject);
var
tmpview : IKHViewInfo;
begin
try
tmpview := coKHViewInfo.Create;
tmpview.tilt := 30;
tmpview.azimuth:= 0;
tmpview.range :=800;
tmpview.latitude := 32.2323;
tmpview.longitude := 118.2332;
FKHInterface.setView(tmpview,1,4.0);
except
//……
end;
end;
执行后的效果如图5-56所示。
图5-56 设定视场
7)LoadKml
LoadKml介绍如下。
l 定义:加载KML文档。
l 方程式:procedure LoadKml(var kmlData: WideString); safecall;。
其参数如表5-21所示。
表5-21 LoadKml参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
kmlData |
In |
WideString |
KML文档 |
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnOpenFileClick(Sender: TObject);
var
KMLpath: widestring;
begin
KMLpath := 'C:\Documents and Settings\Administrator\My Documents\TimeSpan.kmll';
try
FKHInterface. LoadKml(KMLpath);
except
//……
end;
end;
8)getFeatureByName
getFeatureByName介绍如下。
l 定义:根据要素名称获得要素对象。
l 方程式:function getFeatureByName(const name: WideString): IKHFeature; safecall;。
其参数如表5-22所示。
表5-22 getFeatureByName参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
Name |
In |
WideString |
要素名称 |
Delphi实例代码与Google版IApplicationGE接口中的方法相同,在此不再赘述。
9)setViewParams
setViewParams介绍如下。
l 定义:设置视场的参数。
l 方程式:procedure setViewParams(lat: Double; lon: Double; range: Double; tilt: Double; azimuth: Double; terrain: Integer; speed: Double); safecall;。
其参数如表5-23所示。
表5-23 setViewParams参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
lat |
In |
Double |
纬度 |
(续表)
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
lon |
In |
Double |
经度 |
tilt |
In |
Double |
倾角 |
azimuth |
In |
Double |
方位角 |
terrain |
In |
Integer |
地形值 |
speed |
In |
Double |
速度 |
Delphi实例代码:
procedure TForm1.btnsetViewParamsClick(Sender: TObject);
var
tmpLat,tmplon,tmpAzi,tmptilt,tmpran : double;
tmpflyspeed : double;
tmpTerrain :integer;
begin
try
//定义照相机参数
tmpLon := 118.2452;
tmplat := 32.3453;
tmpran := 20000;
tmpAzi := 0;
tmptilt := 60;
//定义飞行速度
tmpflyspeed := 4.0;
//定义地形夸张度
tmpTerrain := 2;
//设置视场
FKHInterface.setViewParams(tmplat,tmplon,tmpran,tmptilt,tmpAzi,tmpTerrain,tmpflyspeed);
except
//……
end;
end;
执行后的效果如图5-57所示。
图5-57 停止播放
10)setFeatureView
setFeatureView介绍如下。
l 定义:设置“飞行到”某要素的视场,第二个参数为飞行速度,取值0~5。
l 方程式:procedure setFeatureView(const feature: IKHFeature; speed: Double); safecall;。
Delphi实例代码:
var FKHInterface : IKHInterface;
……
procedure TForm1.btnsetFeatureViewClick(Sender: TObject);
var
tmpFeature :IKHFeature;
begin
try
tmpFeature := FKHInterface.getFeatureByName('testplacemark1');
FKHInterface.setFeatureView(tmpFeature,4.0);
except
//……
end;
end;
执行后的效果如图5-58所示。
图5-58 运行效果
11)getPointOnTerrainFromScreenCoords
getPointOnTerrainFromScreenCoords介绍如下。
l 定义:取得地面上某一点的屏幕坐标。
l 方程式:function getPointOnTerrainFromScreenCoords(screen_x: Double; screen_y: Double): PSafeArray; safecall;。
其参数如表5-24所示。
表5-24 getPointOnTerrainFromScreenCoords参数
参 数 |
输 入 方 向 |
值 类 型 |
定 义 |
screen_x |
In |
Double |
屏幕坐标X |
screen_y |
In |
Double |
屏幕坐标Y |
screen_x和screen_y的取值都在-1~+1之间,具体说明请参看前面的Google Earth API。
5.4.3 IKHFeature接口
IKHFeature接口类似于Google Earth API的IFeatureGE接口,不过少了很多属性,如高亮显示、获取子要素集等。
IKHFeature属性如下。
1)visibility
visibility介绍如下。
l 定义:描述了每次视点“飞行”停止的时长。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property visibility: Integer
read Get_visibility
write Set_visibility;。
Delphi实例代码:
procedure TForm1.btnVisibleClick(Sender: TObject);
var
tmpFeature :IKHFeature;
begin
try
tmpFeature := FKHInterface.getFeatureByName('testplacemark1');
if (tmpFeature.visibility <>0) then
tmpFeature.visibility := 0
else
tmpFeature.visibility :=1;
except
//……
end;
end;
2)hasView
hasView介绍如下。
l 定义:描述了要素是否有视场。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property hasView: Integer
read Get_hasView;。
Delphi实例代码:
procedure TForm1.btnhasViewClick(Sender: TObject);
var
tmpFeature :IKHFeature;
begin
tmpFeature := FKHInterface.getFeatureByName('testplacemark1');
if (tmpFeature.hasView <>0) then
begin
showmessage('有视场');
FKHInterface.setFeatureView(tmpFeature,4.0);
end
else
begin
showmessage('无视场');
end;
end;
5.4.4 IKHViewExtents接口
表示Google Earth当前地图视场的范围,此接口为IKHInterface.currentViewExtents的返回值,一般用4个方向的属性值来表示范围,并且这4个方向的属性值都是只读的。
1)North
North介绍如下。
l 定义:视场的北边界。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property north: Double
read Get_north;。
2)South
South介绍如下。
l 定义:视场的南边界。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property south: Double
read Get_south;。
3)East
East介绍如下。
l 定义:视场的东边界。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property east: Double
read Get_east;。
4)West
West介绍如下。
l 定义:视场的西边界。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property west: Double
read Get_west;。
Delphi实例代码:
procedure TForm1.btnViewExtentsClick(Sender: TObject);
var
tmpViewExt : IKHViewExtents ;
tmpstr: string;
begin
try
tmpViewExt := FKHInterface.currentViewExtents;
tmpstr := 'N: ' + floattostr(tmpViewExt.North ) + #13#10 + tmpstr;
tmpstr := 'S: ' + floattostr(tmpViewExt.South ) + #13#10 + tmpstr;
tmpstr := 'E: ' + floattostr(tmpViewExt.East ) + #13#10 + tmpstr;
tmpstr := 'W: ' + floattostr(tmpViewExt.West ) + #13#10 + tmpstr;
showmessage(tmpstr);
except
//……
end;
end;
执行后的效果如图5-59所示。
5.4.5 IKHViewInfo接口
IKHViewInfo接口类似于Google Earth API的ICameraInfoGE接口,IKHViewInfo属性介绍如下。
1)latitude
latitude介绍如下。
l 定义:描述了Google Earth照相机的纬度。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property latitude: Double
read Get_latitude
write Set_latitude;。
2)longitude
longitude介绍如下。
l 定义:描述了Google Earth照相机的经度。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property longitude: Double
read Get_longitude
write Set_longitude;。
3)range
range介绍如下。
l 定义:描述了Google Earth照相机的视场范围。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property range: Double
read Get_range
write Set_range;。
4)tilt
tilt介绍如下。
l 定义:描述了Google Earth照相机镜头的倾角。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property tilt: Double
read Get_tilt
write Set_tilt;。
5)azimuth
azimuth介绍如下。
l 定义:描述了Google Earth照相机镜头的方位角。
l 使用方式:读(Get)/ 写(Set)。
l 值类型:Double。
l 方程式:property azimuth: Double
read Get_azimuth
write Set_azimuth;。
Delphi实例代码:
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
……
private
{ Private declarations }
function GetLat():double;
function GetLng():double;
function GetAzimuth():double;
function GetTilt():double;
function GetRange():double;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
uses KEYHOLELib_TLB;
{$R *.dfm}
var FKHInterface: IKHInterface;
procedure TForm1.btnGetClick(Sender: TObject);
begin
if (FKHInterface <> nil) then
begin
edLng.Text := floattostr(GetLng());
edLat.Text := floattostr(GetLat());
edAzi.Text := floattostr(GetAzimuth());
edTilt.Text := floattostr(GetTilt());
edRan.Text := floattostr(GetRange());
end
else
begin
showmessage('请稍等……');
end;
end;
//获取相机方位角
function TForm1.GetAzimuth: double;
var
cm: IKHViewInfo;
begin
cm := FKHInterface.currentView(1);
if cm <> nil then
result:= cm.Azimuth;
end;
//获取照相机纬度
function TForm1.GetLat: double;
var
cm: IKHViewInfo;
begin
cm := FKHInterface.currentView(1);
if cm <> nil then
result:= cm.latitude;
end;
//获取照相机经度
function TForm1.GetLng: double;
var
cm: IKHViewInfo;
begin
cm := FKHInterface.currentView(1);
if cm <> nil then
result:= cm.longitude;
end;
//获取照相机倾斜角
function TForm1.GetTilt: double;
var
cm: IKHViewInfo;
begin
cm := FKHInterface.currentView(1);
if cm <> nil then
result:= cm.Tilt;
end;
//获取照相机的现场范围
function TForm1.GetRange: double;
var
cm: IKHViewInfo;
begin
cm := FKHInterface.currentView(1);
if cm <> nil then
result:= cm.Range;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
try
FKHInterface := coKHInterface.Create;
Except
showmessage('启动失败');
end;
end;
end.
执行后的效果如图5-60所示。
图5-60 相机参数