基于C#的ArcEngine二次开发48:点是否落在实体上检查

简介: 基于C#的ArcEngine二次开发48:点是否落在实体上检查

在数据检查过程中,我们需要点要素是否落在实体上进行检查处理,本文针对这个需求介绍两种实现思路


背景依托:我们需要检查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();
        }
}
相关文章
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁
基于C#的ArcEngine二次开发56:双击属性表跳转目标要素并闪烁
基于C#的ArcEngine二次开发54:IStatusBar状态栏接口的使用
基于C#的ArcEngine二次开发54:IStatusBar状态栏接口的使用
基于C#的ArcEngine二次开发54:IStatusBar状态栏接口的使用
|
NoSQL 数据处理 C#
基于C#的ArcEngine二次开发52:GDB数据处理过程中与Name相关的操作
基于C#的ArcEngine二次开发52:GDB数据处理过程中与Name相关的操作
基于C#的ArcEngine二次开发52:GDB数据处理过程中与Name相关的操作
基于C#的ArcEngine二次开发51:获取图层字段唯一值列表(Get Unique Values)
基于C#的ArcEngine二次开发51:获取图层字段唯一值列表(Get Unique Values)
基于C#的ArcEngine二次开发51:获取图层字段唯一值列表(Get Unique Values)
|
算法 C#
基于C#的ArcEngine二次开发50:生成面空洞连接线
基于C#的ArcEngine二次开发50:生成面空洞连接线
基于C#的ArcEngine二次开发50:生成面空洞连接线
|
存储 NoSQL Unix
基于C#的ArcEngine二次开发50:MDB创建新要素类及“无当前记录”异常处理
基于C#的ArcEngine二次开发50:MDB创建新要素类及“无当前记录”异常处理
基于C#的ArcEngine二次开发50:MDB创建新要素类及“无当前记录”异常处理
|
NoSQL C#
基于C#的ArcEngine二次开发57:每用户订阅上的所有人SID 不存在
基于C#的ArcEngine二次开发57:每用户订阅上的所有人SID 不存在
|
定位技术 C# 图形学
基于C#的ArcEngine二次开发53: mxd与IPagelayout
基于C#的ArcEngine二次开发53: mxd与IPagelayout
|
NoSQL C# 数据库管理
基于C#的ArcEngine二次开发49:修改图层名称和别名、字段名称
基于C#的ArcEngine二次开发49:修改图层名称和别名、字段名称