GIS软件开发技术_第1页
GIS软件开发技术_第2页
GIS软件开发技术_第3页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

1、.第一章MapObjects基础l Gis常用开发平台l MapObjects简介Ø MapObjects功能Ø MapObjects优点Ø MapObjects基础l 编程规范01、Gis软件开发常用开发平台常用开发平台的比较:VB:较易入门VBA:对于扩充原有功能较好。如AutoCAD、ArcMap中的VBA。开发效率最高的一种开发方式(常常是一个语名即可实现其它开发工具要几十甚至上百行的代码才能实现的功能)。缺点是所开发出的应用程序不能脱离相应的运行环境。(如在ArcMap中开发的应用程序,必须先要安装ArcMap)VC+:较为灵活,开发资料众多。可实现对系

2、统的全面操作。缺点是学习起来较难,所开发出的应用程序常常会产生难以预计的错误。(如内存泄露等)Delphi:可扩充性最好,现已有上万个带源码的控件可供使用,几乎涉及到各各方面。如数据库控件InfoPower3000、OpenGL控件GLScene,工业控制控件等。GIS组件简介:MapObjects:ESRI1、 可实现功能:2、 可使用的数据ArcView Gis Shapefiles:创建新层、读写数据,添加删除记录与几何要素ArcSDE:不能创建新层Arcinfo Coverages:只读CAD格式及VPF数据库:只读(Vector Product Format是一种标准的基于空间关系数

3、据模型的大型空间数据库的格式、结构与组织。是美国国防部的标准)外部数据库:只读ArcObjects:ESRIMapX:MapinfoSupermap:中科院地理所一般用户(大多数用户)关心的问题:应用程序的运行速度与稳定性。不关心所采用的开发工具及内部实现方式。只有特殊用户(少量用户)考虑与原有系统的兼容性才关心开发平台。软件开发中应注意的问题:代码的规范性:1、命名约定 2、代码缩进 3、逻辑关系的排列次序对于较为普通的问题尽量使用较常见的解决方式。尽量不使用较为古怪的技巧(如:两数的交换),这样会降低代码的可读性。Delphi开发环境简介:1、数据库应用 2、OpenGL应用 3、报表制作

4、 02、通用GIS功能的界面框架设计1、 菜单的设计2、 工具条的设计3、 状态栏提示信息的显示(标准控件及1stClass控件的使用)4、 fcLookoutBar控件的使用5、 TActionList控件的使用6、 图标及标题的设置03、MapObjects的模块间关系简介属性、事件、方法:属性:对象的性质,方法:对象的动作,事件:对象的响应。(只有Map Control有事件)可创建对象与不可创建对象为有效地使用MapObjects中的OLE Automation对象,必须注意一些对象可以创建,一些对象不可创建。如果某个对象可以创建,在对象图中对象名称下有一个Creatable标注。如一

5、个对象可以创建可用如下代码创建:(假设创建点对象). v.Dim NewObject as New MapObjects2.Point或Dim NewObject as MapObjects2.PointSet NewObject = New MapObjects2.Point在将对象的引用赋给变量、数据类型的元素或可写对象的属性时,须使用关键字Set;在创建对象的实例时,须使用关键字NewVar NewObject: ImoPoint;Begin NewObject := coPoint.Create;End;在Delphi中如一个对象可创建,可用coXXX.Create方法进行创建。XXX

6、为可创建对象名. v.值传递与引用传递:值传递:新的变量得到原始数据或对象的一个拷贝,其值的改变不影响原值。Name属性;引用传递:新的变量得到原始数据或对象的内存地址,其值的改变影响原值。Symbol属性. v.值传递. v.Dim LayerName As StringLayerName= Map1.Layers.Item(0).NameLayerName = "MyLayerName"MsgBox LayerNameMsgBox Map1.Layers.Item(0).Namevar LayerName: string;begin LayerName := ImoMa

7、pLayer(Map1.layers.Item(0).Name; LayerName := 'MyLayerName' ShowMessage(LayerName); ShowMessage(ImoMapLayer(Map1.layers.Item(0).Name);End;. v.引用传递. v.Dim MySymbol As New MapObjects2.SymbolSet MySymbol = Map1.Layers.Item(0).SymbolMySymbol.Color = moRedMap1.Refreshvar MySymbol: imoSymbol;begin

8、 MySymbol := coSymbol.Create ; MySymbol := ImoMapLayer(Map1.Layers.Item(0).Symbol; MySymbol.Color := moRed; Map1.Refresh ;end;. v.MapObjects中的常量:常量均以mo开头。在编写代码时,可使用常量名也可使用常量左边的整数。但最好使用常量名称以增强代码的可读性。MainMap.MousePointer = moArrow;或MainMap.MousePointer = 1;第二章 地图与图层l Map Controll Layers Collection

9、6; MapLayersØ ImageLayersl Rectangle、pointl DataConnectionl GeoDatasets Collectionl GeoDatasetl TrackingLayer查看地图 地图的放大、缩小、平移等操作交互式方法:Pan、 TrackRegtangle、 TrackPolygon、 TrackCircle。当使用上述方法时,运行时线程将暂停,等待用户使用鼠标与Map控件交互。实现对地图的基本操作。(地图的放大、缩小、平移). v.Private Sub MainMap_MouseDown(Button As Integer, Sh

10、ift As Integer, x As Single, y As Single) Dim r As new MapObjects2.Rectangle If barDisplay.Buttons("Zoom in").Value = 1 Then MainMap.Extent = MainMap.TrackRectangle ElseIf barDisplay.Buttons("Zoom out").Value = 1 Thenr = MainMap.Extentr.ScaleRectangle(1.25)MainMap.Extent = r Else

11、If barDisplay.Buttons("Pan").Value = 1 Then MainMap.Pan ElseIf barDisplay.Buttons("Identify").Value = 1 Then Call frmIdentify.Identify(x, y)Endif MainMap.RefreshEnd sub procedure TMainFRM.MainMapMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);v

12、ar r: imoRectangle;begin if tbZoomIn.Down then MainMap.Extent := MainMap.TrackRectangle else if tbZoomOut.Down then begin r := coRectangle.Create; r := MainMap.Extent; /(Extent:为地图的空间区域可理解为当前的显示范围) r.ScaleRectangle(1.25); / MainMap.Extent := r; end else if tbPan.Down then MainMap.Pan else if (tbIden

13、tify.Down) and (Button = mbLeft) then/ GetIdentify(X, Y) ;MainMap.Refresh;End;. v.获取鼠标坐标在创建面向图形的应用程序时,必须解决两种坐标系统的转换问题:定义窗体中控件的尺寸与位置的控制坐标,以及定义在打印机或显示器上图形的大小与位置的设备坐标。MapObjects开发人员还须使用第三种坐标系统:地图坐标系统。此坐标定义了地图上几何要素或影像的笛卡尔位置。为保证有效,此坐标系统必须与某种投影或非投影坐标相匹配,以定义物体在地表的位置。在MapObjects中,ToMapPoint方法以参数形式接收MouseDow

14、n、MouseUp、MouseMove事件传递的鼠标位置的x,y参数。这些x,y值是以控制坐标来表达的。ToMapPoint方法将窗体上点的位置转换成相应的地图上的点位置。FromMapPoint方法实现相反的转换。类式的方法有:ToMapDistance与FromMapDistance. v.Private Sub Map1_MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single) Dim MyPoint As New PointSet MyPoint = Map1.ToMapPoint(X, Y) Te

15、xt1.Text = Str(MyPoint.X) + " " + Str(MyPoint.Y)End Subprocedure TForm1.Map1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);var MyPoint: ImoPoint;begin MyPoint := coPoint.Create ; MyPoint := Map1.ToMapPoint(x,y); Edit1.Text := FloatToStr(MyPoint.X) + ' + FloatToStr(MyPoin

16、t.Y );end;. v.图层集合(Layers)Ø 每个地图控件有且只有一个Layers集合Ø Layers集合可包含MapLayer与ImageLayer两类地图文件Ø 每个图层可有自已的显示方式. v.Dim i As Integer For i = 0 To Map1.Layers.Count - 1 MsgBox Map1.Layers.Item(i).Name Next ivar i: integer; MyLayers: imoLayers;begin MyLayers := Map1.Layers ; for i := 0 to MyLayers

17、.Count - 1 do ShowMessage(ImoMapLayer(MyLayers.Item(i).Name);end;或:var i: integer;begin for i := 0 to Map1.Layers.Count - 1 do ShowMessage(ImoMapLayer(Map1.Layers.Item(i).Name);end;. v.04、MapObjects图层操作1、 ArcView格式地图2、 AutoCAD图形3、 位图注意观察如下图形中的红线部份:加入ArcView格式地图步骤:1、生成数据连接对象(ImoDataConnection)2、设定数据连

18、接对象的DataBase属性4、 取得空间数据集5、 生成新的图层6、 将新生成的图层加入地图控件. v.Private Sub Command1_Click()Dim dc As New MapObjects2.DataConnectionDim lyr As New MapObjects2.MapLayerdc.Database = "C:USA"If dc.Connect Then Set lyr.GeoDataset = dc.FindGeoDataset("Counties")If lyr.Valid Then Map1.Layers.Add

19、lyrElse MsgBox "无法加入图层"End IfElse MsgBox "出错,请确定数据是否存在. "End IfEnd Subvar dc: imoDataConnection; lyr: imoMapLayer;begin dc := coDataConnection.Create; lyr := coMapLayer.Create; dc.Database := 'C:USA' if dc.Connect then begin lyr.GeoDataset := dc.FindGeoDataset('Counti

20、es'); if lyr.Valid then Map1.Layers.Add(lyr) else ShowMessage('无法加入图层') end else ShowMessage('出错,请确定数据是否存在.');end;. v.注意要点:DataBase:对于shapefile,数据库属性仅为一包含有shapefile的文件夹或目录字符串。FindGeoDataset:对于shapefile,参数字符串只须设为没有扩展名的ShapeFile文件名。较为完整的加入ShapeFile的Delphi代码:function TMapManage.AddS

21、hapeFile(sFileName: string; LayerColor: integer = 16711680): string;var gs: IMoGeoDataset; dc: IMoDataConnection; name, fname: string; Newlayer: IMoMapLayer;begin dc := IMoDataConnection(CreateOleObject('MapObjects2.DataConnection');/ 或dc := coDataConnection.Create ; name := SFileName; fname

22、 := ExtractFileDir(name); /获取某一文件所在的路径 dc.database := fname; /DataBase属性:指明所采用的数据,如为SDE则为数据库名,如为Shp文件则为Shp文件所在的目录 if not dc.connect then exit; Name := GetFileName(Name); if not LayerExist(Name) then begin gs := dc.FindGeoDataset(name); gs.AllowSharing := true; if VarIsEmpty(gs) then exit; /判断对象是否为空,

23、(在Delphi6中此函数存在错误) NewLayer := IMoMapLayer(CreateOleObject('MapObjects2.MapLayer'); NewLayer.GeoDataset := gs; NewLayer.Symbol.Color := LayerColor;MainMap.Layers.Add(NewLayer); end else begin MessageBox(Handle, '已存在图层', '图层管理', MB_OK + MB_ICONINFORMATION); Result := ''

24、; Exit; end; Result := Name;end;/假设sFileNmae 为C:ProjectsLean.shp函数返回值为Leanfunction GetFileName(sFileName: string): string;begin while pos('', sFileName) > 0 do begin delete(sFileName, 1, 1); end; while pos('.', sFileName) > 0 do delete(sFileName, Pos('.', sFileName), 4)

25、; Result := sFileName;end;更正Delphi6中的VarIsEmpty函数:将: Result := FindVarData(V).VType = varEmpty;改为: with TVarData(V) do Result := (VType = varEmpty) or (VType = varDispatch) or (VType = varUnknown) and (VDispatch = nil);/判断指定的图层是否存在function LayerExist(sLayerName: string): boolean;var i: integer; Curr

26、entMap: ImoMapLayer;begin CurrentMap := CoMapLayer.Create; for i := 0 to Map.Layers.Count - 1 do begin CurrentMap := ImoMapLayer(Map.Layers.Item(i); if CurrentMap.Name = sLayerName then begin Result := true; exit; end; end; Result := false;end;加入Coverage图层:加入SDE图层加入Image图层:. v.Private Sub Command1_C

27、lick() Dim lyr As New MapObjects2.ImageLayer lyr.File = "D: WashingtonWash.bmp" Map1.Layers.Add lyrEnd Subprocedure TForm1.Button1Click(Sender: TObject);var Lyr: imoImageLayer;begin lyr := coImageLayer.Create ; Lyr.File_ := 'D:WashingtonWash.bmp' Map1.Layers.Add(Lyr);end;. v.注意要点:与

28、失量数据不同,在创建ImageLayer时不需要创建DataConnection和GeoDataset对象,中需设置ImageLayer对象实例的File属性,再将ImageLayer加入Map控件即可。加入CAD文件:. v.Private Sub Command2_Click() Dim dc As New MapObjects2.DataConnection Dim lyr As New MapObjects2.MapLayer dc.Database = "CADPointD:ARCVIEWCAD" Set lyr.GeoDataset = dc.FindGeoDa

29、taset("Parcels.dwg") Map1.Layers.Add lyrEnd Subprocedure TForm1.Button3Click(Sender: TObject);var dc: imoDataConnection; Lyr: imoMapLayer;begin dc := coDataConnection.Create ; Lyr := coMapLayer.Create ; dc.Database := 'CADPointD:ARCVIEWCAD' lyr.GeoDataset := dc.FindGeoDataset('

30、Parcels.dwg'); Map1.Layers.Add(Lyr);end;. v.注意要点:DataConnection的Database属性字符串不仅要提供文件所在的路径,而且要包括实体类型的前缀。如CADPoint、CADArea及CADText等,前缀CAD默认为线实体。在使用FindGeoDataset方法时,其参数必须包括扩展名在内的完整文件名。小结:测试数据库联接:Connect与DisConnect:Connect与DisConnect是作用在DataConnection对象上的方法。Connected与ConnectErr是DataConnection对象的属性,

31、可以在任何时间读取检验连接状态。Connect首先读取数据库属性,确定数据的存储位置;读取存储的文件并创建数据的GeoDataset集合;Connect返回一布尔值,并在Connected属性中写入这一布尔值;若Connect返回的布尔值为False,它将设置ConnectError的值。DisConnect方法释放DataConnection对象和数据存储位置间的连接,清空GeoDataSets集合,并重新设置Connected值为False。加入图层时应注意到不同类型的数据其DataConnection的DataBase属性字符串的值格式不同。文件类型DataConnection的Data

32、base属性DataConnection的FindGetDataset方法ShapeFile:Shp文件所在的路径不带扩展名的Shp文件名AutoCAD:类型+CAD文件所在的路径包括扩展名在内的完整文件名Image:不需要设置不需要设置Coverage:05、图层的显示次序图层在地图控件的次序决定或影响整个地图的显示效果,点状信息或线状信息常常会被面状信息所掩盖。可通过Layers集合中的MoveTo、MovtToBottom、MoveToTop方法控制图层的次序。及MapLayer对象中的Visible属性控制某个图层显示与否。/获取当前所打开的所有图层名及状态procedure TLay

33、erManagerFRM.FormActivate(Sender: TObject);var i: Integer;CurrentLayer: ImoMapLayer;begin CheckListBoxLayers.Clear; for i := 0 to MainFRM.MainMap.Layers.Count - 1 do beginCurrentLayer := ImoMapLayer(CurrentMap.Layers.Item(i); if CurrentLayer.LayerType = moMapLayer then checkListBoxLayers.Items.Add(C

34、urrentLayer.Name); CheckListBoxLayers.Checkedi := CurrentLayer.Visible; end;end;/确定各个按钮的状态procedure TLayerManagerFRM.CheckListBoxLayersClick(Sender: TObject);var CurrentLayer: Integer; LayerCount: Integer; Layer: ImoMapLayer;begin CurrentLayer := CheckListBoxLayers.ItemIndex; Layer := ImoMapLayer(Cu

35、rrentMap.Layers.Item(CurrentLayer); LayerCount := CurrentMap.Layers.Count; if (LayerCount = 1) or (LayerCount = 0) then else begin sbTop.Enabled := CurrentLayer <> 0; sbButtom.Enabled := CurrentLayer < LayerCount - 1; sbUp.Enabled := CurrentLayer <> 0; sbDown.Enabled := CurrentLayer &

36、lt; LayerCount - 1; end; CmbRemove.Enabled := CheckListboxLayers.Items.Count > 0; bbtnAttribute.Enabled := CmbRemove.Enabled;end;/移动图层procedure TLayerManagerFRM.MoveLayer(Sender: TObject);var CurrentLayerIndex: Integer;begin CurrentLayerIndex := CheckListBoxLayers.ItemIndex; if CurrentLayerIndex

37、< 0 then ShowMessage('请选择所要移动的图层。') else begin with CurrentMap.Layers do begin case (Sender as TSpeedButton).tag of 1: MoveToTop(CurrentLayerIndex); 2: MoveTo(CurrentLayerIndex, CurrentLayerIndex - 1); 3: MoveTo(CurrentLayerIndex, CurrentLayerIndex + 1); 4: MoveToBottom(CurrentLayerIndex)

38、; end; end; end; LayerManagerFRM.FormActivate(Sender); CurrentMap.Refresh;end;Map控件1) BeforeLayerDraw (index as Integer, hDC as stdole.OLEHandle)绘制图层2) AfterLayerDraw (index as Integer, canceled as Boolean, hDC as stdole.OLEHandle)3) BeforeTrackingLayerDraw (hDC as stdole.OLEHandle)绘制Tracking图层4) Af

39、terTrackingLayerDraw (hDC as stdole.OLEHandle)BeforeLayerDraw事件:在绘制图层前执行,主要用于检查当前图层的显示比例,决定在当前显示比例下是否显示此图层。这样可使地图更具有地图学意义,同时提高显示速度。第三章数据集/提取某一图层中的每一条记录,填充Memoprocedure TForm1.Button1Click(Sender: TObject);var MyRecord: imoRecordSet; CurrentLayer: imoMapLayer; i: integer; MyTableDesc: imoTableDesc;be

40、gin CurrentLayer := coMapLayer.Create; myTableDesc := coTableDesc.Create ; CurrentLayer := ImoMapLayer(Map1.Layers.Item(0); MyRecord := CurrentLayer.Records; myTableDesc := MyRecord.TableDesc ; for i := 0 to MyTableDesc.FieldCount - 1 do begin Memo1.Lines.Add(MyTableDesc.FieldNamei); Memo1.Lines.Add

41、(myRecord.Fields.Item(MyTableDesc.FieldNamei).ValueAsString) ; end;end;/较为完整的Identify代码:procedure TMainFRM.GetIdentify(x, y: integer);var CurrentPoint: imoPoint; i: integer; MyTableDesc: imoTableDesc; MyRecordSet: imoRecordSet; CurrentLayer: imoMapLayer;begin CurrentPoint := coPoint.Create; CurrentL

42、ayer := coMapLayer.Create; MyTableDesc := coTableDesc.Create; CurrentPoint := MainMap.ToMapPoint(x, y); IdentifyFRM.plCurrentCoordinate.Caption := '拾取点坐标:' + FloatToStr(CurrentPoint.X) + ' ; ' + FloatToStr(CurrentPoint.Y); myRecordSet := ImoMapLayer(MainMap.Layers.Item(0).SearchShape

43、(CurrentPoint, 12, ''); MyTableDesc := myRecordSet.TableDesc; IdentifyFRM.sgValues.Cells0, 0 := '字段' IdentifyFRM.sgValues.Cells1, 0 := '值' IdentifyFRM.sgValues.RowCount := myTableDesc.FieldCount + 1;myRecordSet.MoveFirst; while not MyRecordSet.EOF do begin for i := 0 to MyTab

44、leDesc.FieldCount - 1 do begin IdentifyFRM.sgValues.Cells0, i + 1 := MyTAbleDesc.FieldNamei; IdentifyFRM.sgValues.Cells1, i + 1 := myRecordset.Fields.Item(MyTableDesc.FieldNamei).ValueAsString;end; MainMap.FlashShape(myRecordset.Fields.Item('Shape').Value, 2); MyRecordSet.MoveNext; end; Iden

45、tifyFRM.Show;end;注:本模块需完善:在同一图层中查找到多个对象的情况在单击处存在多个图层的情况/编辑记录创建新图层:第四章地图要素的查询与选择l SearchExpressionl SearchByDistancel SearchShape使用MapLayer的SearchExpression方法可实现根据属性值查询属性所对应的地图要素的功能。SearchExpression:其实质是构建Select语句中的Where子句的内容。procedure TForm1.Button1Click(Sender: TObject);var CurrentLayer: imoMapLaye

46、r;begin CurrentLayer := coMapLayer.Create; CurrentLayer := ImoMapLayer(Map1.Layers.Item(0); myRecordSet := CurrentLayer.SearchExpression(Edit1.Text); Map1.Refresh;end;/将查询结果以另外一种Color 显示procedure TForm1.Map1AfterLayerDraw(Sender: TObject; index: Smallint; canceled: WordBool; hDC: Cardinal);var

47、MySymbol: imoSymbol;begin mysymbol := coSymbol.Create; mySymbol.Color := moYellow; if not VarIsEmpty(myRecordSet) then Map1.DrawShape(myRecordSet, mySymbol);end;注:在本例中SearchExpression为一固定值,在实际应用中应根据用户的选择自动组合。编程实现大体步骤:Ø 在窗口的FormActivate事件中提取当前地图中所有的图层名Ø 当用户选取某一图层时提取此图层所包含的字段Ø 根据用户对不同字段

48、的类型选择组合查询条件,如字符型字段需加另外一种方法是用户只需输入所要查询的内容,系统实现对所有图层,所有字段的查询,此方法编程较为复杂。 采用SearchByDistance方法可实现使用距离选择要素SearchByDistance (shape as Object, distance as Double,expression as String) as RecordSetSearchByDistance方法的第一个参数可以是一个shape或者为包含具有0或多个shape的Recordset对象。第二个参数使用一个距离容限值,第三个参数为可选的SQL Where 从句与前面的条件为AND关系

49、。SearchByDistance方法作用于MapLayer对象。对于图层中的每一个要素,根据其与方法中shape参数的距离,被选择或不被选择。如果要素的任何部分落在由shape及距离参数创建的虚拟缓冲区范围内,那么该对象及其所有属性值将被选中,并输入到结果Recordset中。procedure TForm1.MainMapMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);var mySymbol: imoSymbol;begin mySymbol := cosymbol.C

50、reate; myPoint := coPoint.Create; MySymbol.Color := moYellow; MyPoint := MainMap.ToMapPoint(x, y); MyRecordSet := ImoMapLayer(MainMap.Layers.Item(0).SearchByDistance(myPoint, udDistance.Position, ''); MainMap.Refresh;end;procedure TForm1.MainMapAfterLayerDraw(Sender: TObject; index: Smallint; canceled: WordBool; hDC: Cardinal);var m

温馨提示

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

评论

0/150

提交评论