首页 > 文章中心 > 正文

谷歌地图在铁路选线中的技术研究

谷歌地图在铁路选线中的技术研究

1引言

GoogleEarth(以下简称GE)是一款由Google公司开发的三维可视化地球软件,它把卫星影像、航空照片、三维地面模型等GIS信息布置在一个地球的三维模型上[1]。GE提供了丰富、免费的全球不同分辨率的遥感影像数据;GE使用单圆柱投影,并使用WGS84基准面作为其平面基准,GE所采用的坐标系统是WGS-84坐标系;GE采用开放的数据标准和规范,并提供二次开发的API接口。GE所具备的这三个特点说明GE同传统地图一样具备表达和传递地形、地物信息的功能;建立在严密的数学模型下;拥有二次开发的接口。GE具有这三个特点使它能够作为铁路选线设计的一个平台,满足铁路选线设计一定阶段内设计需求,并且具有实时三维显示的巨大优势,这是传统基于CAD选线设计平台所不能比及的[2]。结合传统的基于CAD平台铁路选线设计过程和特点,基于GE平台进行铁路选线设计的过程主要分为平面设计和纵断面设计[3]。区别在于在如何实现在GE平台中实现选取交点,获取点位信息;完成平面设计工作,如何提取地面线,进行下一步的纵断面设计,所有的设计元素都要以一定的形式展示出来,在GE中通过KML文件的格式将各种元素显示,因此本文重点对基于GE平台进行铁路选线设计中,实现平面设计功能、提取地面线进行研究,KML技术进行研究。本文所论述的平台系统是的开发是采用C#语言,采用的开发平台是Micro-softVisualStudio2005,在开发过程中将GE客户端放入到系统自定义的窗体中。

2平面设计

要实现在GoogleEarth上进行选线设计,通过鼠标点击实现在GoogleEarth上进行选点,但是由于GoogleEarth软件在开发过程对其操作的各种鼠标事件都进行了定义,我们无法完成自己的功能,这里就要利用WindowsAPIHOOK技术,获取操作系统发送给GoogleEarth地图窗口的某些消息(如在地图窗口单击,缩放滚轮等消息)。GoogleEarthCOMAPI类库中提供了成员函数用来将客户端坐标系中点的屏幕坐标转换为改点的地理坐标(经纬度的形式),利用该函数,最终实现对平面选取的交点地理位置信息的获取。

2.1WindowsAPIHook技术微软的Windows操作系统是建立在事件驱动的机制上的,钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程序以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它,钩子机制允许应用程序截获处理window消息或特定事件[4]。钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。HookAPI是指Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制。在本系统的开发中,通过钩子钩住了GoogleEarth软件定义下的鼠标单击MouseDown事件。在程序中实现的如下:mouseHook.MouseDown+=newMouseEventH-andler(mouseHook_MouseDown);通过Hook技术实现了获取鼠标点击目标点时,目标点所在位置的屏幕坐标,这是实现GE平台平面选线最关键的技术之一。

2.2四种坐标系概述利用Hook技术,获取到了目标点的屏幕坐标,我们最终目标是获取目标点的在GE下的地理坐标。在整个系统的开发中,涉及到四种坐标系统:屏幕坐标系、工作区坐标系、GoogleEarth客户端坐标系,WGS84坐标系。屏幕坐标系是Windows窗体应用程序用屏幕坐标指定窗口在屏幕上的位置。对于屏幕坐标而言,原点是屏幕的左上角。窗口的完整位置通常用Rectangle结构来描述,该结构包含定义窗口的左上角和右下角的两个点的屏幕坐标[1]。屏幕坐标系如图1所示。Windows窗体应用程序使用工作区坐标指定窗体或控件中的点的位置。在C#中即Form窗体的坐标系,即系统的界面窗体,工作区坐标的原点是控件或窗体的工作区的左上角,它同Windows窗体坐标系是一致的。工作区坐标确保了无论窗体或控件在屏幕上的位置如何,应用程序在窗体或控件中绘制期间都可以使用一致的坐标值。GoogleEarth客户端坐标系[5],是GE在当前视图下,自定义的一种坐标系统,GoogleEarth客户端坐标系如图2所示。

2.3屏幕坐标向工作区坐标的转换在C#语言中,通过使用Control类中的Point-ToClient和PointToScreen方法就可以实现两种坐标系下的坐标转换,要用到的是PointToClient将指定屏幕点的位置计算成工作区坐标,该函数语法为:publicPointPointToClient(Pointp)参数p表示要转换的屏幕坐标Point,该函数返回一个Point,它表示转换后的Poin(t以工作区坐标表示)[6]。

2.4工作区坐标向GoogleEarth客户端坐标的转换通过对两种坐标系的分析,总结出两种坐标系三点区别。(1)坐标系原点不同。前者在整个坐标系左上角,后者居整个坐标系中心。(2)Y方向相反,坐标值有差异。前者坐标都为正值,后者坐标有正有负。(3)单位不同,前者是以整个工作区大小(宽度和高度),后者的范围在正1至负1中间。基于以上三点,对两种坐标系下的坐标做出转换,首先利用C#提供的函数,获取当前工作区的宽度和高度,然后找出两种坐标系的数学关系,具体如下。width=this.FindForm().Width;hight=this.FindForm().Height;x=(X-width/2)/width*2;y=(Y-hight/2)/hight*2;width:当前工作的宽度;hight当前工作区高度;x、y:GoogleEarth客户端坐标;X、Y:工作区的坐标。2.5GoogleEarth客户端坐标向WGS84坐标的转换GECOMAPI的类库中提供了成员函数[7]:Ge-tPointOnTerrainFromScreenCoords(),该成员函数用来将客户端视图中的点的屏幕坐标转换为经纬度的形式。该函数语法为:IPointOnTerrainGEGetPointOnTerrainFromS-creenCoords(doublescreen_x,doublescreen_y)该函数接受两个Double类型的参数,表示视图中心点在GoogleEarth客户端坐标系中的坐标值,这两个参数值均在-1和1之间,该函数的返回值为IPointOnTerrainGE型。至此,获取到了目标点地理坐标,解决了在GE平台中平面设计最关键的问题。

3地面线的提取

平面设计工作完成之后,就要进行纵断面设计工作,而首先是获取线位的地面线。GoogleEarthCOMAPI的类库中提供了成员函数SetCameraPa-rams(),该成员函数实现将视图中心移动到用户指定位置。该函数语法为:voidSetCameraParams(doublelat,doublelon,doublealt,EARTHLib.AltitudeModeGEaltMode,doubleRange,doubleTilt,doubleAzimuth,doublespeed)。该函数接受八个输入参数,除了altMode,其余均为double型。函数返回值为void,其中lat、lon和alt表示视图中心的经纬度和高程;range表示视高;speed表示从当前视图移动到设定点的速度;tilt表示用户视线和垂直地平线方向的夹角。Azimuth即测绘学在中的方位角,表示用户视线和正北方向的夹角,altMode表示高程的形式,为AltitudeM-odeGE型,该类型是一个枚举变量,包括Absol-uteAltitudeGE和RelativeToGroundAltitudeGE两个取值,当用户在当前视图设置地标时,RelativeTo-GroundAltitudeGE取值等于地标的高程值是相对于该位置地面的高度差异,即相对高程,Absol-uteAltitudeGE代表的高程值是相对于海平面得高度差异,即绝对高程。在平面设计完成之后,可以得到线路上任意一里程的坐标值,要想获取该里程的地面高程,需要把该里程的坐标值作为参数,传递给GoogleEarth的API函数SetCameraParam(s),实现将客户端的视图中心移动到该里程点的位置,此时该点在GoogleEarth客户端坐标系下的坐标是(0,0),即坐标系的原点,然后就可以调用GoogleEarth的API函数GetPointOnTerrainFromScreenCoord(s),来获取该点的地面高程,这样就完成了线位上任一点地面高程的获取,进而获取整个线位的地面线。需要注意的一点是,获取地面线的过程,要保证GoogleEarth客户端处于打开状态,在读取地面线的过程中,不要进行其他操作,以免影响客户端的移动,为了保证获取地面线的精度,利用SetCa-meraParams()函数时,在设定speed的值时,不要取的太大,一般取为2,在进行程序设计中,读取点是做一个循环,最好在每一个操作之间设置一个时间间隔,以保证读取的精度,实现方法是让主进程休眠一定得时间。

4KML技术

KML是一种基于XML语法的标记语言和数据扩展格式,通过生成KML文件,就能够将点、线、多边形、图片等显示在GE中,所以在系统开发中,要实现对KMl文件的编程控制[8]。C#中类FileStream,这个类提供了在文件中读写字节的方法,要创建FileStream对象。该类的构造函数具有许多不同的重载版本,在我们程序中要采用的是:FileStream(filePath,FileMode.OpenOrCreate,FileAccess.ReadWrite,FileShare.Read)因为在程序设计中,当创建完KML文件后,就要打开,这就要用到FileShare.Read,这种模式代表允许随后打开文件读取,其他的重载版本是无法实现这一功能的。KMl文件是类XmlTextWriter的对象,创建的对象包含XML数据(这些数据符合W3C可扩展标记语言(XML)1.0和“XML中的命名空间”建议)的流或文件[9]。该类的定义为:XmlTextWriter(stringfilename,Encodingenco-ding)第一个参数就是要写入的文件名,第二个参数,表示要生成的编码方式。GoogleEarth定义的KML文件是UTF-8的形式,所以在程序设计中,创建该类的对象是,这里取的是UTF-8。对KML文件的打开是通过GoogleEarthCOMAPI提供的函数OpenKmlFile来实现的,该函数的定义为:voidOpenKmlFile(stringfileName,intsuppres-sMessages)该函数接受两个输入参数,参数一“fileName”,是一个字符的类型,表示需要打开的文件名和包含文件路径的,例如:@“E:\大论文\Line5.kml”。第二个参数取值为“0”或者“1”,表示当用户要开的文件和GoogleEarth中已经存在的文件如果有冲突,是否处理这种异常情况,一般取为“1”[10]。

5结论

本文分析研究了基于GE平台进行铁路选线设计中遇到的关键问题,并提出了详细的解决方法。基于GE平台进行铁路选线设计的系统研究,涉及大地测量学、图形图像处理、数据库应用、软件工程、铁路选线设计等多个学科的知识体系,限于研究者知识水平所限,对平台系统的研究才算刚刚起步。但随着对GE的深入研究,GE在铁路选线设计中将会发挥巨大的作用。