1 ArcGIS中定义查询和属性查询
1.1 SQL语句
以SQL模糊查询LIKE运算符对应的通配符为例
通配符查询
从图层中选择要素的代码:
///<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 <> '高架'"
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