基于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

相关文章
|
13天前
|
SQL 存储 人工智能
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
Vanna 是一个开源的 Python RAG(Retrieval-Augmented Generation)框架,能够基于大型语言模型(LLMs)为数据库生成精确的 SQL 查询。Vanna 支持多种 LLMs、向量数据库和 SQL 数据库,提供高准确性查询,同时确保数据库内容安全私密,不外泄。
78 7
Vanna:开源 AI 检索生成框架,自动生成精确的 SQL 查询
|
20天前
|
SQL Java
使用java在未知表字段情况下通过sql查询信息
使用java在未知表字段情况下通过sql查询信息
34 8
|
27天前
|
SQL 安全 PHP
PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全
本文深入探讨了PHP开发中防止SQL注入的方法,包括使用参数化查询、对用户输入进行过滤和验证、使用安全的框架和库等,旨在帮助开发者有效应对SQL注入这一常见安全威胁,保障应用安全。
47 4
|
29天前
|
SQL 监控 关系型数据库
SQL语句当前及历史信息查询-performance schema的使用
本文介绍了如何使用MySQL的Performance Schema来获取SQL语句的当前和历史执行信息。Performance Schema默认在MySQL 8.0中启用,可以通过查询相关表来获取详细的SQL执行信息,包括当前执行的SQL、历史执行记录和统计汇总信息,从而快速定位和解决性能瓶颈。
|
1月前
|
SQL 存储 缓存
如何优化SQL查询性能?
【10月更文挑战第28天】如何优化SQL查询性能?
107 10
|
1月前
|
SQL 关系型数据库 MySQL
|
2月前
|
SQL 数据库 开发者
功能发布-自定义SQL查询
本期主要为大家介绍ClkLog九月上线的新功能-自定义SQL查询。
|
2月前
|
SQL 移动开发 Oracle
SQL语句实现查询连续六天数据的方法与技巧
在数据库查询中,有时需要筛选出符合特定时间连续性条件的数据记录
|
2月前
|
SQL Java 数据库连接
如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
【10月更文挑战第6天】在代码与逻辑交织的世界中,我从一名数据库新手出发,通过不断探索与实践,最终成为熟练掌握JDBC的开发者。这段旅程充满挑战与惊喜,从建立数据库连接到执行SQL语句,再到理解事务管理和批处理等高级功能,每一步都让我对JDBC有了更深的认识。示例代码展示了如何使用`DriverManager.getConnection()`连接数据库,并利用`PreparedStatement`执行参数化查询,有效防止SQL注入。
114 5
|
2月前
|
SQL 数据挖掘 数据库
SQL查询每秒的数据:技巧、方法与性能优化
id="">SQL查询功能详解 SQL(Structured Query Language,结构化查询语言)是一种专门用于与数据库进行沟通和操作的语言