gpt4 book ai didi

ArcObjectsSDK开发010FeatureLayer

转载 作者:我是一只小鸟 更新时间:2022-12-02 22:31:51 30 4
gpt4 key购买 nike

1、FeatureLayer的结构 。

FeatureLayer是我们开发的时候用的最多的API之一,其实现的接口以及关联的其他API也非常多。下面我们就用一张图来整体看下FeatureLayer有哪些常用的功能.

image1.png

FeatureLayer类继承实现了非常多的接口。每个接口主要负责什么功能呢?我们可以参考每个接口定义属性和函数,还有一个更直观的方法,就是最找ArcMap软件.

IFeatureLayer接口的FeatureClass属性主要对应着矢量图层属性对话框中的Source选项卡 。IGeoFeatureLayer的Renderer属性对应Symbology选项卡,AnnotationProperties属性对应着Labels选项卡。IFeatureSelection接口对应Selection选项卡。ILayerFields接口对应着Fields选项卡。ILayerGeneralProperties接口对应General选项卡。IFeatureLayerDefinition接口对应Definition Query选项卡。IHTMLPopupInfo以及相似名字的几个接口对应着HTML Popup选项卡。IRelationshipClassCollection接口对应Joins&Relates选项卡。矢量图层属性对话框如下图所示.

image2.png

2、IFeatureClass接口 。

IFeatureLayer的FeatureClass属性返回的是IFeatureClass类型,这就是我们的矢量图层实际指向的数据源。我们用代码打开一个Shape文件,获得的就是一个IFeatureClass对象。FeatureLayer的FeatureClass属性对应的属性标签如下图所示.

image3.png

如果我们打开的是一个Shape文件,通过上图以及参考SDK的API,能够直观的看出可以获得数据的空间范围、数据类型、文件路径、几何体类型、空间参考等信息.

FeatureClass,我们可以理解为有一个几何体字段的二维数据表。二维数据表字段、有数据行,FeatureClass中的字段定义是IField,数据行定位为IFeature。因为包含一个几何体字段,所有就区分几何体类型,是Point、Polyline或者Polygon。所示IField的类型就多了一个几何体类型,定义为esriFieldType. esriFieldTypeGeometry。IFeature也有一个属性,名为Shape,返回该数据行存储的几何体.

image4.png

3、IFeatureRenderer接口 。

通过IGeoFeatureLayer的Renderer属性可以获得地图的渲染对象IFeatureRenderer,IFeatureRender对应了矢量图层选项卡中的Symbology,如下图所示.

image5.png

该选项卡中做的为矢量图层可使用的渲染类型,有的为选中的渲染类型的属性信息。矢量图层支持哪些渲染方式,可展开左侧树结构查看,也可以在ArcObject SDK的帮助中查看有哪些类继承实现了IFeatureRenderer接口,两者是可以对应起来的.

image6.png

以最简单的SimpleRenderer为例,其对应的是渲染界面上的Single symbol项,这点在帮助里面也有说明.

image7.png

其主接口为ISimpleRenderer,其定义基本上也和ArcMap上的UI是对应起来的,如下图所示.

截图.png

4、IAnnotateLayerProperties接口 。

通过IGeoFeatureLayer接口的AnnotationProperties属性可以获取IAnnotateLayerPropertiesCollection接口,该接口是IAnnotateLayerProperties的集合,包含多个IAnnotateLayerProperties接口实例。这点我们也可以在ArcMap的Label标签页中验证,矢量图层在Label的时候,可以设置多种Label规则。如下图所示.

image9.png

实现IAnnotateLayerProperties接口的类有两个,我们常用的是 LabelEngineLayerProperties,而LabelEngineLayerProperties又继承了ILabelEngineLayerProperties、ILabelEngineLayerProperties2等接口。这些接口定义的信息,基本上就能把Label选项卡中的内容对应上了.

5、IFeatureSelection接口 。

FeatureLayer实现继承了IFeatureSelection接口,该接口定义的内容可以Selection选项卡里找到.

image11.png

IFeatureSelection的SelectFeatures可以通过设置查询条件来选择或者反选要素。查询条件既可以设置为属性查询条件,也可以设置为空间查询条件.

image12.png

IQueryFilter接口定义入下.

image13.png

esriSelectionResultEnum枚举的定义如下.

image14.png

6、Search函数 。

IFeatureLayer和IFeatureClass都有Search函数,两者有什么区别呢?我们先看IFeatureLayer的Search函数。我们打开IFeatureLayer. Search函数的帮助,如下图所示.

image15.png

下面备注中的文字大概是以下意思.

如果该图层定义了查询集,有就是说在IFeatureLayerDefinition接口的DefinitionExpression属性(ArcMap的Definition Query标签页)定义了查询条件,那么IFeatureLayer的Search函数就会在该查询的基础上进行查询。如果该图层使用Join连接了某个图层或者属性表,但查询的字段有该连接对象的字段,那么请调用IGeoFeatureLayer.SearchDisplayFeatures函数.

IFeatureLayer.Search函数返回的游标,也就是IFeatureCursor接口,不能用来更新要素,如果想更新要素,请使用IFeatureClass.Update函数.

回收游标第二个参数设置为true,否则设置为false。一般我们调用IFeatureLayer.Search函数后,返回的是IFeatureCursor,我们称为要素游标,通过该游标可以遍历查找结果。一般遍历方法如下所示.

                          IFeatureCursor myFeatureCursor = myFeatureLayer.Search(myQueryFilter, 
                          
                            false
                          
                          
                            );
IFeature myFeature 
                          
                          =
                          
                             myFeatureCursor.NextFeature();

                          
                          
                            while
                          
                           (myFeature != 
                          
                            null
                          
                          
                            )
{
    myFeature 
                          
                          =
                          
                             myFeatureCursor.NextFeature();
}
ComReleaser.ReleaseCOMObject(myFeatureCursor);
                          
                        

如果传false,FeatureCursor.NextFeature之后,上一个IFeature还可以使用,如果是true,则就不能用了。传true会更节约内存,但你要把你想取的信息全部都取出来.

IFeatureClass的Search函数与IFeatureLayer的Search函数类似,只是其在原始数据的基础上查询,和图层的设置没有关系.

7、IFeatureClass.Insert函数 。

该函数用来批量添加要素。如果我们添加一个要素,可以调用IFeatureClass. CreateFeature函数,得到一个IFeature实例,然后对其赋值,最后调用IFeature的Store函数即可。但如果我们要批量添加多个要素,就要调用IFeatureClass.Insert函数,得到要素添加游标,在该游标上添加要素,最后一起提交即可。调用Insert函数的代码基本上都是一样的,使用的时候参考下面的模板即可.

                          IFeatureBuffer myFeatureBuffer =
                          
                             myFeatureClass.CreateFeatureBuffer();
IFeatureCursor myFeatureCursor 
                          
                          = myFeatureClass.Insert(
                          
                            true
                          
                          
                            );

                          
                          
                            for
                          
                           (
                          
                            int
                          
                           i = 
                          
                            0
                          
                          ; i < myXList.Count; i++
                          
                            )
{
    
                          
                          
                            var
                          
                           myPoint = 
                          
                            new
                          
                          
                             PointClass
    {
        X 
                          
                          =
                          
                             myXList[i],
        Y 
                          
                          =
                          
                             myYList[i]
    };
    myFeatureBuffer.Shape 
                          
                          =
                          
                             myPoint;
    myFeatureBuffer.Value[
                          
                          
                            2
                          
                          ] =
                          
                             i;
    myFeatureBuffer.Value[
                          
                          
                            3
                          
                          ] = 
                          
                            0
                          
                          
                            ;
    myFeatureCursor.InsertFeature(myFeatureBuffer);
    
                          
                          
                            if
                          
                           (i % 
                          
                            1000
                          
                           == 
                          
                            0
                          
                          
                            )
    {
        myFeatureCursor.Flush();
    }
}

                          
                          
                            if
                          
                           (
                          
                            this
                          
                          .InputDataTable.Rows.Count % 
                          
                            1000
                          
                           > 
                          
                            0
                          
                          
                            )
{
    myFeatureCursor.Flush();
}
ComReleaser.ReleaseCOMObject(myFeatureCursor);
                          
                        

FeatureCursor.Flush()是提交函数,如果添加的要素太多,最后一次性提交,会导致运行太慢哪,把进度条卡住,所以我一般会每1000条提交依次,这个数可以根据实际情况修改.

8、IFeatureClass.Update函数 。

该函数用看来批量更新要素。和Insert函数类似,如果我们只是操作一个要素,可以在获取IFeature之后,修改其属性值,调用最后调用IFeature的Store函数即可。但如果要批量更新,则建议采用IFeatureClass.Update函数,效率会比较高。调用Update函数的代码基本上都是一样的,使用的时候参考下面的模板即可.

                          
                            int
                          
                           myLevelFieldIndex = myFeatureClass.FindField(
                          
                            "
                          
                          
                            Level
                          
                          
                            "
                          
                          
                            );

                          
                          
                            int
                          
                           myValueFieldIndex = myFeatureClass.FindField(
                          
                            "
                          
                          
                            Value
                          
                          
                            "
                          
                          
                            );
IFeatureCursor myFeatureCursor 
                          
                          = myFeatureClass.Update(
                          
                            null
                          
                          , 
                          
                            true
                          
                          
                            );
IFeature myFeature 
                          
                          =
                          
                             myFeatureCursor.NextFeature();

                          
                          
                            while
                          
                           (myFeature != 
                          
                            null
                          
                          
                            )
{
    
                          
                          
                            double
                          
                           myValue =
                          
                             Convert.ToDouble(myFeature.Value[myValueFieldIndex]);
    myFeature.Value[myLevelFieldIndex] 
                          
                          = 
                          
                            this
                          
                          
                            .GetLevel(myValue);
    myFeatureCursor.UpdateFeature(myFeature);
    myFeature 
                          
                          =
                          
                             myFeatureCursor.NextFeature();
}
ComReleaser.ReleaseCOMObject(myFeatureCursor);
                          
                        

9、ITable. DeleteSearchedRows 函数 。

该函数用来批量删除要素。如果要删除单个要素,可以调用得到的IFeature.Delete函数。如果批量删除或者根据某个条件来删除要素,则可以调用ITable.DeleteSearchedRows函数。FeatureClass是继承实现了ITable接口的,所以我们把IFeature接口转换成ITable接口,调用该函数即可。一般调用代码如下.

                          ITable myTabel = 
                          
                            this
                          
                          .PointFeatureLayer.FeatureClass 
                          
                            as
                          
                          
                             ITable;
IQueryFilter myQueryFilter 
                          
                          = 
                          
                            new
                          
                          
                             QueryFilterClass
{
    WhereClause 
                          
                          = 
                          
                            "
                          
                          
                            RowIndex=
                          
                          
                            "
                          
                           +
                          
                             pRowIndex.ToString()
};
myTabel.DeleteSearchedRows(myQueryFilter);
                          
                        

ITable.DeleteSearchedRows函数的参数为IQueryFilter,除了QueryFilter类外,SpatialFilter类也继承了该接口。但DeleteSearchedRows函数又是在ITable接口中定义的,那这个函数是不是支持SpatialFilter,可以去验证下,但我感觉应该是支持的.

10、IField接口和IFieldInfo接口 。

获取字段有两种方式,一是通过FeatureLayer继承实现了ILayerFields接口获取字段,另外一种是通过矢量数据源IFeatureClass的Fields属性获取IFields接口获取字段信息.

我们先看下IFields接口,如下图所示.

image16.png

可以通过索引或字段名称获取具体的字段信息,返回是IField接口。我们再看下ILayerFields接口的定义.

image17.png

我们看到除了返回IField外,还可以返回IFieldInfo,这两个有什么区别呢?IField是数据源中字段的定义,IFieldInfo是图层对字段定义的扩展。我们看下IFieldInfo的定义,如下图所示.

image18.png

在IField的基础上扩展了字段别名,按照字符串返回某个要素该字段的值,属性表显示的时候该字段是否高亮显示,数字显示格式、是否只读、字段是否按照比率显示,是否可见。我们常用的主要有别名、是否可见等属性。这些信息对应了ArcMap矢量属性对话框中的Fields选显卡,如下图所示.

image19.png

右侧字段详细信息分为两组,上面可设置的部分为IFieldInfo的信息,下面只读的信息为IField信息.

11、字段操作 。

对字段相关的操作主要是添加和删除。在Arcobjects中很少更新字段,基本上都是添加新字段,把旧字段的值设置到新字段中,删除旧字段.

添加字段可以实例化一个IField对象,然后通过IFeatureClass的AddField函数添加字段。添加的时候需要注意,数据源不要被其他应用占用,否则会发生锁定错误.

                          
                            var
                          
                           myFeatureClass =
                          
                             ShapeFileHelper.OpenShapeFile(pContourPolygonFile);
IField myField 
                          
                          = 
                          
                            new
                          
                          
                             Field();
IFieldEdit myFieldEdit 
                          
                          = myField 
                          
                            as
                          
                          
                             IFieldEdit;
myFieldEdit.Name_2 
                          
                          = 
                          
                            "
                          
                          
                            Level
                          
                          
                            "
                          
                          
                            ;
myFieldEdit.Type_2 
                          
                          =
                          
                             esriFieldType.esriFieldTypeInteger;
myFeatureClass.AddField(myField);
                          
                        

删除字段可调用IFeatureClass的DeleteField函数,调用的时候,还是需要注意,数据源不要被其他应用占用,否则会发生锁定错误.

12、打开Shape文件 。

打开Shape文件后,我们就可以获得IFeatureClas。打开Shape文件的代码比较固定,使用下面的代码打开即可.

                          
                            var
                          
                           myType = Type.GetTypeFromProgID(
                          
                            "
                          
                          
                            esriDataSourcesFile.ShapefileWorkspaceFactory
                          
                          
                            "
                          
                          
                            );

                          
                          
                            var
                          
                           myObject =
                          
                             Activator.CreateInstance(myType);

                          
                          
                            var
                          
                           myWorkspaceFactory = myObject 
                          
                            as
                          
                          
                             IWorkspaceFactory;

                          
                          
                            var
                          
                           myFeatureWorkspace = myWorkspaceFactory.OpenFromFile(System.IO.Path.GetDirectoryName(pShapeFilePath), 
                          
                            0
                          
                          ) 
                          
                            as
                          
                          
                             IFeatureWorkspace;

                          
                          
                            return
                          
                           myFeatureWorkspace.OpenFeatureClass(System.IO.Path.GetFileNameWithoutExtension(pShapeFilePath));
                        

13、创建Shape文件 。

创建Shape文件代码模式也很固定,即使是往gbd或者企业sde数据库中创建矢量数据的时候,我一般也喜欢先在一个临时目录下创建shape文件,然后调用Arctoolbox里面的工具,把这个数据拷贝到目标工作空间中。主要还是因为直接创建shape文件更简单,更稳定,而且不用考虑针对那么多数据源再分别写代码.

创建一个Shape文件的代码如下.

                          
                            string
                          
                           myFolderPath =
                          
                             System.IO.Path.GetDirectoryName(pShapeFilePath);

                          
                          
                            if
                          
                           (System.IO.Directory.Exists(myFolderPath) == 
                          
                            false
                          
                          
                            )
{
    System.IO.Directory.CreateDirectory(myFolderPath);
}

                          
                          
                            string
                          
                           myFileName =
                          
                             System.IO.Path.GetFileName(pShapeFilePath);

                          
                          
                            var
                          
                           myType = Type.GetTypeFromProgID(
                          
                            "
                          
                          
                            esriDataSourcesFile.ShapefileWorkspaceFactory
                          
                          
                            "
                          
                          
                            );

                          
                          
                            object
                          
                           myObject =
                          
                             Activator.CreateInstance(myType);

                          
                          
                            var
                          
                           myWorkspaceFactory = myObject 
                          
                            as
                          
                          
                             IWorkspaceFactory;

                          
                          
                            var
                          
                           myFeatureWorkspace = myWorkspaceFactory.OpenFromFile(myFolderPath, 
                          
                            0
                          
                          ) 
                          
                            as
                          
                          
                             IFeatureWorkspace;

                          
                          
                            //
                          
                          
                            定义字段信息
                          
                          
                            var
                          
                           myFields = 
                          
                            new
                          
                          
                             FieldsClass();

                          
                          
                            var
                          
                           myFieldsEdit = myFields 
                          
                            as
                          
                          
                             IFieldsEdit;

                          
                          
                            foreach
                          
                           (IField myField 
                          
                            in
                          
                          
                             pFieldList)
{
    myFieldsEdit.AddField(myField);
}

                          
                          
                            //
                          
                          
                            创建shapefile 
                          
                          
IFeatureClass myFeatureClass = 
                          
                            null
                          
                          
                            ;

                          
                          
                            try
                          
                          
                            
{
    myFeatureClass 
                          
                          = myFeatureWorkspace.CreateFeatureClass(myFileName, myFields, 
                          
                            null
                          
                          , 
                          
                            null
                          
                          , esriFeatureType.esriFTSimple, 
                          
                            "
                          
                          
                            shape
                          
                          
                            "
                          
                          , 
                          
                            ""
                          
                          
                            );
}

                          
                          
                            finally
                          
                          
                            
{
    ComReleaser.ReleaseCOMObject(myWorkspaceFactory);
}

                          
                          
                            return
                          
                           myFeatureClass;
                        

创建完之后,得到IFeatureClass,如果不需要,就可以把该对象释放掉。如果需要添加要素,则可以通过调用其Insert函数,批量添加要素。如果想添加到地图上,则实例化一个FeatureLayer,把该对象赋值给FeatureLayer的FeatureClass对象,然后设置渲染样式,即可添加到地图上展示.

最后此篇关于ArcObjectsSDK开发010FeatureLayer的文章就讲到这里了,如果你想了解更多关于ArcObjectsSDK开发010FeatureLayer的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com