zhpzh1
路人甲
路人甲
  • 注册日期2004-03-12
  • 发帖数45
  • QQ
  • 铜币399枚
  • 威望0点
  • 贡献值0点
  • 银元0个
阅读:22837回复:71

AE数据加载

楼主#
更多 发布于:2006-07-09 13:51
<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编辑过]
喜欢0 评分0
zhpzh1
路人甲
路人甲
  • 注册日期2004-03-12
  • 发帖数45
  • QQ
  • 铜币399枚
  • 威望0点
  • 贡献值0点
  • 银元0个
1楼#
发布于:2006-07-11 11:56
AE开发编辑功能
<P align=center><B>数据编辑问题</B><B>
<br></B>
<p>
<P>在<FONT face="Times New Roman">AE</FONT>中数据的编辑是一个重点,也是一个难点。它包括的东西非常多,如:地物的添加,地物的修改,地物查询,节点捕捉,地物的符号化等一系列的问题。熟练的使用地物编辑的功能,是开发一个系统必须具备的条件。数据编辑问题解决得好坏直接决定着软件是否操作方便。在这我只是写一些相应的功能函数,至于软件开发中的架构,我不考虑。
<p>
<p>
<P><B><FONT face="Times New Roman">1、 </FONT></B><B>添加地物</B><B>
<p></B>
<p>
<P>什么是地物,这是<FONT face="Times New Roman"> GIS</FONT>的基本概念,我在这不想多说,我只想说明一点,地物可以表现在地图上,如房子、铁路、水管等等。我们把房子的总称称为一个地物类,在<FONT face="Times New Roman">AE</FONT>中对应一个地物类(<FONT face="Times New Roman">IFeatureClass</FONT>),一个地物类在地图上表示为一个地物层(<FONT face="Times New Roman">IFeatureLayer</FONT>),单独的一栋房子或一条管道我们称为地物(<FONT face="Times New Roman">IFeature</FONT>),<FONT face="Times New Roman">Arcgis</FONT>中一类地物只能放在一个层,通过图层的叠加组成一幅地图。
<p>
<p>
<P>熟悉面向对象的编程语言的人都知道,其实上边的地物类,地物的概念就是类和实体的概念。房子、铁路、水管等是一类地物的抽象,而具体的某一房子就是对象了。大家了解了这一点。接下来的开发就容易理解一些了。当然,还有一些其他的概念也必须了解一下:如长事务、短事务、编辑空间等。请大家查找一些相关资料,了解这方面的内容。
<p>
<p>
<P>我们先开始最基本的编辑功能:添加点线面的操作。它包括输入添加点线面和通过鼠标拖动添加点线面。下边讨论一下添加点线面的基本的实现方法:
<p>
<p>
<P><FONT face="Times New Roman">一、</FONT><B>添加点</B><B>
<p></B>
<p>
<P>我们可以有多种方法添加点,但基本的思路一样,只是有少量的接口有变化。下边是通过<FONT face="Times New Roman">FeatrueClass</FONT>的<FONT face="Times New Roman">CreateFeature</FONT>()函数添加地物。
<p>
<p>
<P align=left>public void AddPointByStore()
<p>
<p>
<P align=left>      {
<p>
<p>
<P align=left>              //得到要添加地物的图层
<p>
<p>
<P align=left>              IFeatureLayer l = MapCtr.Map.get_Layer(0) as IFeatureLayer;
<p>
<p>
<P align=left>              //定义一个地物类,把要编辑的图层转化为定义的地物类
<p>
<p>
<P align=left>              IFeatureClass fc = l.FeatureClass ;
<p>
<p>
<P align=left>              //先定义一个编辑的工作空间,然后把转化为数据集,最后转化为编辑工作空间,
<p>
<p>
<P align=left>              IWorkspaceEdit w = (fc as IDataset).Workspace as IWorkspaceEdit;
<p>
<p>
<P align=left>              IFeature f ;
<p>
<p>
<P align=left>              IPoint p;
<p>
<p>
<P align=left>              //开始事务操作
<p>
<p>
<P align=left>              w.StartEditing (false);
<p>
<p>
<P align=left>              //开始编辑
<p>
<p>
<P align=left>              w.StartEditOperation() ;
<p>
<p>
<P align=left>              for (int i = 0 ; i< 100 ; i++ )
<p>
<p>
<P align=left>              {
<p>
<p>
<P align=left>                   //创建一个地物
<p>
<p>
<P align=left>                   f= fc.CreateFeature();
<p>
<p>
<P align=left>                   p = new PointClass();
<p>
<p>
<P align=left>                   //设置点的坐标
<p>
<p>
<P align=left>                   p.PutCoords (i,i);
<p>
<p>
<P align=left>                   //确定图形类型
<p>
<p>
<P align=left>                   f.Shape = p;
<p>
<p>
<P align=left>                   //保存地物
<p>
<p>
<P align=left>                   f.Store();    
<p>
<p>
<P align=left>              }
<p>
<p>
<P align=left>              //结束编辑
<p>
<p>
<P align=left>              w.StopEditOperation();
<p>
<p>
<P align=left>              //结束事务操作
<p>
<p>
<P align=left>              w.StopEditing(true);
<p>
<p>
<P align=left>}
<p>
<p>
<P>上边的代码能添加点地物,但不能作为最终的代码使用,细心的人会看到。这段代码只是把第一层加进来,然后在第一层上边添加点地物,如果第一层不是点层,该怎么办,那就要判断了。怎么判断我们以后再说。通过上边的代码,我们已经清楚地了解到,编辑地物的基本框架,这也是我们所说的事务,如果想操作能返回和重做,就必须把代码写在<FONT face="Times New Roman">IWorkspaceEdit</FONT>的<FONT face="Times New Roman">StartEditing()</FONT>和<FONT face="Times New Roman">StopEditing()</FONT>函数之间,把相关的操作写在<FONT face="Times New Roman">IWorkspaceEdit</FONT>的<FONT face="Times New Roman">StartEditOperation()</FONT>和<FONT face="Times New Roman">StopEditOperation()</FONT>之间。并且操作是利用<FONT face="Times New Roman">IWorkspaceEdit</FONT>接口完成的,所以要仔细理会<FONT face="Times New Roman">IWorkspaceEdit</FONT>接口的用处,如何工作空间都可以转化为<FONT face="Times New Roman">IWorkspaceEdit</FONT>的对象,当转化为<FONT face="Times New Roman">IWorkspaceEdit</FONT>定义的对象后,我们定义一个<FONT face="Times New Roman">IFeature</FONT>的对象,然后利用<FONT face="Times New Roman">IFeatureClass</FONT>的<FONT face="Times New Roman">CreateFeature()</FONT>函数创建一个地物,并赋值给定义的<FONT face="Times New Roman">IFeature</FONT>对象。接着设置<FONT face="Times New Roman">IFeature</FONT>对象的一些属性,如:坐标值,坐标系,地物类型等,最后是调用<FONT face="Times New Roman">IFeature</FONT>对象的<FONT face="Times New Roman">Store()</FONT>保存添加的地物。
<p>
<p>
<P>上边的方法可以添加点地物,接着看看下边的代码。看有什么不同:
<p>
<p>
<P align=left>public void AddPointByWrite()
<p>
<p>
<P align=left>     {
<p>
<p>
<P align=left>         IFeatureLayer l = MapCtr.Map.get_Layer(0) as IFeatureLayer;
<p>
<p>
<P align=left>         IFeatureClass fc = l.FeatureClass ;
<p>
<p>
<P align=left>         IFeatureClassWrite fr = fc as IFeatureClassWrite ;
<p>
<p>
<P align=left>         IWorkspaceEdit w = (fc as IDataset).Workspace as IWorkspaceEdit;
<p>
<p>
<P align=left>         IFeature f ;  
<p>
<p>
<P align=left>         IPoint p;
<p>
<p>
<P align=left>         w.StartEditing (true);
<p>
<p>
<P align=left>         w.StartEditOperation() ;
<p>
<p>
<P align=left>         for (int i = 0 ; i< 100 ; i++ )
<p>
<p>
<P align=left>         {
<p>
<p>
<P align=left>              f= fc.CreateFeature();
<p>
<p>
<P align=left>              p = new PointClass();
<p>
<p>
<P align=left>              p.PutCoords (i,i);
<p>
<p>
<P align=left>              f.Shape = p;
<p>
<p>
<P align=left>              fr.WriteFeature (f);
<p>
<p>
<P align=left>         }
<p>
<p>
<P align=left>              w.StopEditOperation();
<p>
<p>
<P align=left>              w.StopEditing(true);
<p>
<p>
<P align=left>     }
<p>
<p>
<P>代码中用红色标记的两行就是不同的代码,其实他就是保存方式的不同而已。在这利用了<FONT face="Times New Roman">IFeatureClassWrite </FONT>接口来保存数据。再看看下边的代码:
<p>
<p>
<P align=left>         public void AddPointByBuffer()
<p>
<p>
<P align=left>         {
<p>
<p>
<P align=left>              IFeatureLayer l = MapCtr.Map.get_Layer(0) as IFeatureLayer;
<p>
<p>
<P align=left>              IFeatureClass fc = l.FeatureClass ;
<p>
<p>
<P align=left>              IWorkspaceEdit w = (fc as IDataset).Workspace as IWorkspaceEdit;
<p>
<p>
<P align=left>              w.StartEditing (true);
<p>
<p>
<P align=left>              w.StartEditOperation() ;
<p>
<p>
<P align=left>              IPoint p;
<p>
<p>
<P align=left>              IFeatureBuffer f;
<p>
<p>
<P align=left>              IFeatureCursor cur = fc.Insert(true);
<p>
<p>
<P align=left>              for (int i = 0 ; i< 100 ; i++ )
<p>
<p>
<P align=left>              {
<p>
<p>
<P align=left>                   f= fc.CreateFeatureBuffer();
<p>
<p>
<P align=left>                   p = new PointClass();
<p>
<p>
<P align=left>                   p.PutCoords (i,i);
<p>
<p>
<P align=left>                   f.Shape = p;
<p>
<p>
<P align=left>                   cur.InsertFeature (f);
<p>
<p>
<P align=left>              }
<p>
<p>
<P align=left>              w.StopEditOperation();
<p>
<p>
<P align=left>              w.StopEditing(true);
<p>
<p>
<P>     }<FONT face="Times New Roman">
<p></FONT>
<p>
<P>其实不同的地方就两句代码,红色表示的。在这没有再定义地物接口了(<FONT face="Times New Roman">IFeature</FONT>),而是使用<FONT face="Times New Roman">IFeatureBuffer </FONT>接口,保存的时候是使用<FONT face="Times New Roman">InsertFeature()</FONT>保存,这对大数据量处理的非常有好处。他是先把要添加的保存到缓冲区里。最后一次性保存。<FONT face="Times New Roman">
<p></FONT>
<p>
<P><FONT face="Times New Roman">二、</FONT><B>添加线</B><B>
<p></B>
<p>
<P>添加线的方法跟添加点一样,不同的只是地物类型不一样而已,我把代码贴出来,大家跟添加点的方式进行对比。这样便于记忆。也有利于理解。
<p>
<p>
<P align=left>     public void AddLineByWrite()
<p>
<p>
<P align=left>     {
<p>
<p>
<P align=left>         IFeatureLayer l = MapCtr.Map.get_Layer(0) as IFeatureLayer;
<p>
<p>
<P align=left>         IFeatureClass fc = l.FeatureClass ;
<p>
<p>
<P align=left>         IFeatureClassWrite fr = fc as IFeatureClassWrite ;
<p>
<p>
<P align=left>         IWorkspaceEdit w = (fc as IDataset).Workspace as IWorkspaceEdit;
<p>
<p>
<P align=left>         IFeature f ;  
<p>
<p>
<P align=left>//可选参数的设置
<p>
<p>
<P align=left>object Missing = Type.Missing;
<p>
<p>
<P align=left>         IPoint p=new PointClass();
<p>
<p>
<P align=left>         w.StartEditing (true);
<p>
<p>
<P align=left>         w.StartEditOperation() ;
<p>
<p>
<P align=left>         for (int i = 0 ; i< 100 ; i++ )
<p>
<p>
<P align=left>         {
<p>
<p>
<P align=left>              f = fc.CreateFeature();
<p>
<p>
<P align=left>              //定义一个多义线对象
<p>
<p>
<P align=left>              IPolyline PlyLine=new PolylineClass();
<p>
<p>
<P align=left>              //定义一个点的集合
<p>
<p>
<P align=left>              IPointCollection ptclo = PlyLine as IPointCollection;
<p>
<p>
<P align=left>              //定义一系列要添加到多义线上的点对象,并赋初始值
<p>
<p>
<P align=left>              for(int j=0;j<4;j++)
<p>
<p>
<P align=left>              {  
<p>
<p>
<P align=left>                   p.PutCoords(j,j);
<p>
<p>
<P align=left>                   ptclo.AddPoint(p,ref Missing,ref Missing);
<p>
<p>
<P align=left>              }
<p>
<p>
<P align=left>                   f.Shape = PlyLine;
<p>
<p>
<P align=left>                   fr.WriteFeature (f);
<p>
<p>
<P align=left>         }
<p>
<p>
<P align=left>              w.StopEditOperation();
<p>
<p>
<P align=left>              w.StopEditing(true);
<p>
<p>
<P>}
<p>
<p>
<P>至于添加线的其他两种方法,通过修改添加点的代码,就可以得到。可以自己想想然后测试,这样便于记忆和理解。
<p>
<p>
<P><B></B> </P>
[此贴子已经被作者于2009-6-3 18:00:37编辑过]
举报 回复(0) 喜欢(0)     评分
cl991036
管理员
管理员
  • 注册日期2003-07-25
  • 发帖数5913
  • QQ14265545
  • 铜币29654枚
  • 威望213点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • GIS帝国铁杆
2楼#
发布于:2006-07-11 14:17
<P>不错的贴</P>
<P>加精华</P>
没钱又丑,农村户口。头可断,发型一定不能乱。 邮箱:gisempire@qq.com
举报 回复(0) 喜欢(0)     评分
crx509
路人甲
路人甲
  • 注册日期2005-04-27
  • 发帖数20
  • QQ
  • 铜币192枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2006-07-12 10:27
<P>楼主的帖子太好了 ,强烈支持!!!</P>
举报 回复(0) 喜欢(0)     评分
tjianp955
路人甲
路人甲
  • 注册日期2006-04-03
  • 发帖数53
  • QQ
  • 铜币436枚
  • 威望0点
  • 贡献值0点
  • 银元0个
4楼#
发布于:2006-07-12 16:29
<P>楼主继续啊!!!</P>
<P>强烈支持!!!</P>
举报 回复(0) 喜欢(0)     评分
helloqj
路人甲
路人甲
  • 注册日期2004-09-04
  • 发帖数3
  • QQ
  • 铜币132枚
  • 威望0点
  • 贡献值0点
  • 银元0个
5楼#
发布于:2006-07-13 19:49
好贴!顶
举报 回复(0) 喜欢(0)     评分
zhpzh1
路人甲
路人甲
  • 注册日期2004-03-12
  • 发帖数45
  • QQ
  • 铜币399枚
  • 威望0点
  • 贡献值0点
  • 银元0个
6楼#
发布于:2006-07-14 09:00
<P>我这近忙于项目。过段时间我会继续。谢谢大家支持。本人有个想法 。我想开辟一个群,定时跟大家交流AE技术。不知道大家有兴趣没有。21349054,交流的时间会在公告栏提示。</P>
举报 回复(0) 喜欢(0)     评分
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
7楼#
发布于:2006-07-14 09:09
<P>进来支持下楼主,你的教程很好,不过我觉得最好是能提供一些事例程序,那样初学的就更有福了</P><img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em02.gif" />
举报 回复(0) 喜欢(0)     评分
semon1981
路人甲
路人甲
  • 注册日期2006-06-04
  • 发帖数28
  • QQ
  • 铜币198枚
  • 威望0点
  • 贡献值0点
  • 银元0个
8楼#
发布于:2006-07-14 14:10
<P>不错</P>
<P>支持</P>
举报 回复(0) 喜欢(0)     评分
tnth2so4
路人甲
路人甲
  • 注册日期2004-10-20
  • 发帖数7
  • QQ
  • 铜币116枚
  • 威望0点
  • 贡献值0点
  • 银元0个
9楼#
发布于:2006-07-18 13:47
高,实在是高<img src="images/post/smile/dvbbs/em01.gif" /><img src="images/post/smile/dvbbs/em02.gif" /><img src="images/post/smile/dvbbs/em06.gif" />
举报 回复(0) 喜欢(0)     评分
上一页
游客

返回顶部