5.3.4 ITimeGE接口
ITimeGE接口是Google Earth内部控制日期和时间的接口。Google Earth的时间计算均是根据UTC时区计算的。UTC是Universal Time Coordinated的英文缩写,中文译为“协调世界时”,是由国际无线电咨询委员会规定和推荐,由BIH负责保持的时间标度。
采用UTC的时区划分方法,把全时间按照每15°一个时区的划分原则,共分为24个时区,每一个时区都有各自的编号。例如北京位置在东经116°左右,时区处于东8区,用UTC+8表示,而美国旧金山处于西8区,则为UTC-8,以此类推,这个常识比较重要,在进行Itime接口开发的时候经常用到。
1.ITimeGE方法
1)Clone
Clone介绍如下。
l 定义:克隆,通常用做对于有只读属性的对象。
l 方程式:function Clone: ITimeGE; safecall;。
Delphi实例代码请见下面的代码。
2)ConvertToZone
ConvertToZone介绍如下。
l 定义:通过给定的时区重新计算,即转换时区的计算。
l 方程式:function ConvertToZone(TimeZone: Double): ITimeGE; safecall;。
其参数如表5-14所示。
表5-14 ConvertToZone参数
参 数 | 输 入 方 向 | 值 类 型 | 定 义 |
TimeZone | In | Double | 给定的UTC时区 |
Delphi实例代码:
var F_AppGE: IApplicationGE;
……
procedure TForm1.BtnTimeZoneClick(Sender: TObject);
var
FFeatures :IFeatureCollectionGE;
ParFeature : IFeatureGE;
i: integer;
tmpstr : string;
tmpYear,tmpMonth,tmpDay:integer;
tmpTimeZone : ITimeGE;
begin
ParFeature := F_AppGE.GetFeatureByName('nanjing');
FFeatures := ParFeature.GetChildren;
for i := 1 to FFeatures.Count do
begin
if (FFeatures[i].Highlighted <> 0) then
begin
tmpTimeZone := FFeatures[i].TimeInterval.BeginTime;
tmpTimeZone := tmpTimeZone.ConvertToZone(-10.0);
tmpYear := tmpTimeZone.Year;
tmpMonth := tmpTimeZone.Month;
tmpDay := tmpTimeZone.Day;
tmpstr := inttostr(tmpYear) + '-' + inttostr(tmpMonth) + '-' +inttostr(tmpDay);
end;
end;
showmessage('开始时间是:' + tmpstr);
end;
首先操作Google Earth,打开第3章中的KML文件“TimeSpan.kml”,然后执行,下同。
C#实例代码:
ApplicationGEClass appGE = new ApplicationGEClass();
……
private void coverTimeFromAnotherTZ()
{
FeatureGE ft = appGE.GetFeatureByName(ft_name);
if (ft != null)
{
DateTime tm = ft.TimeInterval.BeginTime.ConvertToZone(-6.0);
}
}
可以看到原始的BeginTime中日期是2004-01-01,而转换过后的日期为2003-12-31,说明根据时区的不同,Google Earth时间计算的结果是不同的,如图5-37所示。
图5-37 Google时间
2.ITimeGE属性
1)Type
Type介绍如下。
l 定义:读取或设置时间类型,无限或有限的。
l 使用方式:读(Get)/写(Set)。
l 值类型:TimeTypeGE。
l 方程式:property type_: TimeTypeGE
read Get_type_
write Set_type_;。
Delphi代码请参见ConvertToZone中的例子。
2)Year
Year介绍如下。
l 定义:表示时间日期的“年份”。
l 使用方式:读(Get)/写(Set)。
l 值类型:SYSINT。
l 方程式:property Year: SYSINT
read Get_Year
write Set_Year;。
Delphi代码请参见ConvertToZone中的例子。
3)Month
Month介绍如下。
l 定义:表示时间日期的“月”。
l 使用方式:读(Get)/写(Set)。
l 值类型:SYSINT。
l 方程式:property Month: SYSINT
read Get_Month
write Set_Month;。
Delphi代码请参见ConvertToZone中的例子。
4)Day
Day介绍如下。
l 定义:表示时间日期的“日”。
l 使用方式:读(Get)/写(Set)。
l 值类型:SYSINT。
l 方程式:property Day: SYSINT
read Get_Day
write Set_Day;。
Delphi代码请参见ConvertToZone中的例子。
5)Hour
Hour介绍如下。
l 定义:表示时间日期的“小时”。
l 使用方式:读(Get)/写(Set)。
l 值类型:SYSINT。
l 方程式:property Hour: SYSINT
read Get_Hour
write Set_Hour;。
6)Minute
Minute介绍如下。
l 定义:表示时间日期的“分钟”。
l 使用方式:读(Get)/写(Set)。
l 值类型:SYSINT。
l 方程式:property Minute: SYSINT
read Get_Minute
write Set_Minute;。
7)Second
Second介绍如下。
l 定义:表示时间日期的“秒”。Google Earth采用的UTC时间基数是1。
l 使用方式:读(Get)/写(Set)。
l 值类型: SYSINT。
l 方程式:property Second: SYSINT
read Get_Second
zrite Set_Second;。
8)TimeZone
l 定义:返回一个布尔值,表示当前的要素是否被高亮选中。如果被高亮选中,返回true,否则返回false。
l 使用方式:读(Get)/写(Set)。
l 值类型:Double。
l 方程式:property TimeZone: Double
read Get_TimeZone
write Set_TimeZone;。
3.一个完整的ITimeGE的Delphi小程序
首先程序开始的时候初始化,生成或者捕获一个Google Earth进程,代码如下:
unit Unit1;
……
//程序窗口开始创建
procedure TFormTime.FormCreate(Sender: TObject);
begin
try
F_AppGE := CoApplicationGE.Create();
except
showmessage('启动Google Earth失败');
end;
end;
对应的C#代码:
private void Form1_Load(object sender, EventArgs e)
{
try
{
appGE = new ApplicationGEClass();
}
catch (Exception err)
{
MessageBox.Show("未能启动Google Earth程序");
}
}
Delphi代码:
//程序窗口关闭
procedure TFormTime.FormClose(Sender: TObject; var Action: TCloseAction);
begin
F_AppGE := nil;
end;
//获取要素的时间
procedure TFormTime.btnGetClick(Sender: TObject);
var
……
begin
try
ParFeature := F_AppGE.GetFeatureByName('nanjing');
FFeatures := ParFeature.GetChildren; //获得子要素集合
for i := 1 to FFeatures.Count do //遍历
begin
if (FFeatures[i].Highlighted <> 0) then
begin
tmpTimeZone := FFeatures[i].TimeInterval.BeginTime;
tmpYear := tmpTimeZone.Year; //获取当前时区时间的“年”
tmpMonth := tmpTimeZone.Month; //获取当前时区时间的“月”
tmpDay := tmpTimeZone.Day; //获取当前时区时间的“天”
tmpstr := inttostr(tmpYear) + '-' + inttostr(tmpMonth) + '-' +inttostr(tmpDay);
……
end;
end;
except
end;
end;
这里主要是时间的赋值,克隆时间对象至另一个变量,然后更改被赋值时间变量的属性,主要是以展示时间参数的用法为目的:
//时间赋值,主要是用到了ITimeGE.Clone方法
procedure TFormTime.btnSetClick(Sender: TObject);
var
……
begin
try
ParFeature := F_AppGE.GetFeatureByName('nanjing');
FFeatures := ParFeature.GetChildren;
for i := 1 to FFeatures.Count do
begin
if (FFeatures[i].Highlighted <> 0) then
begin
tmpTimeBegin := FFeatures[i].TimeInterval.BeginTime.Clone; //克隆“开始时间”
……
edZoneClone.Text := 'UTC ' + floattostr(tmpTimeBegin); //在文本框中显示克隆的时间
end;
end;
except
//……
end;
end;
下面的代码就是根据时区转换时间,代码中的timezoneNum指时区号码,例如北京时间为东八区,那么timezoneNum就取值+8,美国休斯顿为西6区,则取值-6:
//根据给定的时区计算时间
procedure TFormTime.btnConvertClick(Sender: TObject);
var
……
begin
try
ParFeature := F_AppGE.GetFeatureByName('nanjing');
FFeatures := ParFeature.GetChildren;
timezoneNum := strtofloat(edZoneNum.Text);
for i := 1 to FFeatures.Count do
begin
if (FFeatures[i].Highlighted <> 0) then
begin
tmpTimeBegin := FFeatures[i].TimeInterval.BeginTime.Clone; //克隆开始时间
tmpTimeEnd := FFeatures[i].TimeInterval.EndTime.Clone; //克隆结束时间
ZoneTimeBegin := tmpTimeBegin.ConvertToZone(timezoneNum); //时区转换后的开始时间
ZoneTimeEnd := tmpTimeEnd.ConvertToZone(timezoneNum);// 时区转换后的结束时间
……
end;
end;
except
//……
end;
end;
转换时间对应的C#代码段:
private void ftTimeZoneChange(string ft_name)
{
FeatureGE ft = appGE.GetFeatureByName(ft_name).GetChildren()[1];
if (ft != null)
{
try
{
//没转换前的时间
TimeGE ftBeginTime1 = ft.TimeInterval.BeginTime;
TimeGE ftEndTime1 = ft.TimeInterval.EndTime;
double ftTZ1 = ft.TimeInterval.BeginTime.TimeZone;
//转换后的时间
TimeGE ftBeginTime2 = ft.TimeInterval.BeginTime.ConvertToZone(-6.0);
TimeGE ftEndTime2 = ft.TimeInterval.EndTime.ConvertToZone(-6.0);
double ftTZ2 = ft.TimeInterval.BeginTime.ConvertToZone(-6.0).TimeZone;
//把这些时间显示出来
txtBeginTime1.Text = ftBeginTime1.Year.ToString() + "年" +
ftBeginTime1.Month.ToString() + "月" +
ftBeginTime1.Day.ToString() + "天";
txtEndTime1.Text = ftEndTime1.Year.ToString() + "年" +
ftEndTime1.Month.ToString() + "月" +
ftEndTime1.Day.ToString() + "天";
txtTimeZone1.Text = "UTC" + ftTZ1.ToString();
txtBeginTime2.Text = ftBeginTime2.Year.ToString() + "年" +
ftBeginTime2.Month.ToString() + "月" +
ftBeginTime2.Day.ToString() + "天";
txtEndTime2.Text = ftEndTime2.Year.ToString() + "年" +
ftEndTime2.Month.ToString() + "月" +
ftEndTime2.Day.ToString() + "天";
txtTimeZone2.Text = "UTC" + ftTZ2.ToString();
} catch {
throw (new Exception("转换出错"));
}
} else {
throw ( new Exception("找不到要素"));
}
}
本例中,通过运行第3章中的KML文件“TimeSpan.kml”,Google Earth创建了一个具有时间段特性的地标,执行后的效果如图5-38所示。
图5-38 时区转换
5.3.5 IAnimationControllerGE接口
IAnimationControllerGE接口定义了Google Earth动画的各种基本的操作方式和属性,这个接口使用较少,因此在这里只做个简单介绍。
1.IAnimationControllerGE方法
IAnimationControllerGE方法介绍如下。
l Play。
Ø 定义:播放动画。
Ø 方程式:procedure Play; safecall;。
l Pause。
Ø 定义:停止播放当前的动画。
Ø 方程式:procedure Pause; safecall;。
2.IAnimationControllerGE属性
IAnimationControllerGE属性介绍如下。
l SliderTimeInterval。
Ø 定义:动画的整个时长,针对的是整个动画文件夹的时长。
Ø 使用方式:读(Get)。
Ø 值类型:ITimeIntervalGE。
Ø 方程式:property SliderTimeInterval: ITimeIntervalGE
read Get_SliderTimeInterval;。
l CurrentTimeInterval。
Ø 定义:动画的当前时长。
Ø 使用方式:读(Get)/写(Set)。
Ø 值类型:ITimeIntervalGE。
Ø 方程式:property CurrentTimeInterval: ITimeIntervalGE
read Get_CurrentTimeInterval
write Set_CurrentTimeInterval;。
5.3.6 IFeatureCollectionGE接口
IFeatureCollectionGE接口定义了要素的集合。Google Earth的官方文档提到了IFeatureCollectionGE接口可以支持如JavaScript或者VBScript脚本,并给出了调用的方法。其实对于服务器端生成的此类集合形式的数组,只要可以取到每一个元素,利用其他的方法也可以通过HTTP浏览器进行操作,如利用Ajax或者WebService均可以对其进行操作。
此接口代表像GetChildren返回的子要素集合等概念,但是此集合的开头序号是从1开始的,而非0,在使用时要加以注意。
1.单个子要素
本节前面介绍了IfeatureGE接口,代表单个地理要素,对于IFeatureCollectionGE要素集合来说,Item属性可以得到某一个确定的要素,如通过遍历要素的序号得到要素。
1)Item
Item介绍如下。
l 定义:要素集合中的子项,返回的是要素对象,index为要素集中的序号,从1开始。
l 使用方式:读(Get)。
l 值类型:IFeatureGE。
l 方程式:property Item[index: Integer]: IFeatureGE
read Get_Item; default;。
关于Item的Delphi代码请参见IApplicationGE接口的GetLayersDatabases方法的实例。
2)Count
Count介绍如下。
l 定义:要素集中的总数,返回的是一个整数,如果为空,则返回0。
l 使用方式:读(Get)。
l 值类型:ITimeIntervalGE。
l 方程式:property Count: Integer
read Get_Count;。
3)Clone
Clone介绍如下。
l 定义:克隆,通常用做对于有只读属性的对象。
l 方程式:function Clone: ITimeGE; safecall;。
2.子要素的操作
要得到IFeatureCollectionGE要素集合的子要素,可以采用GetChildren方法,这个方法的返回值也是IFeatureCollectionGE类型,表示所有子要素的集合。
其定义为得到当前要素,所有子要素的集合。
其方程式为function GetChildren: IFeatureCollectionGE; safecall;。
3.实例分析
这里给出一个实用的小例子的代码:在窗口上有文本框,里面填入父要素的名称,单击按钮得到该父要素下所有子要素,反填到列表框中,用鼠标选择列表框中的选项,同时Google Earth的地址要素栏中的相同要素也会被高亮显示。
代码如下:
unit Unit1;
……
//程序窗口开始创建
procedure TFormFC.FormCreate(Sender: TObject);
begin
try
F_AppGE := CoApplicationGE.Create();
except
showmessage('启动Google Earth失败');
end;
end;
对应的C#代码可参考前面的例子。
//程序窗口关闭
procedure TFormFC.FormClose(Sender: TObject; var Action: TCloseAction);
begin
F_AppGE := nil;
end;
这里通过文本框中的父要素名称,得到要素“parFeature”,然后得到所有其他的子要素,通过for循环遍历所有的子要素,再将子要素逐一添加到列表框lbFeatures中:
//获取要素列表
procedure TFormFC.btnGetListClick(Sender: TObject);
var
FFeatures :IFeatureCollectionGE;
ParFeature : IFeatureGE;
i: integer;
tmpstr : string;
begin
//清空列表框
lbFeartures.Items.Clear;
tmpstr := trim(edParFeature.Text);
ParFeature := F_AppGE.GetFeatureByName(tmpstr);
//获得所有的子要素
FFeatures := ParFeature.GetChildren;
//添加到列表框
for i := 1 to FFeatures.Count do
begin
lbFeartures.Items.Add(FFeatures[i].Name);
end;
end;
C#代码参考:
private string[] getFeatureChildrenNameList(string ft_name)
{
FeatureGE ft = appGE.GetFeatureByName(ft_name);
string[] ftNameList = null;
if (ft != null)
{
ftNameList = new string[ft.GetChildren().Count];
FeatureCollectionGE ftlist = ft.GetChildren();
for (int i = 0; i < ft.GetChildren().Count - 1; i++)
{
ftNameList[i] = ft.GetChildren()[i].Name;
}
return ftNameList;
}
else
{
return null;
}
}
这里利用了IFeatureGE接口的Selected属性,通过for循环遍历所有的子要素,判断该要素是否被鼠标选中,因为这段代码是写在鼠标按下(MouseDown)事件中的,所以当鼠标按下的时候,程序会反向控制Google Earth,从而高亮选择相同的地理要素项目:
//单击要素列表框,操作Google Earth高亮显示该要素
procedure TFormFC.lbFearturesMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
i:integer;
tmpFeature : IFeatureGE;
begin
for i := 0 to lbFeartures.Items.Count-1 do
begin
if (lbFeartures.Selected[i]) then
begin
tmpFeature := F_AppGE.GetFeatureByName(lbFeartures.Items[i]);
tmpFeature.Highlight;
break;
end;
end;
end;
end.
C#代码参考:
private void highlightFtbyName(FeatureCollectionGE ftlist,string ftname)
{
for (int i = 0; i < ftlist.Count - 1; i++)
{
if (ftlist[i].Name == ftname)
{
ftlist[i].Highlight();
} else {
continue;
}
}
}
本程序的逻辑主要是实现如下两个主要功能:
l 取得子要素列表,如图5-39所示。
l 根据Delphi程序中选中的要素,反向控制Google Earth高亮显示该要素。
图5-39 子要素集合
这个例子稍加改动就可以拓展成其他项目的一部分。通过这个例子可以发现当前版本Google Earth的API接口结构很清晰,只要找到正确的接口,开发Google Earth程序就不会太难。
5.3.7 IViewExtentsGE接口
IViewExtentsGE接口描述了Google Earth地图视场的经纬度范围。它仅仅是一个范围的定义而已,并不包含其他的如视角在内的视场定义参数。
所谓视场的四边,是指东、南、西、北4个顶边的经纬度,如图5-40所示。
该接口提供的所有属性都是只读型的,所以不能通过这个接口操作Google Earth改变视场。
1.IViewExtentsGE属性
IViewExtentsGE属性如下。
l North。
Ø 定义:视场的北边,为纬度值。
Ø 使用方式:读(Get)。
Ø 值类型:Double。
Ø 方程式:property North: Double
read Get_North;。
l South。
Ø 定义:视场的南边,为纬度值。
Ø 使用方式:读(Get)。
Ø 值类型:Double。
Ø 方程式:property South: Double
read Get_South;。
l East。
Ø 定义:视场的东边,为经度值。
Ø 使用方式:读(Get)。
Ø 值类型:Double。
Ø 方程式:property East: Double
read Get_East;。
l West。
Ø 定义:视场的西边,为经度值。
Ø 使用方式:读(Get)。
Ø 值类型:Double。
Ø 方程式:property West: Double
read Get_West;。
该接口因为只有4个属性,非常简单,因此在此给出一个Delphi代码。例子中tmpViewExt为一个IViewExtentsGE类型的变量,然后分别获得当前地图视场的东、南、西、北4个边的经纬度数值,显示在文本框中。
2.实例代码
Delphi实例代码:
var F_AppGE: IApplicationGE;
……
procedure TFormViewExtens.btnGetClick(Sender: TObject);
var
tmpViewExt : IViewExtentsGE ;
begin
try
tmpViewExt := F_AppGE.ViewExtents;
edNorth.Text := floattostr(tmpViewExt.North );
edSouth.Text := floattostr(tmpViewExt.South );
edEast.Text := floattostr(tmpViewExt.East );
edWest.Text := floattostr(tmpViewExt.West );
except
//……
end;
end;
C#代码参考:
private void getMapViewExtents()
{
ViewExtentsGE vt = appGE.ViewExtents;
double vt_north = vt.North;
double vt_south = vt.South;
double vt_west = vt.West;
double vt_east = vt.East;
MessageBox.Show("东至:" + vt_east.ToString() +
"西至:" + vt_west.ToString() +
"北至:" + vt_north.ToString() +
"南至:" + vt_south.ToString());
}
代码执行后的效果如图5-41所示。
图5-41 四边经纬度
5.3.8 IPointOnTerrainGE接口
IPointOnTerrainGE接口是IApplicationGE.GetPointOnTerrainFromScreenCoords方法的返回值接口类型,重点突出点位的地理特征,提供了关于地形和点位的操作,对于地球空间上的一点,必然和地形发生着千丝万缕的联系,一个点位必然包括经纬度、高度、投影关系。
但是Google Earth没有提供获取屏幕坐标的操作方法,关于屏幕坐标的操作方法或者属性其实是比较重要的,这一点比较奇怪。虽然程序员可以通过Windows提供的API实现捕捉地图窗口内要素的屏幕点位信息,但是实现起来成本较高,可能Google认为无须给用户提供这个接口。
本接口提供的所有属性都是只读属性。
1.IPointOnTerrainGE属性
1)Latitude
Latitude介绍如下。
l 定义:点位的纬度值。取值从-90°到90°。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property Latitude: Double
read Get_Latitude;。
2)Longitude
Longitude介绍如下。
l 定义:点位的经度值。取值从-180°到180°
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property Longitude: Double
read Get_Longitude;。
3)Altitude
Altitude介绍如下。
l 定义:点位的高度值。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property Altitude: Double
read Get_Altitude;。
Google Earth中点位的高度值的设定和Google Maps有相似的地方,Google Earth的高度属性值受到ElevationExaggeration的影响,如表5-15所示。
表5-15 高度设定关系
ElevationExaggeration | >0 | 0 |
ZeroElevationExaggeration | true | false |
Altitude | 真实高度 | 0 |
4)ProjectedOntoGlobe
ProjectedOntoGlobe介绍如下。
l 定义:判断一个点位是否为投影点,返回值是布尔型。
l 使用方式:读(Get)。
l 值类型:Integer(Bool)。
l 方程式:property ProjectedOntoGlobe: Integer
read Get_ProjectedOntoGlobe;。
5)ZeroElevationExaggeration
ZeroElevationExaggeration介绍如下。
l 定义:是否被顺着地形拉伸而起伏。
l 使用方式:读(Get)。
l 值类型:Integer(Bool)。
l 方程式:property ZeroElevationExaggeration: Integer
read Get_ZeroElevationExaggeration;
2.实例代码分析
此处仅给出了主要代码片段:
//拉伸地形3倍
procedure TForm1.btnExaggerationClick(Sender: TObject);
begin
try
F_AppGE.ElevationExaggeration := 3;
except
//……
end;
end;
对应的C#代码参考:
private void setExaggeration()
{
……
appGE.ElevationExaggeration = 3;
}
在IApplicationGE中有一个坐标转换的方法GetPointOnTerrainFromScreenCoords,可以把屏幕的像素坐标转换为经纬度坐标。下面的例子采用该方法把屏幕中心点转换成经纬度坐标:
//取得屏幕中心点的地理坐标
procedure TForm1.btnTerrainCorrClick(Sender: TObject);
var
tmpPointOnTer: IPointOnTerrainGE;
tmpstr: string;
begin
//从屏幕坐标转换成地理坐标
tmpPointOnTer := F_AppGE.GetPointOnTerrainFromScreenCoords(0,0); tmpstr := '经度:' + floattostr(tmpPointOnTer.Longitude) + #13#10;
tmpstr := tmpstr + '纬度:' + floattostr(tmpPointOnTer.Latitude) + #13#10;
tmpstr := tmpstr + '高度:' + floattostr(tmpPointOnTer.Latitude) + #13#10;
tmpstr := tmpstr + '是否为投影点:' + ConvertIntToBool(tmpPointOnTer.Projected OntoGlobe) + #13#10;
tmpstr := tmpstr + '是否拉伸:' + ConvertIntToBool(tmpPointOnTer.ZeroElevationExag geration) + #13#10;
showmessage(tmpstr);
end;
……
以上的Delphi代码中tmpPointOnTer为从屏幕坐标转换而来的地理坐标(用经纬度表示),以上代码对应的C#参考代码:
private PointOnTerrainGE covertCoordinatesFromScreen()
{
PointOnTerrainGE pt = appGE.GetPointOnTerrainFromScreenCoords(0.0, 0.0);
return pt;
}
代码执行后的效果如图5-42所示。
图5-42 地形点参数
5.3.9 ISearchControllerGE接口
ISearchControllerGE接口是Google Earth的核心功能之一。Google Earth的成功一方面是具有遍布全球的精美的卫星图片;另一方面就是具有几乎无所不能的搜索功能。Isearch ControllerGE是一个搜索控件接口,提供类似与Goolge Earth主界面上“搜索栏”一样的功能,但比“搜索栏”更加灵活,可以通过它,将Google Earth的搜索功能嵌入到自己的程序中。
1.地名搜索
1)Search
Search介绍如下。
l 定义:执行Google Earth搜索。
l 方程式:procedure Search(const searchString: WideString); safecall;。
其参数如表5-16所示。
表5-16 Search参数
参 数 | 输 入 方 向 | 值 类 型 | 定 义 |
searchString | In | WideString | 需搜索的地名字词 |
地名搜索、路线地址搜索都有一个时间超时的阈值,从开始搜索到返回结果这一过程的耗时如果在这个超时阈值之内,可以返回相对应的结果;如果超过这个阈值,则返回E_USAGE_LIMIT_EXCEEDED,表明搜索超时。
最终的搜索结果将在Google Earth的地图窗口或者地址栏中反映出来。
Delphi实例代码:
procedure TForm1.searchClick(Sender: TObject);
var
tmpSearchstr : string;
Isearch : ISearchControllerGE;
begin
tmpsearchstr := edsearch.Text;
Isearch := coSearchControllerGE.Create();
Isearch.Search(tmpsearchstr);
end;
C#代码参考:
private void searchFunction(string searchStr)
{
SearchControllerGE scGe = new SearchControllerGEClass();
scGe.Search(searchStr.Trim());
}
//调用查询函数
private void btnSearch_Click(object sender, EventArgs e)
{ searchFunction("nanjing "); }
在这里,用户自定义的程序窗口代替了Google Earth原来的搜索窗口,输入“beijing”后单击【Search】按钮,程序会自动“飞行”到北京地区,如图5-43所示。
图5-43 搜索接口
注意 | 在搜索的时候需要使用IsSearchInProgress来验证搜索过程是否完全执行完毕。 |
2)IsSearchInProgress
因为Google Earth的搜索过程相对耗时,所以用户不可能“立即”获得搜索结果。通常需要有个等待过程,程序中需要有一个判断是否正在搜索状态中的方法IsSearchInProgress。介绍如下。
l 定义:得到当前要素下所有子要素的集合。
l 方程式:function IsSearchInProgress: Integer; safecall;。
Delphi实例代码请看后面的完整实例。
2.获得结果
ISearchControllerGE接口所获得的结果最终只有两个归结点:搜索结果栏和地图窗口。在搜索结果栏中,会列出所有结果项目,而地图则会“飞行”(fly-To)到最可能的那个结果的所在地,通过调用GetResults方法可以获得结果。
由于返回的结果类型是IFeatureCollectionGE要素集合类型,所以开发人员可以根据需要将要素的名称或者其他属性以多种方式显示在自己的界面上。
获得结果介绍如下。
l GetResults。
Ø 定义:得到符合搜索的所有要素的集合。
Ø 方程式:function GetResults: IFeatureCollectionGE; safecall;。
Delphi实例代码请看后面的完整实例。
l ClearResults。
Ø 定义:清空所有搜索要素集合。
Ø 方程式:procedure ClearResults; safecall;。
3.实例分析
unit Unit1;
……
uses EARTHLib_TLB;
{$R *.dfm}
var
F_AppGE: IApplicationGE;
tmpSearch : ISearchControllerGE;
单击【搜索】按钮,将名为【edSearchStr】的文本框中的搜索内容作为搜索的条件,在搜索之后,将搜索的结果添加入列表框中:
procedure TFormSearch.btnSearchClick(Sender: TObject);
var
searchStr : string;
IFeaList: IFeatureCollectionGE;
i:integer;
begin
//清空要素列表框
lbSearch.Items.Clear;
searchStr := Trim(edSearchStr.Text);
//搜索
tmpSearch := coSearchControllerGE.Create;
tmpSearch.Search(searchStr);
IFeaList := tmpSearch.GetResults;
//往搜索框中添加结果要素
for i := 1 to IFeaList.Count do
begin
lbSearch.Items.Add(IFeaList[i].Name);
end;
//检查搜索是否完毕
if (tmpSearch.IsSearchInProgress <> 0) then
begin
showmessage('查询完毕!');
end;
end;
C#代码参考:
private FeatureCollectionGE searchFunction(string searchStr)
{
//新的搜索对象
SearchControllerGE scGe = new SearchControllerGEClass();
scGe.Search(searchStr.Trim()) ;
//得到搜索结果
FeatureCollectionGE ftList = scGe.GetResults();
if (scGe.IsSearchInProgress() == 0)
{
MessageBox.Show("查询完毕!");
return ftList;
} else {
return null;
}
}
窗体启动的时候,启动一个Google Earth进程:
procedure TFormSearch.FormCreate(Sender: TObject);
begin
try
F_AppGE := CoApplicationGE.Create();
except
showmessage('启动Google Earth失败');
end;
end;
关于上面这段C#代码请参考前面5.3.1节中的Google Earth启动代码:
关闭窗体时候,释放Google Earth的进程控制,代码如下:
procedure TFormSearch.FormClose(Sender: TObject; var Action: TCloseAction);
begin
F_AppGE := nil;
end;
在大部分情况下需要清空搜索的结果,可使用ClearResults来完成清空结果工作,此时Google Earth的搜索结果界面上就会有相应的清空动作,如下:
procedure TFormSearch.btnClearClick(Sender: TObject);
begin
try
tmpSearch.ClearResults;
showmessage('已经清空Google Earth搜索结果。');
except
end;
end;
end.
C#代码参考:
private void clearSearch()
{
scGe.ClearResults();
}
5.3.10 ITimeIntervalGE接口
ITimeIntervalGE接口表示Google Earth中的时间段。接口中提供的属性全部为只读属性。
1.属性
ITimeIntervalGE属性如下。
l BeginTime。
Ø 定义:表示时间段的开始时间,返回时间类型为ITimeGE。
Ø 使用方式:读(Get)。
Ø 值类型:ITimeGE。
Ø 方程式:property BeginTime: ITimeGE
read Get_BeginTime;。
l EndTime。
Ø 定义:表示时间段的结束时间,返回时间类型为ITimeGE。
Ø 使用方式:读(Get)。
Ø 值类型:ITimeGE。
Ø 方程式:property EndTime: ITimeGE
read Get_EndTime;。
2.实例代码
Delphi实例代码:
procedure TForm1.BtnGetTimeIntervalClick(Sender: TObject);
var
FFeatures :IFeatureCollectionGE;
ParFeature : IFeatureGE;
i: integer;
tmpstrBegin,tmpstrEnd : string;
tmpYear,tmpMonth,tmpDay:integer;
begin
ParFeature := F_AppGE.GetFeatureByName('nanjing');
FFeatures := ParFeature.GetChildren;
for i := 1 to FFeatures.Count do
begin
if (FFeatures[i].Highlighted <> 0) then
begin
tmpYear := FFeatures[i].TimeInterval.BeginTime.Year;
tmpMonth := FFeatures[i].TimeInterval.BeginTime.Month;
tmpDay := FFeatures[i].TimeInterval.BeginTime.Day;
tmpstrBegin := inttostr(tmpYear) + '-'+ inttostr(tmpMonth) + '-' +inttostr (tmpDay);
tmpYear := FFeatures[i].TimeInterval.EndTime.Year;
tmpMonth := FFeatures[i].TimeInterval.EndTime.Month;
tmpDay := FFeatures[i].TimeInterval.EndTime.Day;
tmpstrEnd := inttostr(tmpYear) + '-'+ inttostr(tmpMonth) + '-' +inttostr (tmpDay);
end;
end;
showmessage('开始时间是:' + tmpstrBegin + #13#10 + '结束时间是:' + tmpstrEnd);
end;
此处的C#代码可参考5.3.4节中的TimeInterval的操作实例。
首先用Google Earth程序打开本书第3章的KML代码TimeSpan. kml,然后执行。
以上的Delphi代码,分别取出了开始和结束时间的年、月、日的参数值,执行结果如图5-44所示。
5.3.11 ITourControllerGE接口
ITourControllerGE是设置和控制Google Earth漫游的接口。
1.ITourControllerGE属性
1)speed
speed介绍如下。
l 定义:描述了Google Earth视场移动的速度,Speed是取值在0~5之间的双精度型小数,无法通过程序修改。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property speed: Double
read Get_speed
write Set_speed;。
Delphi实例代码:
procedure TForm1. getFlySpeedDelayClick (Sender: TObject);
var
flycycle : double;
begin
flycycle := F_AppGE.TourController.speed;
showmessage(floattostr(flycycle));
end;
C#代码参考:
private double getSpeed()
{
TourControllerGE TourGE = appGE.TourController;
if (TourGE != null)
{
return TourGE.speed;
} else {
return -1;
}
}
执行后的效果如图5-45所示,这里的取值是【Tools】→【Options】命令中【Fly-To Speed】设置框中的数值。中文版Google Earth的菜单对应项目为【工具】菜单项中的【选项】,然后在弹出窗口中选择【导航】页面即可。
2)PauseDelay
PauseDelay介绍如下。
l 定义:描述了每次视点“飞行”停止的时长。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property PauseDelay: Double
read Get_PauseDelay
write Set_PauseDelay;。
以1/10秒计,取值为0.0~60.0。
Delphi实例代码:
procedure TForm1. getFlyPauseDelayClick(Sender: TObject);
var
flycycle : double;
begin
flycycle := F_AppGE.TourController.PauseDelay;
showmessage(floattostr(flycycle));
end;
C#代码参考:
private double getFlyPauseTime ()
{
TourControllerGE TourGE = appGE.TourController;
if (TourGE != null)
{
return TourGE.PauseDelay;
} else {
return -1;
}
}
执行后的效果如图5-46所示,这里的取值是【Tools】→【Options】命令中【Tour Pause】设置框中的数值。
图5-45 飞行速度 图5-46 暂停时间
3)Cycles
Cycles介绍如下。
l 定义:漫游飞行的循环次数。
l 使用方式:读(Get)。
l 值类型:Double。
l 方程式:property Cycles: SYSINT
read Get_Cycles
write Set_Cycles;。
取值范围是0~9 999,超过9 999则表示无限循环漫游。
Delphi实例代码:
procedure TForm1.getFlyCyclesClick(Sender: TObject);
var
flycycle : integer;
begin
flycycle := F_AppGE.TourController.Cycles ;
showmessage(inttostr(flycycle));
end;
C#的代码参考:
private int getFlyCycles()
{
TourControllerGE TourGE = appGE.TourController;
if (TourGE != null)
{
return TourGE.Cycles;
} else {
return -1;
}
}
执行后的效果如图5-47所示,这里的取值是【Tools】→【Options】命令中【Tour Pause】设置框中的数值。
图5-47 循环次数
2.ITourControllerGE方法
1)PlayOrPause
PlayOrPause介绍如下。
l 定义:继续飞行或者暂停,每执行一次,就重复一次飞行和暂停。
l 方程式:procedure PlayOrPause; safecall;。
Delphi实例代码:
procedure TForm1.flypauseClick(Sender: TObject);
begin
F_AppGE.TourController.PlayOrPause;
end;
C#的代码参考:
private void PauseFly()
{ appGE.TourController.PlayOrPause(); }
2)Stop
Stop介绍如下。
l 定义:停止飞行。
l 方程式:procedure Stop; safecall;。
l Delphi实例代码:
procedure TForm1.flystopClick(Sender: TObject);
begin
F_AppGE.TourController.Stop;
end;
C#的代码参考:
private void stopFly()
{ appGE.TourController.Stop();}