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

相关文章
|
11月前
|
SQL 监控 关系型数据库
一键开启百倍加速!RDS DuckDB 黑科技让SQL查询速度最高提升200倍
RDS MySQL DuckDB分析实例结合事务处理与实时分析能力,显著提升SQL查询性能,最高可达200倍,兼容MySQL语法,无需额外学习成本。
|
11月前
|
SQL 存储 关系型数据库
MySQL体系结构详解:一条SQL查询的旅程
本文深入解析MySQL内部架构,从SQL查询的执行流程到性能优化技巧,涵盖连接建立、查询处理、执行阶段及存储引擎工作机制,帮助开发者理解MySQL运行原理并提升数据库性能。
|
SQL 数据挖掘 数据库
第三篇:高级 SQL 查询与多表操作
本文深入讲解高级SQL查询技巧,涵盖多表JOIN操作、聚合函数、分组查询、子查询及视图索引等内容。适合已掌握基础SQL的学习者,通过实例解析INNER/LEFT/RIGHT/FULL JOIN用法,以及COUNT/SUM/AVG等聚合函数的应用。同时探讨复杂WHERE条件、子查询嵌套,并介绍视图简化查询与索引优化性能的方法。最后提供实践建议与学习资源,助你提升SQL技能以应对实际数据处理需求。
999 1
|
SQL 运维 监控
SQL查询太慢?实战讲解YashanDB SQL调优思路
本文是Meetup第十期“调优实战专场”的第二篇技术文章,上一篇《高效查询秘诀,解码YashanDB优化器分组查询优化手段》中,我们揭秘了YashanDB分组查询优化秘诀,本文将通过一个案例,助你快速上手YashanDB慢日志功能,精准定位“慢SQL”后进行优化。
|
10月前
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
381 4
|
11月前
|
SQL 监控 关系型数据库
SQL优化技巧:让MySQL查询快人一步
本文深入解析了MySQL查询优化的核心技巧,涵盖索引设计、查询重写、分页优化、批量操作、数据类型优化及性能监控等方面,帮助开发者显著提升数据库性能,解决慢查询问题,适用于高并发与大数据场景。
|
SQL 索引
【YashanDB知识库】字段加上索引后,SQL查询不到结果
【YashanDB知识库】字段加上索引后,SQL查询不到结果
|
12月前
|
SQL XML Java
通过MyBatis的XML配置实现灵活的动态SQL查询
总结而言,通过MyBatis的XML配置实现灵活的动态SQL查询,可以让开发者以声明式的方式构建SQL语句,既保证了SQL操作的灵活性,又简化了代码的复杂度。这种方式可以显著提高数据库操作的效率和代码的可维护性。
609 18
|
10月前
|
SQL 关系型数据库 MySQL
(SQL)SQL语言中的查询语句整理
查询语句在sql中占了挺大一部分篇幅,因为在数据库中使用查询语句的次数远多于更新与删除命令。而查询语句比起其他语句要更加的复杂,可因为sql是数据库不可或缺的一部分,所以即使不懂,也必须得弄懂,以上。
476 0
|
SQL 关系型数据库 MySQL
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路
凌晨2点报警群炸了:一条sql 执行200秒!搞定之后,我总结了一个慢SQL查询、定位分析解决的完整套路