阅读:24908回复:71
AE数据加载
<P align=center><B><FONT face="Times New Roman">AE</FONT></B><B>开发技术文档</B><B><br></B>
<P> <P><B><FONT face="Times New Roman">1、 </FONT></B><B>数据加载问题:</B><B> <P></B> <P> <P>任何系统都离不开数据的加载,下边就<FONT face="Times New Roman">AE</FONT>中几种常用的数据加载做一个列举。以便查阅:<br> <P> <P> <P><B><FONT face="Times New Roman">1</FONT></B><B>、加载个人数据库</B><B> <P></B> <P> <P>个人数据库是保存在<FONT face="Times New Roman">Access</FONT>中的数据库。其加载方式有两种:通过名字和通过属性加载(也许不只这两种,<FONT face="Times New Roman">AE</FONT>中实现同一功能可以有多种方式)。<br> <P> <P> <P><B><FONT face="Times New Roman">A</FONT></B><B>、通过设置属性加载个人数据库。</B><B> <P></B> <P> <P>首先通过<B>IPropertySet</B>接口定义要连接数据库的一些相关属性,在个人数据库中为数据库的路径,例如:<br> <P> <P> <P align=left><B>IPropertySet Propset = new PropertySetClass(); <br> <P></B> <P> <P align=left><B> Propset.SetProperty("DATABASE",@"D:\test\Ao\data\sh\MapData.mdb" );<br> <P></B> <P> <P align=left><B> </B>当定义完属性并设置属性后就可以进行打开数据库的操作了,在<FONT face="Times New Roman">ArcEngine</FONT>开发中存在<B>IWorkspaceFactory</B><B>、IFeatureWorkspace、IFeatureClass、IFeatureLayer</B>等几个常用的用于打开和操作数据空间地物的接口。<B>IWorkspaceFactory</B>是一个用于创建和打开工作空间的接口,它是一个抽象的接口,我们在具体应用时要用对应的工作空间实例化它,如下<FONT face="Times New Roman">:<br> <P></FONT> <P> <P align=left><B>IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass ();<br> <P></B> <P> <P align=left>如果我们打开的是<FONT face="Times New Roman">SDE</FONT>数据库就要用<B>SdeWorkspaceFactoryClass</B>实例化<B>Fact</B>。当我们完成了工作空间的实例化后就可以根据上边设置的属性打开对应的<FONT face="Times New Roman">Access</FONT>数据库了。打开方式如下:<br> <P> <P> <P align=left><FONT face="Times New Roman"> </FONT><B>IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace;<br> <P></B> <P> <P align=left>打开<FONT face="Times New Roman">Access</FONT>工作空间后接下来的事情是做什么了,很简单,找到对应的地物类,赋给相应的层,通过<FONT face="Times New Roman">MapControl</FONT>控件添加对应的层,然后刷新地图。以下为添加某一层的代码:<br> <P> <P> <P align=left><FONT face="Times New Roman"> </FONT><B>IFeatureClass Fcls = Workspace.OpenFeatureClass("District");<br> <P></B> <P> <P align=left><B> IFeatureLayer Fly = new FeatureLayerClass();<br> <P></B> <P> <P align=left><B> Fly.FeatureClass = Fcls;<br> <P></B> <P> <P align=left><B> MapCtr.Map.AddLayer (Fly); <br> <P></B> <P> <P><B>MapCtr.ActiveView.Refresh();</B><B> <P></B> <P> <P align=left>其中<B>District</B>为地物类的名字,<B>MapCtr</B>为<B>AE</B>中<FONT face="Times New Roman">MapControl</FONT>的对象。上边的通过属性设置加载数据空间的方式还可以用于<FONT face="Times New Roman">SDE</FONT>数据库,在<FONT face="Times New Roman">SDE</FONT>数据库加载时会介绍。<br> <P> <P> <P>以下为通过设置属性加载<FONT face="Times New Roman">Access</FONT>数据库的完整<FONT face="Times New Roman">C#</FONT>代码:<br> <P> <P> <P><FONT face="Times New Roman">public void AddAccessDBByPro()<br> <P></FONT> <P> <P><B>{<br> <P></B> <P> <P align=left><B>IPropertySet Propset = new PropertySetClass(); <br> <P></B> <P> <P align=left><B> Propset.SetProperty("DATABASE",@"D:\test\Ao\data\sh\MapData.mdb" );<br> <P></B> <P> <P align=left><B> <P></B> <P> <P align=left><B>IWorkspaceFactory Fact = new AccessWorkspaceFactoryClass ();<br> <P></B> <P> <P align=left><B> IFeatureWorkspace Workspace = Fact.Open(Propset,0) as IFeatureWorkspace;<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B>IFeatureClass Fcls = Workspace.OpenFeatureClass ("District");<br> <P></B> <P> <P align=left><B> IFeatureLayer Fly = new FeatureLayerClass();<br> <P></B> <P> <P align=left><B> Fly.FeatureClass = Fcls;<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> MapCtr.Map.AddLayer(Fly); <br> <P></B> <P> <P><B>MapCtr.ActiveView.Refresh();<br> <P></B> <P> <P><B>}<br> <P></B> <P> <P><B><FONT face="Times New Roman">B</FONT></B><B>、通过数据库名字加载个人数据库</B> <P> <P> <P>在这我先把完整的代码写出来,让您先跟上边的代码做个对比。以下为完整的代码:<br> <P> <P> <P><FONT face="Times New Roman">public void AddAccessDBByName()<br> <P></FONT> <P> <P align=left><B>{<br> <P></B> <P> <P align=left><B> IWorkspaceName pWorkspaceName = new WorkspaceNameClass() ;<br> <P></B> <P> <P align=left><B>pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory";<br> <P></B> <P> <P align=left><B> pWorkspaceName.PathName = @"D:\test\Ao\data\sh\MapData.mdb";<br> <P></B> <P> <P align=left><B> <P></B> <P> <P align=left><B> IName n = pWorkspaceName as IName ;<br> <P></B> <P> <P align=left><B> IFeatureWorkspace Workspace = n.Open() as IFeatureWorkspace;<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> IFeatureClass Fcls = Workspace.OpenFeatureClass ("District");<br> <P></B> <P> <P align=left><B> IFeatureLayer Fly = new FeatureLayerClass();<br> <P></B> <P> <P align=left><B> Fly.FeatureClass = Fcls;<br> <P></B> <P> <P align=left><B> <P></B> <P> <P align=left><B> MapCtr.Map.AddLayer (Fly); <br> <P></B> <P> <P align=left><B> MapCtr.ActiveView.Refresh();<br> <P></B> <P> <P align=left><B>}<br> <P></B> <P> <P align=left>细心的人已经注意到,打开<FONT face="Times New Roman">Access</FONT>工作空间后接下来的代码是一样的,都是找到对应的地物类,赋给相应的层,通过<FONT face="Times New Roman">MapControl</FONT>控件添加对应的层,然后刷新地图。现在讲解一下上边的代码,首先是创建一个个人数据库工作空间名<FONT face="Times New Roman">,</FONT>在指定工作空间名的ProgID,以确定打开的是什么类型的工作空间,例如在打开<FONT face="Times New Roman">Access</FONT>个人数据库时使用的是下边的代码:<br> <P> <P> <P align=left><B>IWorkspaceName pWorkspaceName = new WorkspaceNameClass() ;<br> <P></B> <P> <P align=left><B>pWorkspaceName.WorkspaceFactoryProgID = "esriDataSourcesGDB.AccessWorkspaceFactory";<br> <P></B> <P> <P align=left><B>pWorkspaceName.PathName = @"D:\test\Ao\data\sh\MapData.mdb";<br> <P></B> <P> <P><FONT face=宋体>属性</FONT>WorkspaceFactoryProgID<FONT face=宋体>可以确保工作空间是</FONT>AccessWorkspaceFactory<FONT face=宋体>,即个人数据库,同时指定要打开数据库的路径。为了打开数据库,我们通过</FONT>AE<FONT face=宋体>的类图可以发现打开工作空间必须使用</FONT>IName<FONT face=宋体>接口(个人认为,不一定正确,可以思考一下看有其他办法没有),所以接着定义</FONT>IName<FONT face=宋体>对象,并把工作空间名转换成</FONT>IName<FONT face=宋体>类型并赋值给</FONT>IName<FONT face=宋体>对象,然后通过</FONT>IName<FONT face=宋体>对象的</FONT>Open()<FONT face=宋体>方法打开相应的工作空间</FONT>,<FONT face=宋体>代码如下:<br> <P></FONT> <P> <P align=left><B>IName n = pWorkspaceName as IName ;<br> <P></B> <P> <P align=left><B>IFeatureWorkspace Workspace = n.Open () as IFeatureWorkspace;<br> <P></B> <P> <P><FONT face=宋体>接下来的事情就是上边提到。<br> <P></FONT> <P> <P><B><FONT face="Times New Roman">2</FONT></B><B>、加载</B><B><FONT face="Times New Roman">SDE</FONT></B><B>数据库</B><B> <P></B> <P> <P><FONT face=宋体>什么是</FONT>SDE<FONT face=宋体>数据库?这个问题要详细地讲解将花费大量的时间,但我可以告诉你</FONT>SDE<FONT face=宋体>数据数据库可以是任何关系数据库。</FONT>ESRI<FONT face=宋体>公司为了使空间数据能保存在关系数据库中,并且能很好的查询相关的空间属性而开发的一个中间件,使用</FONT>SDE<FONT face=宋体>能很好的将空间数据保存在关系数据库中。如</FONT>Orcale SQL Server <FONT face=宋体>等。</FONT>SDE<FONT face=宋体>具体细节的了解请查找相关的资料,这里只介绍怎么连接</FONT>SDE<FONT face=宋体>数据库。</FONT>SDE<FONT face=宋体>数据库的联机分为直接连接和通过</FONT>SDE<FONT face=宋体>连接。当服务器的性能比较好的时候可以采用</FONT>SDE<FONT face=宋体>连接,否则采用直接连接,这样可以减轻服务器的任务。建议采用直接连接,其实,</FONT>SDE<FONT face=宋体>连接方式和直接连接的方式只是一个属性参数设置的问题。跟个人数据库采用属性连接的方式一样,先定义一个属性对象,然后设置属性参数,接着定义一个工作空间并用</FONT>SdeWorkspaceFactoryClass()<FONT face=宋体>实例化它,接着加在加载图层</FONT>,<FONT face=宋体>至于加载图层的代码,与加载个人数据库中图层的方法一样,其实不只加载这两种数据类型,加载其他类型的数据时也是采用相同的方法加载图层,只是工作空间采用不同的实例而已,下边为完整的对吗</FONT>”//”<FONT face=宋体>后的为注析</FONT>:<br> <P> <P> <P><B><FONT face=宋体>public void AddSDELayer(bool ChkSdeLinkModle)<br> <P></FONT></B> <P> <P><B><FONT face=宋体>{<br> <P></FONT></B> <P> <P><FONT face=宋体><B> //</B><B>定义一个属性<br> <P></B></FONT> <P> <P align=left><B>IPropertySet Propset = new PropertySetClass(); <br> <P></B> <P> <P align=left><B> if (</B><B><FONT face="Times New Roman">ChkSdeLinkModle==true</FONT></B><B>) // </B><B>采用SDE连接<br> <P></B> <P> <P align=left><B> { <br> <P></B> <P> <P align=left><B> //</B><B>设置数据库服务器名<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("SERVER", "zhpzh");<br> <P></B> <P> <P align=left><B> //</B><B>设置SDE的端口,这是安装时指定的,默认安装时"port:5151"<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("INSTANCE", "port:5151");<br> <P></B> <P> <P align=left><B> //SDE</B><B>的用户名<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("USER", "sa");<br> <P></B> <P> <P align=left><B> //</B><B>密码<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("PASSWORD", "sa");<br> <P></B> <P> <P align=left><B>//</B><B>设置数据库的名字,只有SQL Server Informix 数据库才需要设置<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("DATABASE", "sde"); <br> <P></B> <P> <P align=left><B>//SDE</B><B>的版本,在这为默认版本 <br> <P></B> <P> <P align=left><B> Propset.SetProperty ("VERSION", "SDE.DEFAULT");<br> <P></B> <P> <P align=left><B> }<br> <P></B> <P> <P align=left><B> else // </B><B>直接连接<br> <P></B> <P> <P align=left><B> { <br> <P></B> <P> <P align=left><B> //</B><B>设置数据库服务器名,如果是本机可以用"sde:sqlserver:."<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("INSTANCE", "sde:sqlserver:zhpzh");<br> <P></B> <P> <P align=left><B> //SDE</B><B>的用户名<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("USER", "sa");<br> <P></B> <P> <P align=left><B> //</B><B>密码<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("PASSWORD", "sa"); <br> <P></B> <P> <P align=left><B>//</B><B>设置数据库的名字,只有SQL Server Informix 数据库才需要设置 Propset.SetProperty ("DATABASE", "sde"); <br> <P></B> <P> <P align=left><B>//SDE</B><B>的版本,在这为默认版本<br> <P></B> <P> <P align=left><B> Propset.SetProperty ("VERSION", "SDE.DEFAULT");<br> <P></B> <P> <P align=left><B> }<br> <P></B> <P> <P align=left><B> //</B><B>定义一个工作空间,并实力化为SDE的工作空间<br> <P></B> <P> <P align=left><B> IWorkspaceFactory Fact = new SdeWorkspaceFactoryClass();<br> <P></B> <P> <P align=left><B> //</B><B>打开SDE工作空间,并转化为地物工作空间<br> <P></B> <P> <P align=left><B>IFeatureWorkspace Workspace = (IFeatureWorkspace )Fact.Open(Propset,0);<br> <P></B> <P> <P align=left><B>/*</B><B>定义一个地物类,并打开SDE中的管点地物类,写的时候一定要写全.如SDE中有一个管点层,你不能写成IFeatureClass Fcls = Workspace.OpenFeatureClass ("管点");这样,一定要写成下边的样子.*/<br> <P></B> <P> <P align=left><B> IFeatureClass Fcls = Workspace.OpenFeatureClass ("sde.dbo.</B><B>管点");<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> IFeatureLayer Fly = new FeatureLayerClass ();<br> <P></B> <P> <P align=left><B> Fly.FeatureClass = Fcls;<br> <P></B> <P> <P align=left><B> MapCtr.Map.AddLayer (Fly); <br> <P></B> <P> <P align=left><B> MapCtr.ActiveView.Refresh (); <br> <P></B> <P> <P align=left><B> }<br> <P></B> <P> <P align=left>不知道注意到了没有<FONT face="Times New Roman">,</FONT>直接连接跟<FONT face="Times New Roman">SDE</FONT>连接的最大的不同是直接连接不要设置端口,同时他们的参数设置也不一样,好好注意参数的设置。</P> <P align=left><B>3、加载</B><B><FONT face="Times New Roman">CAD</FONT></B><B>图层</B></P> <P align=left>CAD图层的加载可以分为:分图层加载和整幅图加载<br> <P> <P> <P align=left><B>A、 </B><B>分图层加载</B> <P> <P> <P align=left>我们可以把CAD图分为点线面标注加载到MapControl中,跟加载其他数据一样,首先要定义一个工作空间,并用CadWorkspaceFactoryClass()实例化它,当得到了工作空间后就可以打开相应的工作空间,然后再打开指定的层类型。下边为完整的代码:<br> <P> <P> <P align=left> <B>public void AddCADByLayer()<br> {<br> <P></B> <P> <P align=left><B> //定义工作空间,并用CadWorkspaceFactoryClass()实例化它<br> <P></B> <P> <P align=left><B> IWorkspaceFactory Fact = new CadWorkspaceFactoryClass();<br> <P></B> <P> <P align=left><B> //打开相应的工作空间,并赋值给要素空间,OpenFromFile()<br> <P></B> <P> <P align=left><B> //中的参数为CAD文件夹的路径<br> <P></B> <P> <P align=left><B>IFeatureWorkspace Workspace = Fact.OpenFromFile(@"I:\test\",0) as IFeatureWorkspace;<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> /*</B><B>打开线要素类,如果要打开点类型的要素,需要把下边的代码该成:<br> <P></B> <P> <P align=left><B> IFeatureClass Fcls = Workspace.OpenFeatureClass ("modle.dwg:point");<br> <P></B> <P> <P align=left><B>由此可见modle.dwg为CAD图的名字,后边加上要打开的要素类的类型,中间用冒号 隔开,大家可以想想多边形和标注是怎么打开的。 */<br> <P></B> <P> <P align=left><B> IFeatureClass Fcls = Workspace.OpenFeatureClass ("modle.dwg:polyline");<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> IFeatureLayer Fly = new FeatureLayerClass ();<br> <P></B> <P> <P align=left><B> Fly.FeatureClass = Fcls;<br> <P></B> <P> <P align=left><B>MapCtr.Map.AddLayer (Fly); <br> <P></B> <P> <P align=left><B> MapCtr.ActiveView.Refresh ();<br> <P></B> <P> <P align=left><B>}<br> <P></B> <P> <P align=left><B>B、 </B><B>整幅CAD图的加载</B> <P> <P> <P align=left>当我们要加载整幅CAD图时,需要使用下边的代码,这跟加载地物类有一定的区别,详细地介绍请看代码中的注析:<br> <P> <P> <P align=left> <P> <P> <P align=left><B>public void AddWholeCAD()<br>{<br> <P></B> <P> <P align=left><B> </B><B>/*下边的两行代码是定义一个CAD工作空间,然后打开它,但这次不是赋值给<br> <P></B> <P> <P align=left><B> IFeatureWorkspace对象,而是赋值给IWorkspace定义的对象*/<br> <P></B> <P> <P align=left><B>IWorkspaceFactory Fact = new CadWorkspaceFactoryClass();<br> <P></B> <P> <P align=left><B> IWorkspace Workspace = Fact.OpenFromFile(@"I:\test\",0);<br> <P></B> <P> <P align=left><B> <br> <P></B> <P> <P align=left><B> //定义一个CAD画图空间,并把上边打开的工作空间赋给它<br> <P></B> <P> <P align=left><B> ICadDrawingWorkspace dw = Workspace as ICadDrawingWorkspace;<br> <P></B> <P> <P align=left><B> //定义一个CAD的画图数据集,并且打开上边指定的工作空间中一幅CAD图<br> <P></B> <P> <P align=left><B> //然后赋值给CAD数据集<br> <P></B> <P> <P align=left><B> ICadDrawingDataset ds = dw.OpenCadDrawingDataset ("modle.DWG");<br> <P></B> <P> <P align=left><B> //通过ICadLayer类,把上边得到的CAD数据局赋值给ICadLayer类对象的<br> <P></B> <P> <P align=left><B> //CadDrawingDataset属性<br> <P></B> <P> <P align=left><B> ICadLayer CadLayer = new CadLayerClass();<br> <P></B> <P> <P align=left><B> CadLayer.CadDrawingDataset = ds;<br> <P></B> <P> <P align=left><B> //</B><B>利用MapControl加载CAD层<br> <P></B> <P> <P align=left><B> MapCtr.Map.AddLayer (CadLayer); <br> <P></B> <P> <P align=left><B> MapCtr.ActiveView.Refresh ();<br> <P></B> <P> <P align=left><B>}<br> <P></B> <P> <P align=left>通过上边的代码和相关的解析,大家可能对整幅CAD图的加载有一个了解,但要具体搞清楚它的含义,也不那么容易。这留给大家去慢慢体会,在这我谈谈我自己的体会,但不一定正确。要打开数据集,首先要打开它的工作空间,至于什么是工作空间,我也说不太明白,但我的理解是,如果数据是保存在文件中的,工作空间大概就是它对应的文件夹,如果是数据库中的数据,我想大概就是对应的数据库。打开数据空间后,在这因为是整幅CAD图加载,所以跟以前的有点不同,这也就是相当整个CAD图就是一个数据集,所以要转到CAD画图的工作空间,然后把CAD图作为CAD数据集打开。为了在MapControl中加载CAD层,必须使用ICadLayer控件的对象,因为MapCtr.Map.AddLayer ()方法中只能是ICadLayer的对象。<br> <P> <P> <P align=left> <P> <P> <P align=left> <P> <P> <P align=left> <P> <P> <P align=left> <P> <P> <P align=left> <P> <P> <P align=left>本人这几天突发奇想,想写点东西,但没有修改,有很多大字错误。敬请原谅。如果大家觉得可以。我会接着写下去。把我自己的资料整理出来。供大家分享。<br> <P> <P> <P align=left> </P> [此贴子已经被作者于2009-6-3 17:59:11编辑过]
|
|
1楼#
发布于:2009-02-12 10:46
<P>强烈支持!!!怎么不继续了?</P>
|
|
2楼#
发布于:2008-11-12 12:21
<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em03.gif" /><img src="images/post/smile/dvbbs/em04.gif" /><img src="images/post/smile/dvbbs/em05.gif" /><img src="images/post/smile/dvbbs/em06.gif" /><img src="images/post/smile/dvbbs/em08.gif" />
|
|
3楼#
发布于:2008-11-02 16:28
很好,收藏了<img src="images/post/smile/dvbbs/em05.gif" />
|
|
4楼#
发布于:2008-07-27 14:19
楼主太牛了
<P>非常感谢留住的无私的奉献!</P><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em03.gif" /><img src="images/post/smile/dvbbs/em04.gif" /><img src="images/post/smile/dvbbs/em05.gif" /><img src="images/post/smile/dvbbs/em06.gif" /><img src="images/post/smile/dvbbs/em07.gif" /><img src="images/post/smile/dvbbs/em08.gif" /> |
|
5楼#
发布于:2008-06-18 17:43
<P>可惜没有后文了</P><img src="images/post/smile/dvbbs/em15.gif" />
|
|
6楼#
发布于:2008-05-30 12:11
<P>建议加精华</P>
|
|
7楼#
发布于:2008-05-30 11:59
学习了,路过<img src="images/post/smile/dvbbs/em01.gif" />
|
|
8楼#
发布于:2008-05-26 16:17
DDDDDDDDING
|
|
9楼#
发布于:2008-05-06 10:47
好贴<img src="images/post/smile/dvbbs/em02.gif" />
|
|
上一页
下一页