在数据检查过程中,我们需要点要素是否落在实体上进行检查处理,本文针对这个需求介绍两种实现思路
背景依托:我们需要检查AGNP层的AK和BB点与RESA/RESP/RESL是否实体对应关系
思路:首先将需要进行实体要素检查的要素聚合呈multipart要素,然后与AGNP层进行逻辑运算,最终选出不再实体上的AK或BB
1 基于选择集的要素实体检查
该思路为先基于AGNP层所有要素点建立选择集,然后用multipart要素与该选择集求交运算,减去相交的部分,再从最终结果中筛选出CLASS为AK/BB的要素。
1.1 基于AGNP层建立选择集
如果在AO开发,需现将IFeatureClass转化为IFeatureLayer进行运算:
IFeatureLayer pFeatureLayer = new FeatureLayerClass(); pFeatureLayer.FeatureClass = agnpFeatureClass; IFeatureSelection pSelection = pFeatureLayer as IFeatureSelection;
如果在Addins下,直接读取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; }
更多信息参见:基于C#的ArcEngine二次开发32:属性sql查询语句与IMap,ILayer,IFeatureLayer,IFeatureClass关系
1.2 基于要素类创建multipart要素
/// <summary> /// 获取空间参考 /// </summary> /// <returns></returns> private ISpatialReference GetSpatialReference(IFeatureClass in_FeatureClass) { IGeoDataset pGeoDataset = in_FeatureClass as IGeoDataset; ISpatialReference pSpatialReference = pGeoDataset.SpatialReference; return pSpatialReference; } /// <summary> /// 合并几何体 /// </summary> /// <returns></returns> private IGeometry GetMergeGeometry(IFeatureClass in_FeatureClass) { IGeometryBag pGeometryBag = new GeometryBag() as IGeometryBag; pGeometryBag.SpatialReference = GetSpatialReference(in_FeatureClass); IGeometryCollection pGeometryCollection = pGeometryBag as IGeometryCollection; // 属性过滤 IQueryFilter pQueryFilter = new QueryFilter(); pQueryFilter.WhereClause = "GB = 310200 or GB = 310500"; // 要素游标 IFeatureCursor pFeatureCursor = in_FeatureClass.Search(pQueryFilter, true); IFeature pFeature = pFeatureCursor.NextFeature(); if (pFeature == null) { return null; } // 遍历游标 object missing = Type.Missing; while (pFeature != null) { pGeometryCollection.AddGeometry(pFeature.ShapeCopy, ref missing, ref missing); pFeature = pFeatureCursor.NextFeature(); } Marshal.ReleaseComObject(pFeatureCursor); // 合并要素 ITopologicalOperator pTopologicalOperator = null; if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPoint) { pTopologicalOperator = new Multipoint() as ITopologicalOperator; pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry); } else if (in_FeatureClass.ShapeType == esriGeometryType.esriGeometryPolyline) { pTopologicalOperator = new Polyline() as ITopologicalOperator; pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry); } else { pTopologicalOperator = new Polygon() as ITopologicalOperator; pTopologicalOperator.ConstructUnion(pGeometryCollection as IEnumGeometry); } return pTopologicalOperator as IGeometry; }
关于multipart更多信息,参见:
基于C#的ArcEngine二次开发23:复合要素的识别与导出
基于C#的ArcEngine二次开发34:使用ConstructUnion方法进行多要素合并
基于C#的ArcEngine二次开发46:编辑内容回撤与炸开multipart feature
1.3 选择集建立与剔除
public ISelectionSet selectSubtract(IFeatureClass agnpFeatureClass, string[] pFeatureClassNames) { IFeatureLayer pFeatureLayer = new FeatureLayerClass(); pFeatureLayer.FeatureClass = agnpFeatureClass; IFeatureSelection pSelection = pFeatureLayer as IFeatureSelection; pSelection.SelectFeatures(null, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResultNew, false); //设置查询条件,如果表达式错误会报异常信息 ISpatialFilter queryFilter = new QueryFilterClass(); //读取RESA/RESL/RESP层 for(int i = 0; i < pFeatureClassNames.Length; i++) { IFeatureClass pFeatureClass = (srcWorkspace as IFeatureWorkspace).OpenFeatureClass(pFeatureClassNames[i]); IGeometry pGeometry = GetMergeGeometry(pFeatureClass); //设置空间查询条件 queryFilter.Geometry = pGeometry; queryFilter.GeometryField = "SHAPE"; queryFilter.SpatialRel= esriSpatialRelEnum.esriSpatialRelIntersects; //选择集过滤 pSelection.SelectFeatures(queryFilter, ESRI.ArcGIS.Carto.esriSelectionResultEnum.esriSelectionResaultSubtract, false); } ISelectionSet pSelectionSet = pSelection.SelectionSet; //导出代码 }
2 基于空间相离原理的实体检查
2.1 空间相离判断
//判断AGNP层要素与构造的复合要素是否相离 private bool spatialdDisjiont(IFeature pFeature, IGeometry multipartGeometry) { IReleationalOperation pRelOpr = pFeature.ShapeCopy; return pRelOpr.Disjoint(multipartGeometry); }
2.2 逐图层判断
private void check(IWorkspace srcWorkspace, IGeometry multipartA, IGeometry multipartS, IGeometry multipartP) { IFeatureWorkspace pFeatureWorkspace = srcWorkspace as IFeatureWorkspace; IFeatureClass pRefFeatureClass = pFeatureWorkspace .OpenFeatureClass(refFeatureClassName); IFeatureCursor pCursor = pRefFeatureClass.Search(null, false); IFeature pFeature = pCursor.NextFeature(); while(pFeature != null) { if(spatialRel(pFeature, multipartA) && spatialRel(pFeature, multipartL) && spatialRel(pFeature, multipartP)) { exportSingleAKorBB(pFeature); } pFeature = pCursor.NextFeature(); } }
3 导出选择集
3.1 创建导出要素类
private void CreateFeatureClass(string strShapeFolder, string refFeatureClassName,string ouFeatureClassName) { IWorkspaceFactory pWSF = new FileGDBWorkspaceFactoryClass(); IWorkspace srcWorkspace = pWSF.OpenFromFile(strShapeFolder,0); IFeatureWorkspace pFeatureWorkspace = srcWorkspace as IFeatureWorkspace; IFeatureClass pRefFeatureClass = pFeatureWorkspace .OpenFeatureClass(refFeatureClassName); IGeoDataset refGeodataset = pRefFeatureClass as IGeoDataset; IFields pFields = refGeodataset.Fields; IFeatureDataset pWorkDataset = pFeatureWorkspace.OpenFeatureDataset("MainDataFrame"); IWorkspace2 pWorkspace2 = pWorkDataset.Workspace as IWorkspace2; if(pWorkspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, ouFeatureClassName)) { IFeatureClass pDelFeatureClass = pFeatureWorkspace .OpenFeatureClass(ouFeatureClassName); IDataset pDS = pDelFeatureClass as IDataset; pDS.Delete(); } pWorkDataset.CreateFeatureClass(ouFeatureClassName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", ""); }
3.2 根据选择集导出要素
exportSelectionSetAKorBB(IFeatureClass ouFeatureClass, ISelectionSet pSelectinset, string type) { ICursor pCursor; pSelectinset.Search(null, false, out pCursor); IFeatureCursor pFeatureCursor = pCursor as IFeatureCursor; IFeature pFeature = pFeatureCursor.NextFeature; while(pFeature != null) { if(pFeature.get_Value(pFeature.Fields.FindField("STACOD")).ToString() != "删除" && pFeature.get_Value(pFeature.Fields.FindField("CLASS")).ToString() != type) { IFeature ouFeature = ouFeatureClass.CreateFeture(); for(int ii = 0; ii < ouFeatureClass.Fields.FieldCount; ii++) { string fiedldName = pFeature.Fields.get_Field(ii).Name; switch(ouFeature.Fields.get_Field(ii).Name) { case "OBJECTID": break; case "CREATED_USER": break; case "CREATED_DATE": break; case "CREATED_EDITED_USER": break; case "CREATED_EDITED_DATE": break; default : ouFeature.set_Value(ii, pFeature.get_Value(ii)); break; } } ouFeature.Shape = pFeature.ShapeCopy; ouFeature.Store(); } pFeature = pFeatureCursor.NextFeature; } }
3.3 导出单个要素
exportSingleAKorBB(IFeatureClass ouFeatureClass, IFeature pFeature, string type) { if(pFeature.get_Value(pFeature.Fields.FindField("STACOD")).ToString() != "删除" && pFeature.get_Value(pFeature.Fields.FindField("CLASS")).ToString() != type) { IFeature ouFeature = ouFeatureClass.CreateFeture(); for(int ii = 0; ii < ouFeatureClass.Fields.FieldCount; ii++) { string fiedldName = pFeature.Fields.get_Field(ii).Name; switch(ouFeature.Fields.get_Field(ii).Name) { case "OBJECTID": break; case "CREATED_USER": break; case "CREATED_DATE": break; case "CREATED_EDITED_USER": break; case "CREATED_EDITED_DATE": break; default : ouFeature.set_Value(ii, pFeature.get_Value(ii)); break; } } ouFeature.Shape = pFeature.ShapeCopy; ouFeature.Store(); } }