Google Earth 卫星地图影像数据获取与应用.doc_第1页
Google Earth 卫星地图影像数据获取与应用.doc_第2页
Google Earth 卫星地图影像数据获取与应用.doc_第3页
Google Earth 卫星地图影像数据获取与应用.doc_第4页
Google Earth 卫星地图影像数据获取与应用.doc_第5页
已阅读5页,还剩15页未读, 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Google Earth 卫星地图影像数据获取与应用Google 公司通过Google Earth数字化平台和互联网络,向全世界免费发布其所拥有的全球卫星影像数据。本文阐述如何从Google Earth数字平台获得用户关心区域的地图卫星影像。1 地图卫星影像获取方案通过重写Google Earth的KML数据文件,将用户关心的区域以“路标”点阵的方式写入KML数据文件;然后利用Google Earth提供的游览功能,自动播放KML文件;与此同时使用智能抓图软件,同步将播放图像保存为本地数据文件,完成地图卫星影像获取。1.1 “路标”点阵写入KML文件Google Earth允许用户在地图上感兴趣的特定位置处设置标志,即“路标”(Place Mark),它是Google Earth定义的一种空间点类型,包括路标名称、位置(经纬度、高度)、视角、等信息。为了能够一次获取一个地区的全部图像,需要在该地区所在的空间范围内布置“路标”点阵。Google Earth提供了添加和编辑“路标”的功能,但是要获取一个地区的地图卫星影像,就必须采用直接写入KML数据文件的方式,将区域所包含的大量的“路标”点阵写入Google Earth中。Google Earth的KML数据文件是一种通用非结构化数据文件(XML格式),通过KML数据文件,用户可以实现与Google Earth软件的沟通与交流。KML数据文件包括文件头、数据体、文件结束三部分。附件1是一个Google Earth软件使用的KML数据文件例子。- DQ47_05_125_00 - 125 47.0833333333333 8000 0 0 - - ffff00ff - 1 KML数据文件的具体访问方法参考DQMAP主程序KML写入部分及XMLU.PAS单元。写入KML数据文件时, 通过设置Placemark数据类型,将用户关心的区域进行覆盖。下图是Placemark数据类型的格式,重要的是将Placemark的空间位置(经度、纬度、高度)设置正确,其中经度、纬度数据单位是度,高度和视距单位是m。经度、纬度的计算方法根据视距和每屏覆盖的经差范围和纬差范围确定。保证相邻图像适度重合,然后计算每一幅图像的中心位置。1.2 自动播放KML文件将KML调入Google Earth,在Google Earth的Option菜单中设置控制参数。关键是要根据网速,设置图像的停顿时间,以便让Google Earth有充足的时间将图像数据通过网络从远端图像数据服务器传到本地。一般宽带网设置停顿时间为10-30秒,另外,为了加快抓图速度,可以先浏览一、两次,提前将数据下载到Google Earth在本地的Cache数据文件中,在实际抓图时,Google Earth可以以较快的速度从Cache数据文件中获取数据,此时可以将停顿时间缩短,一般4秒即可。1.3 智能抓图智能抓图与播放KML文件同时进行,抓图功能由DQMAP软件提供。DQMAP可以根据Google Earth播放KML数据文件的进程,抓到最清晰的图像,并保存到设置的文件夹中。为了保证抓图与播放动作同步,DQMAP软件在写KML文件和抓图时,在安排“路标”阵列与抓图数据文件名称时,采用一对一的关系。“路标”阵列的安排如下: With DQ800CurrentSec do For j:=0 to ACol -1 do begin Lon:=LonSt+j*DLon; For i:=0 to ARow-1 do begin Lat:=LatSt-i*DLat; XMLDoc_WritePlaceMark(F,Prefix+FormatDegSecRound(Lat)+_+ FormatDegSecRound(Lon), Lon,Lat,DQ800CurrentSec.Scale,False); end; end;由定时器和图像自动识别单元组成的抓图图像文件列表安排如下: With DQ800CurrentSec do For j:=0 to ACol -1 do begin Lon:=LonSt+j*DLon; For i:=0 to ARow-1 do begin Lat:=LatSt-i*DLat; fn:=GetImageFileNameRound(Path,Prefix,Lat,Lon,NameLen,CheckBox1.Checked); Inc(k); SetLength(BMPFName,k); BMPFNamek-1:=fn; end; end;2 图像数据的组织与使用2.1 ImageSect数据类型声明了两个实例DQ800,DQUnits:TImageSecArr,分别代表区域数列和当前区域的图像数列。它们具有相同的数据类型。TImageSecArr=Array of TImageSec;其中ImageSect是为了描述一个区域或图像数据而定义的数据类型。 TImageSec=record LatSt,LonSt:Real; /区域或图像的起点,左上 LatEn,LonEn:Real; /区域或图像的终点,右下 DLat,DLon:Real; /区域或图像的范围纬差,经差 NERange:RangeType; /区域或图像的范围(MinP(左下),MaxP(右上)) Rows,Cols:Integer; /图像的行数、列数 Scale:Real; /视距,视野宽度 Lats,Lons:TpVector; /图像行阵列的纬度、图像行阵列的经度 NameLen:Integer; /2 for DD_MM,3 for DD_MM_SS SecDir, Path, Prefix, /图像的存放目录 SecName:String; /区域名称 SizeX,SizeY:Integer; /图像单元的像素尺寸,图像的宽度、高度像素数 Width,Height:Integer; /区域图像尺寸(估计),宽度、高度像素数 PixelToX,PixelToY:Real; /水平像素系数,垂直像素系数 WidToHei:Real; /垂直水平比例(估计) ImageLoaded:Boolean; MinScale,MaxScale:Real; /可见图像的比例尺范围 ID:String16; /数据库中区域的ID号 end;2.2 数据库将DQ800,DQUnits数据存放到数据库文件中,以便访问。附录3是从数据库文件中读取DQ800数据的程序段。下面是写当前Section 的程序段。With ASec doFor i := 0 to Rows doFor j := 0 to Cols doBeginFName:=GetImageFileNameRound(Path,Prefix,Lats.veci,Lons.vecj,NameLen,IsGrided);FieldByName(ID).asString:=UnitID;FieldByName(SectName).asString:=FName;FieldByName(SectDir).asString:=SecDir;FieldByName(MainPath).asString:=Path;UnitLatSt:=LatSt-DLat*i;UnitLonSt:=LonSt+DLon*j;FieldByName(LatSt).asFloat:=UnitLatSt;FieldByName(LonSt).asFloat:=UnitLonSt;Deg2DMS(UnitLatSt,DD,MM,SS);FieldByName(LatStDD).asinteger:=DD;FieldByName(LatStMM).asinteger:=MM;FieldByName(LatStSS).asinteger:=SS;Deg2DMS(UnitLonSt,DD,MM,SS);FieldByName(LonStDD).asinteger:=DD;FieldByName(LonStMM).asinteger:=MM;FieldByName(LonStSS).asinteger:=SS;UnitLatEn:=LatSt-DLat*(i+1);UnitLonEn:=LonSt+DLon*(j+1);FieldByName(LatEn).asFloat:=UnitLatEn;Deg2DMS(UnitLatEn,DD,MM,SS);FieldByName(LatEnDD).asinteger:=DD;FieldByName(LatEnMM).asinteger:=MM;FieldByName(LatEnSS).asinteger:=SS;FieldByName(LonEn).asFloat:=UnitLonEn;Deg2DMS(UnitLonEn,DD,MM,SS);FieldByName(LonEnDD).asinteger:=DD;FieldByName(LonEnMM).asinteger:=MM;FieldByName(LonEnSS).asinteger:=SS;FieldByName(DLat).asFloat:=DLat;FieldByName(DLon).asFloat:=DLon;FieldByName(Rows).asFloat:=Rows;FieldByName(Cols).asFloat:=Cols;FieldByName(Scale).asFloat:=Scale;FieldByName(NameLen).asInteger:=NameLen;FieldByName(Prefix).asString:=Prefix;FieldByName(SizeX).asInteger:=SizeX;FieldByName(SizeY).asInteger:=SizeY;FieldByName(Width).asInteger:=Width;FieldByName(Height).asInteger:=Height;FieldByName(PixelToX).asFloat:=PixelToX;FieldByName(PixelToY).asFloat:=PixelToY;FieldByName(WidToHei).asFloat:=WidToHei;l:=1;For m:=i-1 to i+1doFor n:=j-1 to j+1doIf (mi)or(nj) thenBeginXUnitID:=ID+I2S0(m,3)+I2S0(n,3);XFName:=GetImageFileNameRound(Path,Prefix,Lats.vecm,Lons.vecn,NameLen,IsGrided);IfFileExists(XFname)thenBeginFieldByName(ID+Inttostr(l).AsString:=XUnitID;End;Inc(l);End;Post;End;下面是读当前Section 的程序段。LoadAUnit(ATable,ASec) With ATable,ASec,ImageSecOfs do begin SecName:=FieldByName(SectName).asString; SecDir:=FieldByName(SectDir).asString; Path:=FieldByName(MainPath).asString; LatSt:=FieldByName(LatSt).asFloat; LonSt:=FieldByName(LonSt).asFloat; LatEn:=FieldByName(LatEn).asFloat; LonEn:=FieldByName(LonEn).asFloat; DLat:=FieldByName(DLat).asFloat; DLon:=FieldByName(DLon).asFloat; NERange.MinP:=Get3DPoint(LatEn+DLat/2+MinP.Y/3600)*PI/180,(LonSt-DLon/2+MinP.X/3600)*PI/180,0);NERange.MaxP:=Get3DPoint(LatSt+DLat/2+MaxP.Y/3600)*PI/180,(LonEn-DLon/2+MaxP.X/3600)*PI/180,0); NameLen:=FieldByName(NameLen).asInteger; Prefix:=FieldByName(Prefix).asString; SizeX:=FieldByName(SizeX).asInteger; SizeY:=FieldByName(SizeY).asInteger; Width:=FieldByName(Width).asInteger; Height:=FieldByName(Height).asInteger; PixelToX:=FieldByName(PixelToX).asFloat; PixelToY:=FieldByName(PixelToY).asFloat; WidToHei:=FieldByName(WidToHei).asFloat; ImageLoaded:=False; end;读DQUnits数据Procedure LoadUnit(ATable:TAdoQuery; SecTbName,SecDir:String; IsGrided:Boolean);OverLoad;Var k:Integer; SqlStr:String;begin With ATable do begin Try Open; First; k:=0; If RecordCount=0 then exit; SetLength(DQUnits,RecordCount); While Not eof do begin LoadAUnit(ATable,DQUnitsk,IsGrided); Inc(k); Next; end; except end; end;end;2.3 图像显示包括可缩放的图像显示和原始尺寸图像显示。图像显示重点解决图像映射、图像变形等问题。图像映射需要考虑用户坐标、屏幕坐标和图像坐标之间的对应关系,参考附件4。(1)图像缩放显示图像缩放显示的原理是同步处理图像覆盖的实际用户区域与屏幕显示区域的关系以及实际图像与缩放后图像之间的关系。图像覆盖的实际用户区域与屏幕显示区域的关系用MapScreen实现;实际图像与缩放后图像之间的关系是通过MapImage实现。见附件5。显示流程如下:1)使用MapScreen将图像的范围映射到屏幕上对应的区域Dest(可见部分);2)如果Dest为空,退出;3)使用CopyRect,将屏幕上Dest对应的内容复制到临时图象Temp中;4)使用MapImage,将Dest对应的范围映射到原始图像上对应的区域Source;5)使用CopyRect,将原始图像上区域Source对应的部分复制到Temp0;6)使用DistortPic,将Temp0、Temp合成(暂存在Temp中);7)使用CopyRect,将Temp中的图象复制到目标Canvas上。下文是显示图像的程序段。Procedure ShowMapImage(Var BBMP:TBitMap;Image:TRasterImage);OverLoad;Var Dest,Source:TRect; Dest0,Source0:TRect; Temp,Temp0:TBitMap; VisRange:RangeType; Scale:Real;With BBMP,Canvas,Image,XYRange doBegin Dest:=MapScreenP(XYRange); /求图象在屏幕中的显示区域 Scale:=abs(Dest.Top-Dest.Bottom)/Height; /显示比例尺 Dest:=RectAnd(Dest,Rect(0,0,Width,Height); /求能见的图像显示区,交集 Dest0:=RectTrim(Dest); /归一化为局部区域 If (Dest0.Right0) and (Dest0.Bottom0) then /目标区域不空时才显示,important If ScaleImageZoomScale then /在可见范围才显示 begin Temp:=TBitmap.Create; /临时图像 ,存放当前屏幕内容 Try SetBMPSize(Temp,Dest0); /用Dest0设置临时图像尺寸 Temp.Canvas.CopyRect(Dest0,Canvas,Dest); /将屏幕对应区复制到临时图像TEMP VisRange:=AndRange(XYRange,CurrentRelPort.RVRange); /求图象在UCS中的可见区域 Source:=MapImage(VisRange,XYRange,BMP.Width,BMP.Height); /映射UCS可见区到图像坐标系 Source0:=RectTrim(Source); /将Source 归一化 If (Source0.Right0) and (Source0.Bottom0) then / begin Temp0:=TBitmap.Create; Try SetBMPSize(Temp0,Source0); /用设置临时图像尺寸 Temp0.Canvas.CopyRect(Source0,BMP.Canvas,Source); /将Source0复制到Temp0中 DistortPic(Temp0.Handle,Temp.Handle,Temp.Canvas.Handle,0,Transparent);/缩放后存Temp CopyRect(Dest,Temp.Canvas,Dest0); /将Temp中的图象复制到目标Canvas Finally Temp0.Free; end; end; Finally Temp.Free; end; end;end;(2)图像变形显示处理图像变形更复杂,需要考虑视角、球面与平面之间的映射等问题。通过设置局部用户坐标,可以在某种程度绕过处理图像变形显示的问题。(3)阵列显示作为底图显示时,通常需要显示大量的图像阵列。在显示大量的图像时,需要重点解决的问题是显示反映的速度和减少对内存的过度需求。实际上,上述需求是相互矛盾的,为了加速显示速度,通常采用双缓存机制,这需要开辟一个内存区,用于后台的图像调入,这必然占用大量的内存。实际上,对于图像处理的硬件要求中,内存是一个关键数据。因此,好的解决方案在于寻求一个折衷的方案,在速度和内存上都能够达到用户的需求。(4)由定时器控制显示 With CurrentMap,DM1 do Begin NE:=XY2BL(PR2.Y,PR2.X); If AutoRasterImageSec then Begin NewSec:=SectionExists(NE); If NewSecCurrentSec then If NewSec=0 then Begin FreeAllRasterImage; CurrentSec:=NewSec; ImageSecName:=DQ800CurrentSec.SecName; LoadImageOfs(AdoQuery1,Sections,ImageSecName); LoadUnit(AdoQuery1,Units,ImageSecName,ImageGridFormat); End; End; CurrImage:=ImageExists(NE); If CurrImage0 then exit; With DQUnitsCurrImage,CurrentRelPort.RVRange do Begin If ImageLoaded then exit; If ImageGridFormat then Fn:=Path+Grid else Fn:=Path+; Fn:=fn+SecName; If FileExists(Fn) Then Begin AppendRasterImage(Fn,LayerNo(底图),NERange); ImageLoaded:=True; GMapLoaded; LocalShowScater; End; End; End;end;3 图像重定位正确显示图像,需要对获得的图像进行重定位。通过调整图像范围(XYRange)、核心区域尺寸(SizeX、SizeY)或重叠区宽度(DX、DY)、图像偏移(Ofs)、图像的长宽比例(WidetoHeight)等。3.1 图像偏移ImageSec的ImageSecOfs从数据库中取数据的程序体。 With ImageSecOfs do Begin MinP.X:=FieldByName(OfsMinE).AsFloat MinP.Y:=FieldByName(OfsMinN).AsFloat MaxP.X:=FieldByName(OfsMaxE).AsFloat MaxP.Y:=FieldByName(OfsMaxN).AsFloat end; With ImageSecOfs2 do Begin MinP.X:=FieldByName(OfsMinE2).AsFloat MinP.Y:=FieldByName(OfsMinN2).AsFloat MaxP.X:=FieldByName(OfsMaxE2).AsFloat MaxP.Y:=FieldByName(OfsMaxN2).AsFloat end; If UseLocalCentreLon then With ImageSecOfs do Begin MinP.X:=MinP.X+ImageSecOfs2.MinP.X; MaxP.X:=MaxP.X+ImageSecOfs2.MaxP.X; MinP.Y:=MinP.Y+ImageSecOfs2.MinP.Y; MaxP.Y:=MaxP.Y+ImageSecOfs2.MaxP.Y; End;With ASec,ImageSecOfs dobegin LatSt:=FieldByName(LatSt).asFloat; LonSt:=FieldByName(LonSt).asFloat; LatEn:=FieldByName(LatEn).asFloat; LonEn:=FieldByName(LonEn).asFloat; DLat:=FieldByName(DLat).asFloat; DLon:=FieldByName(DLon).asFloat; With NERange doBeginMinP:=Get3DPoint(LatEn+DLat/2+MinP.Y/3600)*PI/180,(LonSt-DLon/2+MinP.X/3600)*PI/180,0);MaxP:=Get3DPoint(LatSt+DLat/2+MaxP.Y/3600)*PI/180,(LonEn-DLon/2+MaxP.X/3600)*PI/180,0);End;End;20附件附件1 Google Earth 的KML数据文件 - - - - - root:/icons/palette-3.png 224 32 32 - ffff00ff - My Places 1 - DQ_125_00 1 - DQ46_49_125_00 - 125 46.8166666666667 8000 0 0 - - ffff00ff - 1 - DQ46_57_125_00 - 125 46.95 8000 0 0 - - ffff00ff - 1 - DQ47_13_125_00 - 125 47.2166666666667 8000 0 0 - - ffff00ff - 1 - DQ47_21_125_00 - 125 47.35 8000 0 0 - - ffff00ff - 1 - DQ47_29_125_00 - 125 47.4833333333333 8000 0 0 - - ffff00ff - 1 - DQ47_37_125_00 - 125 47.6166666666667 8000 0 0 - - ffff00ff - 1 - DQ47_45_125_00 - 125 47.75 8000 0 0 - - ffff00ff - 1 附件2 写入KML数据文件的程序体FName:=DirectPath+MyPlaces.kml;CreateTFile(FName,F);XMLDoc_WriteBegin(F);XMLDoc_WriteMainFolderBegin(F);LoadImageSec(DQ800CurrentSec,Latst,LonSt,LatEn,LonEn,DLat,DLon);XMLDoc_WriteSubFolderBegin(F,DQ800CurrentSec.SecDir);With DQ800CurrentSec doFor j:=0 to ACol -1 dobegin Lon:=LonSt+j*DLon; For i:=0 to ARow-1 do begin Lat:=LatSt-i*DLat; XMLDoc_WritePlaceMark(F,Prefix+FormatDegSecRound(Lat)+_+ FormatDegSecRound(Lon), Lon,Lat,DQ800CurrentSec.Scale,False); end;end;XMLDoc_WriteFolderEnd(f);XMLDoc_WriteFolderEnd(f);XMLDoc_WriteEnd(f);CloseFile(F);WithDQ800idobeginFieldByName(LatSt).asFloat:=LatSt;Deg2DMS(LatSt,DD,MM,SS);FieldByName(LatStDD).asinteger:=DD;FieldByName(LatStMM).asinteger:=MM;FieldByName(LatStSS).asinteger:=SS;FieldByName(LonSt).asFloat:=LonSt;Deg2DMS(LonSt,DD,MM,SS);FieldByName(LonStDD).asinteger:=DD;FieldByName(LonStMM).asinteger:=MM;FieldByName(LonStSS).asinteger:=SS;FieldByName(LatEn).asFloat:=LatEn;Deg2DMS(LatEn,DD,MM,SS);FieldByName(LatEnDD).asinteger:=DD;FieldByName(LatEnMM).asinteger:=MM;FieldByName(LatEnSS).asinteger:=SS;FieldByName(LonEn).asFloat:=LonEn;Deg2DMS(LonEn,DD,MM,SS);FieldByName(LonEnDD).asinteger:=DD;FieldByName(LonEnMM).asinteger:=MM;FieldByName(LonEnSS).asinteger:=SS;FieldByName(DLat).asFloat:=DLat;FieldByName(DLon).asFloat:=DLon;FieldByName(Rows).asInteger:=Rows;FieldByName(Cols).asInteger:=Cols;FieldByName(Scale).asFloat:=Scale;FieldByName(NameLen).asInteger:=NameLen;FieldByName(SectName).asString:=SecName;FieldByName(SectDir).asString:=SecDir;FieldByName(MainPath).asString:=Path;FieldByName(Prefix).asString:=Prefix;FieldByName(SizeX).asInteger:=SizeX;FieldByName(SizeY).asInteger:=SizeY;FieldByName(Width).asInteger:=Width;FieldByName(Height).asInteger:=Height;FieldByName(PixelToX).asFloat:=PixelToX;FieldByName(PixelToY).asFloat:=PixelToY;FieldByName(WidToHei).asFloat:=WidToHei;end;WithDQ800idoBeginLatSt:=FieldByName(LatSt).asFloat;LonSt:=FieldByName(LonSt).asFloat;LatEn:=FieldByName(LatEn).asFloat;LonEn:=FieldByName(LonEn).asF

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论