GIS软件开发技术.docx
《GIS软件开发技术.docx》由会员分享,可在线阅读,更多相关《GIS软件开发技术.docx(52页珍藏版)》请在冰豆网上搜索。
GIS软件开发技术
第一章MapObjects根底
Gis常用开发平台
MapObjects简介
ØMapObjects功能
ØMapObjects优点
ØMapObjects根底
编程规X
01、Gis软件开发常用开发平台
常用开发平台的比较:
VB:
较易入门
VBA:
对于扩大原有功能较好。
如AutoCAD、ArcMap中的VBA。
开发效率最高的一种开发方式〔常常是一个语名即可实现其它开发工具要几十甚至上百行的代码才能实现的功能〕。
缺点是所开发出的应用程序不能脱离相应的运行环境。
〔如在ArcMap中开发的应用程序,必须先要安装ArcMap〕
VC++:
较为灵活,开发资料众多。
可实现对系统的全面操作。
缺点是学习起来较难,所开发出的应用程序常常会产生难以预计的错误。
〔如内存泄露等〕
Delphi:
可扩大性最好,现已有上万个带源码的控件可供使用,几乎涉及到各各方面。
如数据库控件InfoPower3000、OpenGL控件GLScene,工业控制控件等。
GIS组件简介:
MapObjects:
ESRI
1、可实现功能:
2、可使用的数据
ArcViewGisShapefiles:
创立新层、读写数据,添加删除记录与几何要素
ArcSDE:
不能创立新层
ArcinfoCoverages:
只读
CAD格式及VPF数据库:
只读〔VectorProductFormat是一种标准的基于空间关系数据模型的大型空间数据库的格式、构造与组织。
是美国国防部的标准〕
外部数据库:
只读
ArcObjects:
ESRI
MapX:
Mapinfo
Supermap:
中科院地理所
一般用户〔大多数用户〕关心的问题:
应用程序的运行速度与稳定性。
不关心所采用的开发工具及内部实现方式。
只有特殊用户〔少量用户〕考虑与原有系统的兼容性才关心开发平台。
软件开发中应注意的问题:
代码的规X性:
1、命名约定2、代码缩进3、逻辑关系的排列次序
对于较为普通的问题尽量使用较常见的解决方式。
尽量不使用较为古怪的技巧〔如:
两数的交换〕,这样会降低代码的可读性。
Delphi开发环境简介:
1、数据库应用2、OpenGL应用3、报表制作
02、通用GIS功能的界面框架设计
1、菜单的设计
2、工具条的设计
3、状态栏提示信息的显示〔标准控件及1stClass控件的使用〕
4、fcLookoutBar控件的使用
5、TActionList控件的使用
6、图标及标题的设置
03、MapObjects的模块间关系简介
属性、事件、方法:
属性:
对象的性质,方法:
对象的动作,事件:
对象的响应。
〔只有MapControl有事件〕
可创立对象与不可创立对象
为有效地使用MapObjects中的OLEAutomation对象,必须注意一些对象可以创立,一些对象不可创立。
如果某个对象可以创立,在对象图中对象名称下有一个Creatable标注。
如一个对象可以创立可用如下代码创立:
〔假设创立点对象〕
DimNewObjectasNewMapObjects2.Point
或
DimNewObjectasMapObjects2.Point
SetNewObject=NewMapObjects2.Point
在将对象的引用赋给变量、数据类型的元素或可写对象的属性时,须使用关键字Set;在创立对象的实例时,须使用关键字New
Var
NewObject:
ImoPoint;
Begin
NewObject:
=coPoint.Create;
End;
在Delphi中如一个对象可创立,可用coXXX.Create方法进展创立。
XXX为可创立对象名
值传递与引用传递:
值传递:
新的变量得到原始数据或对象的一个拷贝,其值的改变不影响原值。
Name属性;
引用传递:
新的变量得到原始数据或对象的内存地址,其值的改变影响原值。
Symbol属性
值传递
DimLayerNameAsString
LayerName="MyLayerName"
MsgBoxLayerName
var
LayerName:
string;
begin
LayerName:
='MyLayerName';
ShowMessage(LayerName);
End;
引用传递
DimMySymbolAsNewMapObjects2.Symbol
MySymbol.Color=moRed
Map1.Refresh
var
MySymbol:
imoSymbol;
begin
MySymbol:
=coSymbol.Create;
MySymbol.Color:
=moRed;
Map1.Refresh;
end;
MapObjects中的常量:
常量均以mo开头。
在编写代码时,可使用常量名也可使用常量左边的整数。
但最好使用常量名称以增强代码的可读性。
MainMap.MousePointer=moArrow;或MainMap.MousePointer=1;
第二章地图与图层
MapControl
LayersCollection
ØMapLayers
ØImageLayers
Rectangle、point
DataConnection
GeoDatasetsCollection
GeoDataset
TrackingLayer
查看地图
地图的放大、缩小、平移等操作
交互式方法:
Pan、TrackRegtangle、TrackPolygon、TrackCircle。
当使用上述方法时,运行时线程将暂停,等待用户使用鼠标与Map控件交互。
实现对地图的根本操作。
〔地图的放大、缩小、平移〕
PrivateSubMainMap_MouseDown(ButtonAsInteger,ShiftAsInteger,xAsSingle,yAsSingle)
DimrAsnewMapObjects2.Rectangle
IfbarDisplay.Buttons("Zoomin").Value=1Then
MainMap.Extent=MainMap.TrackRectangle
ElseIfbarDisplay.Buttons("Zoomout").Value=1Then
r=MainMap.Extent
r.ScaleRectangle(1.25)
MainMap.Extent=r
ElseIfbarDisplay.Buttons("Pan").Value=1Then
MainMap.Pan
ElseIfbarDisplay.Buttons("Identify").Value=1Then
CallfrmIdentify.Identify(x,y)
Endif
MainMap.Refresh
Endsub
procedureTMainFRM.MainMapMouseDown(Sender:
TObject;Button:
TMouseButton;Shift:
TShiftState;X,Y:
Integer);
var
r:
imoRectangle;
begin
iftbZoomIn.Downthen
MainMap.Extent:
=MainMap.TrackRectangle
else
iftbZoomOut.Downthen
begin
r:
=coRectangle.Create;
r:
=MainMap.Extent;//〔Extent:
为地图的空间区域可理解为当前的显示X围〕
r.ScaleRectangle(1.25);//
MainMap.Extent:
=r;
end
else
iftbPan.Downthen
MainMap.Pan
else
if(tbIdentify.Down)and(Button=mbLeft)then
//GetIdentify(X,Y);
MainMap.Refresh;
End;
获取鼠标坐标
在创立面向图形的应用程序时,必须解决两种坐标系统的转换问题:
定义窗体中控件的尺寸与位置的控制坐标,以及定义在打印机或显示器上图形的大小与位置的设备坐标。
MapObjects开发人员还须使用第三种坐标系统:
地图坐标系统。
此坐标定义了地图上几何要素或影像的笛卡尔位置。
为保证有效,此坐标系统必须与某种投影或非投影坐标相匹配,以定义物体在地表的位置。
在MapObjects中,ToMapPoint方法以参数形式接收MouseDown、MouseUp、MouseMove事件传递的鼠标位置的x,y参数。
这些x,y值是以控制坐标来表达的。
ToMapPoint方法将窗体上点的位置转换成相应的地图上的点位置。
FromMapPoint方法实现相反的转换。
类式的方法有:
ToMapDistance与FromMapDistance
PrivateSubMap1_MouseMove(ButtonAsInteger,ShiftAsInteger,XAsSingle,YAsSingle)
DimMyPointAsNewPoint
SetMyPoint=Map1.ToMapPoint(X,Y)
Text1.Text=Str(MyPoint.X)+""+Str(MyPoint.Y)
EndSub
procedureTForm1.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(MyPoint.Y);
end;
图层集合(Layers)
Ø每个地图控件有且只有一个Layers集合
ØLayers集合可包含MapLayer与ImageLayer两类地图文件
Ø每个图层可有自已的显示方式
DimiAsInteger
Nexti
var
i:
integer;
MyLayers:
imoLayers;
begin
MyLayers:
=Map1.Layers;
fori:
=0toMyLayers.Count-1do
ShowMessage(ImoMapLayer(MyLayers.Item(i)).Name);
end;
或:
var
i:
integer;
begin
end;
04、MapObjects图层操作
1、ArcView格式地图
2、AutoCAD图形
3、位图
注意观察如以下图形中的红线部份:
参加ArcView格式地图
步骤:
1、生成数据连接对象〔ImoDataConnection〕
2、设定数据连接对象的DataBase属性
4、取得空间数据集
5、生成新的图层
6、将新生成的图层参加地图控件
PrivateSubCommand1_Click()
DimdcAsNewMapObjects2.DataConnection
DimlyrAsNewMapObjects2.MapLayer
dc.Database="C:
\USA"
Ifdc.ConnectThen
Setlyr.GeoDataset=dc.FindGeoDataset("Counties")
Iflyr.ValidThen
Else
MsgBox"无法参加图层"
EndIf
Else
MsgBox"出错,请确定数据是否存在?
"
EndIf
EndSub
var
dc:
imoDataConnection;
lyr:
imoMapLayer;
begin
dc:
=coDataConnection.Create;
lyr:
=coMapLayer.Create;
dc.Database:
='C:
\USA';
ifdc.Connectthen
begin
lyr.GeoDataset:
=dc.FindGeoDataset('Counties');
iflyr.Validthen
else
ShowMessage('无法参加图层')
endelse
ShowMessage('出错,请确定数据是否存在?
');
end;
注意要点:
DataBase:
对于shapefile,数据库属性仅为一包含有shapefile的文件夹或目录字符串。
FindGeoDataset:
对于shapefile,参数字符串只须设为没有扩展名的ShapeFile文件名。
较为完整的参加ShapeFile的Delphi代码:
functionTMapManage.AddShapeFile(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:
=ExtractFileDir(name);//获取某一文件所在的路径
dc.database:
=fname;//DataBase属性:
指明所采用的数据,如为SDE那么为数据库名,如为Shp文件那么为Shp文件所在的目录
ifnotdc.connectthenexit;
Name:
=GetFileName(Name);
ifnotLayerExist(Name)then
begin
gs:
=dc.FindGeoDataset(name);
gs.AllowSharing:
=true;
ifVarIsEmpty(gs)thenexit;//判断对象是否为空,〔在Delphi6中此函数存在错误〕
NewLayer:
=IMoMapLayer(CreateOleObject('MapObjects2.MapLayer'));
NewLayer.GeoDataset:
=gs;
Main
end
elsebegin
MessageBox(Handle,'已存在图层','图层管理',MB_OK+MB_ICONINFORMATION);
Result:
='';
Exit;
end;
Result:
=Name;
end;
//假设sFileNmae为C:
\Projects\Lean.shp函数返回值为Lean
functionGetFileName(sFileName:
string):
string;
begin
whilepos('\',sFileName)>0do
begin
delete(sFileName,1,1);
end;
whilepos('.',sFileName)>0do
delete(sFileName,Pos('.',sFileName),4);
Result:
=sFileName;
end;
更正Delphi6中的VarIsEmpty函数:
将:
Result:
=FindVarData(V)^.VType=varEmpty;
改为:
withTVarData(V)do
Result:
=(VType=varEmpty)or((VType=varDispatch)or
(VType=varUnknown))and(VDispatch=nil);
//判断指定的图层是否存在
functionLayerExist(sLayerName:
string):
boolean;
var
i:
integer;
CurrentMap:
ImoMapLayer;
begin
CurrentMap:
=CoMapLayer.Create;
begin
ifCurrentMap.Name=sLayerNamethen
begin
Result:
=true;
exit;
end;
end;
Result:
=false;
end;
参加Coverage图层:
参加SDE图层
参加Image图层:
PrivateSubCommand1_Click()
DimlyrAsNewMapObjects2.ImageLayer
lyr.File="D:
\Washington\Wash.bmp"
EndSub
procedureTForm1.Button1Click(Sender:
TObject);
var
Lyr:
imoImageLayer;
begin
lyr:
=coImageLayer.Create;
Lyr.File_:
='D:
\Washington\Wash.bmp';
end;
注意要点:
与失量数据不同,在创立ImageLayer时不需要创立DataConnection和GeoDataset对象,中需设置ImageLayer对象实例的File属性,再将ImageLayer参加Map控件即可。
参加CAD文件:
PrivateSubCommand2_Click()
DimdcAsNewMapObjects2.DataConnection
DimlyrAsNewMapObjects2.MapLayer
dc.Database="[CADPoint]D:
\\ARCVIEW\CAD"
Setlyr.GeoDataset=dc.FindGeoDataset("Parcels.dwg")
EndSub
procedureTForm1.Button3Click(Sender:
TObject);
var
dc:
imoDataConnection;
Lyr:
imoMapLayer;
begin
dc:
=coDataConnection.Create;
Lyr:
=coMapLayer.Create;
dc.Database:
='[CADPoint]D:
\ARCVIEW\CAD';
lyr.GeoDataset:
=dc.FindGeoDataset('Parcels.dwg');
end;
注意要点:
DataConnection的Database属性字符串不仅要提供文件所在的路径,而且要包括实体类型的前缀。
如[CADPoint]、[CADArea]及[CADText]等,前缀[CAD]默认为线实体。
在使用FindGeoDataset方法时,其参数必须包括扩展名在内的完整文件名。
小结:
测试数据库联接:
Connect与DisConnect:
Connect与DisConnect是作用在DataConnection对象上的方法。
Connected与ConnectErr是DataConnection对象的属性,可以在任何时间读取检验连接状态。
Connect首先读取数据库属性,确定数据的存储位置;读取存储的文件并创立数据的GeoDataset集合;Connect返回一布尔值,并在Connected属性中写入这一布尔值;假设Connect返回的布尔值为False,它将设置ConnectError的值。
DisConnect方法释放DataConnection对象和数据存储位置间的连接,清空GeoDataSets集合,并重新设置Connected值为False。
参加图层时应注意到不同类型的数据其DataConnection的DataBase属性字符串的值格式不同。
文件类型
DataConnection的Database属性
DataConnection的FindGetDataset方法
ShapeFile:
Shp文件所在的路径
不带扩展名的Shp文件名
AutoCAD:
[类型]+CAD文件所在的路径
包括扩展名在内的完整文件名
Image:
不需要设置
不需要设置
Coverage:
05、图层的显示次序
图层在地图控件的次序决定或影响整个地图的显示效果,点状信息或线状信息常常会被面状信息所掩盖。
可通过Layers集合中的MoveTo、MovtToBottom、MoveToTop方法控制图层的次序。
及MapLayer对象中的Visible属性控制某个图层显示与否。
//获取当前所翻开的所有图层名及状态
procedureTLayerManagerFRM.FormActivate(Sender:
TObject);
var
i:
Integer;
CurrentLayer:
ImoMapLayer;
begin
CheckListBoxLayers.Clear;
fori:
=0toMainFRM.MainMap.Layers.Count-1do
begin
Current
ifCurrentLayer.LayerType=moMapLayerthen
CurrentLayer.Name);
CheckListBoxLayers.Checked[i]:
=CurrentLayer.Visible;
end;
end;
//确定各个按钮的状态
procedureTLayerManagerFRM.CheckListBoxLayersClick(Sender:
TObject);
var
CurrentLayer:
Integer;
LayerCount:
Integer;
Layer:
ImoMapLayer;
begin
CurrentLayer:
=CheckListBoxLayers.ItemIndex;
if(LayerCount=1)or(LayerCount=0)then
else
begin
sbTop.Enabl