基于C#的ArcEngine二次开发32:属性sql查询语句与IMap,ILayer,IFeatureLayer,IFeatureClass关系

简介: 基于C#的ArcEngine二次开发32:属性sql查询语句与IMap,ILayer,IFeatureLayer,IFeatureClass关系

1 ArcGIS中定义查询和属性查询

1.1 SQL语句

20190626174116479.png以SQL模糊查询LIKE运算符对应的通配符为例

20190626180811669.png

通配符查询

image.png


从图层中选择要素的代码:

///<summary>Select features in the IActiveView by an attribute query using a SQL syntax in a where clause.</summary>
/// 
///<param name="activeView">An IActiveView interface</param>
///<param name="featureLayer">An IFeatureLayer interface to select upon</param>
///<param name="whereClause">A System.String that is the SQL where clause syntax to select features. Example: "CityName = 'Redlands'"</param>
///  
///<remarks>Providing and empty string "" will return all records.</remarks>
public void SelectMapFeaturesByAttributeQuery(ESRI.ArcGIS.Carto.IActiveView activeView, ESRI.ArcGIS.Carto.IFeatureLayer featureLayer, System.String whereClause)
{
      if(activeView == null || featureLayer == null || whereClause == null)
      {
        return;
      }
      ESRI.ArcGIS.Carto.IFeatureSelection featureSelection = featureLayer as ESRI.ArcGIS.Carto.IFeatureSelection; // Dynamic Cast
      // Set up the query
      ESRI.ArcGIS.Geodatabase.IQueryFilter queryFilter = new ESRI.ArcGIS.Geodatabase.QueryFilterClass();
      queryFilter.WhereClause = whereClause;
      // Invalidate only the selection cache. Flag the original selection
      activeView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null);
      // Perform the selection
      featureSelection.SelectFeatures(queryFilter, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResultNew, false);
      // Flag the new selection
      activeView.PartialRefresh(ESRI.ArcGIS.Carto.esriViewDrawPhase.esriViewGeoSelection, null, null);
}

whereas语句的写法:

//查询与某一指定字符串一致的记录
//直接写
WhereClause = "RN = Y003";
//使用参数变量传递
string fieldStr = "Y003";
WhereClause = "RN = '" + fieldStr + "'";//注意单引号不要忘
//查询以固定字符串开头的记录
//LXBM = "Y003456789"
//RN = "Y003"
WhereClause = "LXBM like 'Y003%'"
WhereClause = "LXBM like '" + RN+ "'%'";//注意单引号
//不等于
WhereClause = "LXBM != 10011";
WhereClause = "LXBM <> 10011";
//查询多个要素
WhereClause = "NAME IS NOT NULL AND NAME <> '高架'"

image.png

1.2 查询不重复的要素

1.2.1 从GDB获取不重复要素

//使用FeatureClass对象的IDataset接口来获取dataset和workspace的信息
IDataset dataset = (IDataset)currentFeatureLayer.FeatureClass;
//使用IQueryDef接口的对象来定义和查询属性信息。通过IWorkspace接口的CreateQueryDef()方法创建该对象。
IQueryDef queryDef = ((IFeatureWorkspace)dataset.Workspace).CreateQueryDef();
//设置所需查询的表格名称为dataset的名称
queryDef.Tables = dataset.Name;
//设置查询的字段名称。可以联合使用SQL语言的关键字,如查询唯一值可以使用DISTINCT关键字。
queryDef.SubFields = currentFieldName ;
//执行查询并返回ICursor接口的对象来访问整个结果的集合
ICursor cursor = queryDef.Evaluate();
//使用IField接口获取当前所需要使用的字段的信息
IFields fields = currentFeatureLayer.FeatureClass.Fields;
IField field = fields.get_Field(fields.FindField(currentFieldName));
//对整个结果集合进行遍历,从而添加所有的唯一值
//使用IRow接口来操作结果集合。首先定位到第一个查询结果。
IRow row = cursor.NextRow();
//如果查询结果非空,则一直进行添加操作
while (row != null)
{
    //对String类型的字段,唯一值的前后添加'和',以符合SQL语句的要求
    if (field.Type == esriFieldType.esriFieldTypeString)
    {
        listBoxValues.Items.Add("\'" + row.get_Value(0).ToString() + "\'");
    }
    else
    {
        listBoxValues.Items.Add(row.get_Value(0).ToString());
    }
    //继续执行下一个结果的添加
    row = cursor.NextRow();
}

1.2.2 从GDB/SHP获取不重复要素

//获取要素图层的源
IFeatureClass feclass = currentFeatureLayer.FeatureClass;
//根据源数据创建游标
IFeatureCursor cusro = feclass.Search(null, true);
IFeature fea = cusro.NextFeature();
//获取源数据的所有字段
IFields fields = currentFeatureLayer.FeatureClass.Fields;
//获取所选字段的Index
int index = fields.FindField(currentFieldName);
while (fea != null)
{
    string str;
    str = fea.get_Value(index).ToString();
    //如果值列表中还没有str这个值
    if (!listBoxValues.Items.Contains("\'" + str + "\'"))
    {
        //将str加入到值列表,并且str前后加上单引号
        listBoxValues.Items.Add("\'" + str + "\'");
    }
    fea = cusro.NextFeature();
}

2 IMap、ILayer、IFeatureLayer和IFeatureClass关系

刚开时学习 Engine 开发时,对于这几个接口之间的关系总是理不清,因此写下这篇文章做个总结

2.1 是什么

在 engine 开发中,我觉得使用过程中应该将每个接口对应到 ArcMap 中的具体事物中,这才能对它们有深刻的认识,那么,这几个接口代表的事物是什么呢?


IMap

这相对来说比较好理解,Map就是许多图层的集合,就像 ArcMap 中的 MXD文档一样,可以包括许多图层 Layer.

ILayer

Layer 是图层对象,是数据的外壳,必须建立在数据的基础上才有意义。在 ArcMap 中,它可以表示任何图层,例如要素图层( IFeatureLayer ),栅格图层( IRasterLayer ),图形图层集合( ICompositeGraphicsLayer )

IFeatureLayer

继承自ILayer,提供了访问基于矢量数据图层的属性和方法,图层的数据可以是Geodatabase、Shapefile或Coverage数据。如果使用FeatureLayer组件类,还可以通过IGeoFeatureLayer接口获得更多的属性和方法。提供了控制要素图层的属性和方法,例如标记属性( AnnotationProperties )、注记显示设置( DisplayAnnotation )

IFeatureClass

获取和设置要素类属性的主要接口。如获取要素类的类型,得到满足某个查询条件的要素个数,或在要素类中创建一个新的功能。


2.2 关系

其中IMap是由多个ILayer构成的,而IFeatureLayer是ILayer的一个子类,IFeatureClass是IFeatureLayer的一个属性。

2.2.1 从IMap中获取IFeatureLayer

        /// <summary>
        /// 根据图层名找到图层 
        /// </summary>
        /// <param name="pMap">地图名称</param>
        /// <param name="layerName">图层名称</param>
        /// <returns>未找到图层返回null,找到图层返回目标图层</returns>
        public static IFeatureLayer GetLayerByName(IMap pMap, string layerName)
        {
            for(int i = 0; i < pMap.LayerCount; i++)
            {
                if(pMap.getLayer(i).Name == layerName)
                {
                    return pMap.getLayer(i) as IFeatureLayer;
                }
            }
            return null;
        }

2.2.2 从IMap中获取IFeatureClass

注意:使用此函数时,不能再通过接口跳转到IFeatureLayer

        /// <summary>
        /// 根据图层名找到图层 
        /// </summary>
        /// <param name="pMap">地图名称</param>
        /// <param name="layerName">图层名称</param>
        /// <returns>未找到图层返回null,找到图层返回目标图层</returns>
        public static IFeatureClass GetLayer(IMap pMap, string layerName)
        {
            for(int i = 0; i < pMap.LayerCount; i++)
            {
                if(pMap.getLayer(i).Name == layerName)
                {
                    return (pMap.getLayer(i) as IFeatureLayer).FeatureClass;
                }
            }
            return null;
        }

2.3 向图层中添加字段

public void addFieldIntoFeatureClass(IFeatureClass feaClass, string fieldName)
{
    int fieldIndex = feaClass.FinfField(fieldName);
    if(fieldIndex != -1)
    {
        IField pField = new FieldClass();
        IFieldEdit pFieldEdit = (IFieldEdit)pField;
        pFieldEdit.Name_2 = fieldName;
        pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
        pFieldEdit.Length_2 = 100;
        pFieldsEdit.AddField(pField);
    }
}

2.4 获取IMap下某图层所属的数据库名称

IFeatureLayer pFeaLayer = getLayerByName(pMap, "LRDL");
string gdbName = pFeaLayer.FeatureClass.FeatureDataset.Workspace.PathName;

2.5 相关信息获取

获取IMap

相关文章
|
3月前
|
开发框架 .NET API
以C#一分钟浅谈:GraphQL 数据类型与查询
本文从C#开发者的角度介绍了GraphQL的基本概念、核心组件及其实现方法。GraphQL由Facebook开发,允许客户端精确请求所需数据,提高应用性能。文章详细讲解了如何在C#中使用`GraphQL.NET`库创建Schema、配置ASP.NET Core,并讨论了GraphQL的数据类型及常见问题与解决方案。通过本文,C#开发者可以更好地理解并应用GraphQL,构建高效、灵活的API。
138 64
|
2月前
|
存储 安全 编译器
学懂C#编程:属性(Property)的概念定义及使用详解
通过深入理解和使用C#的属性,可以编写更清晰、简洁和高效的代码,为开发高质量的应用程序奠定基础。
117 12
|
2月前
|
开发框架 .NET 测试技术
C# 一分钟浅谈:GraphQL 数据类型与查询
本文介绍了GraphQL的基本概念、数据类型及查询方法,重点从C#角度探讨了GraphQL的应用。通过Hot Chocolate库的实例,展示了如何在ASP.NET Core中实现GraphQL API,包括安装、定义Schema、配置及运行项目。文中还讨论了常见问题与解决方案,旨在帮助开发者更好地理解和使用GraphQL。
58 2
|
4月前
|
SQL 缓存 分布式计算
C#如何处理上亿级数据的查询效率
C#如何处理上亿级数据的查询效率
79 1
|
5月前
|
安全 C# 索引
C#一分钟浅谈:属性与索引器的定义
本文深入浅出地介绍了C#编程中的属性和索引器。属性让字段更安全,通过访问器方法在读写时执行额外操作,如验证数据有效性;索引器则赋予类数组般的访问方式,支持基于索引的数据访问模式。文章通过示例代码展示了如何定义及使用这两种特性,并提供了常见问题及其解决方案,帮助读者写出更健壮、易维护的代码。希望读者能从中学习到如何有效利用属性和索引器增强C#类的功能性。
132 12
|
5月前
|
开发框架 自然语言处理 .NET
C#一分钟浅谈:LINQ 查询表达式的使用技巧
【9月更文挑战第6天】LINQ(Language Integrated Query)是C#开发中的强大工具,使查询数据集合变得简单且接近自然语言。本文从基础入手,通过具体示例讲解LINQ查询表达式的使用技巧,包括过滤、排序和分组等操作。同时,文章还探讨了常见问题及解决方法,如性能优化、过早枚举和类型转换等,帮助开发者写出更高效、易维护的代码。
132 15
|
6月前
|
存储 安全 编译器
C#中的属性
C#中的属性
62 7
|
7月前
|
JSON 数据格式 SQL
SQL开发问题之直接使用join方法在处理字符串类型属性时可能会遇到性能问题如何解决
SQL开发问题之直接使用join方法在处理字符串类型属性时可能会遇到性能问题如何解决
|
7月前
|
分布式计算 MaxCompute 计算机视觉
ODPS问题之odps.sql.mapper.split.size属性有什么作用,以及如何根据场景调整它
ODPS问题之odps.sql.mapper.split.size属性有什么作用,以及如何根据场景调整它
355 1
|
8月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
53 2