You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							587 lines
						
					
					
						
							26 KiB
						
					
					
				
			
		
		
	
	
							587 lines
						
					
					
						
							26 KiB
						
					
					
				using ESRI.ArcGIS.Carto; | 
						|
using ESRI.ArcGIS.Geodatabase; | 
						|
using ESRI.ArcGIS.Geometry; | 
						|
using KGIS.Framework.AE; | 
						|
using KGIS.Framework.Maps; | 
						|
using KGIS.Framework.Utils; | 
						|
using KGIS.Framework.Utils.Helper; | 
						|
using Kingo.Plugin.MapView.Model; | 
						|
using Kingo.PluginServiceInterface; | 
						|
using Newtonsoft.Json; | 
						|
using System; | 
						|
using System.Collections.Generic; | 
						|
using System.Linq; | 
						|
 | 
						|
namespace Kingo.Plugin.MapView.Common | 
						|
{ | 
						|
    public class CommonHelper | 
						|
    { | 
						|
        public static string GetGDPDJB_BJ(IFeature feature, ESRI.ArcGIS.Carto.IFeatureLayer layerJC_DLTB, ESRI.ArcGIS.Carto.IFeatureLayer layerJC_PDT) | 
						|
        { | 
						|
            string poduMax = ""; | 
						|
            try | 
						|
            { | 
						|
                /*GDPDJB取值 | 
						|
                *1.变更前后均为耕地,耕地坡度级别继承基础库的耕地坡度级别; | 
						|
                *继承时耕地坡度级别占比最大的;此时的耕地坡度级别属性为可编辑 | 
						|
                *2.变更前为非耕地或部分耕地,变更后为耕地,耕地坡度级别根据坡度图面积占比最优赋值; | 
						|
                * 此时的耕地坡度级别属性不可编辑 | 
						|
                */ | 
						|
                if (layerJC_DLTB == null || layerJC_DLTB.FeatureClass == null) | 
						|
                { | 
						|
                    throw new Exception("[基础库_地类图斑]数据源为空,请确认工作目录设置是否正确!"); | 
						|
                } | 
						|
                int poduindex = layerJC_DLTB.FeatureClass.Fields.FindField("GDPDJB"); | 
						|
                if (poduindex < 0) | 
						|
                { | 
						|
                    throw new Exception("[基础库_地类图斑]无GDPDJB字段,请确认工作目录设置是否正确!"); | 
						|
                } | 
						|
                int dlbmindex = layerJC_DLTB.FeatureClass.Fields.FindField("DLBM"); | 
						|
                if (dlbmindex < 0) | 
						|
                { | 
						|
                    throw new Exception("[基础库_地类图斑]无DLBM字段,请确认工作目录设置是否正确!"); | 
						|
                } | 
						|
                ESRI.ArcGIS.Geometry.IGeometry geometry = feature.ShapeCopy; | 
						|
                IFeatureClass featureClass = (layerJC_DLTB as ESRI.ArcGIS.Carto.IFeatureLayer).FeatureClass; | 
						|
                if (geometry.SpatialReference.FactoryCode != (featureClass as IGeoDataset).SpatialReference.FactoryCode) | 
						|
                { | 
						|
                    geometry.Project((featureClass as IGeoDataset).SpatialReference); | 
						|
                } | 
						|
 | 
						|
                ISpatialFilter spatialFilter = new SpatialFilterClass() | 
						|
                { | 
						|
                    Geometry = geometry, | 
						|
                    SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects | 
						|
                }; | 
						|
                Dictionary<ESRI.ArcGIS.Geometry.IGeometry, IFeature> data = new Dictionary<IGeometry, IFeature>(); | 
						|
                IFeatureCursor cursor = featureClass.Search(spatialFilter, true); | 
						|
                IFeature fea; | 
						|
                while ((fea = cursor.NextFeature()) != null) | 
						|
                { | 
						|
                    data.Add(fea.ShapeCopy, fea); | 
						|
                } | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); | 
						|
 | 
						|
                //Dictionary<ESRI.ArcGIS.Geometry.IGeometry, IFeature> data = Common.CommonHelper.IdentifyReturnIntersect(geometry, layerJC_DLTB); | 
						|
                if (data == null || data.Count <= 0) | 
						|
                { | 
						|
                    throw new Exception("未正确压盖[基础库_地类图斑]图层"); | 
						|
                } | 
						|
                Dictionary<string, double> pdMj = new Dictionary<string, double>(); | 
						|
                //是否全是耕地 | 
						|
                bool isALLGD = true; | 
						|
                foreach (var item in data) | 
						|
                { | 
						|
                    double mj = (item.Key as ESRI.ArcGIS.Geometry.IArea).Area; | 
						|
                    if (mj < 0.01) | 
						|
                    { | 
						|
                        continue; | 
						|
                    } | 
						|
                    //地类编码 | 
						|
                    if (item.Value.get_Value(dlbmindex) == null || !item.Value.get_Value(dlbmindex).ToString().StartsWith("01")) | 
						|
                    { | 
						|
                        isALLGD = false; | 
						|
                        break; | 
						|
                    } | 
						|
                    //耕地坡度级别 | 
						|
                    string pdjb = item.Value.get_Value(poduindex).ToString(); | 
						|
                    if (pdMj.ContainsKey(pdjb)) | 
						|
                    { | 
						|
                        pdMj[pdjb] = pdMj[pdjb] + (item.Key as ESRI.ArcGIS.Geometry.IArea).Area; | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        pdMj.Add(pdjb, (item.Key as ESRI.ArcGIS.Geometry.IArea).Area); | 
						|
                    } | 
						|
                } | 
						|
                if (isALLGD) | 
						|
                { | 
						|
                    if (!System.Diagnostics.Debugger.IsAttached) | 
						|
                    { | 
						|
                        LogAPI.Debug(JsonConvert.SerializeObject(pdMj.OrderByDescending(x => x.Value))); | 
						|
                    } | 
						|
                    //计算取耕地坡度级别占比最大的 | 
						|
                    string caculateValue = pdMj.OrderByDescending(x => x.Value).FirstOrDefault().Key; | 
						|
                    //页面值 | 
						|
                    string featureValue = ""; | 
						|
                    if (feature.Fields.FindField("GDPDJB") > -1) | 
						|
                    { | 
						|
                        featureValue = feature.get_Value(feature.Fields.FindField("GDPDJB")).ToString(); | 
						|
                    } | 
						|
                    //为空赋值计算的值 | 
						|
                    if (string.IsNullOrWhiteSpace(featureValue)) | 
						|
                    { | 
						|
                        poduMax = caculateValue; | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        //原值与计算的值不一致 | 
						|
                        if (!caculateValue.Equals(featureValue)) | 
						|
                        { | 
						|
                            //弹出提示框,让用户确认是否核实 | 
						|
                            if (MessageHelper.ShowYesNoAndTips("变更前后均为耕地,计算占比最大坡度级别为“" + caculateValue + "”,与页面实际填写值“" + featureValue + "”不一致,是否已核实(以页面值为准)?") == System.Windows.Forms.DialogResult.Yes) | 
						|
                            { | 
						|
                                poduMax = featureValue; | 
						|
                            } | 
						|
                            else | 
						|
                            { | 
						|
                                poduMax = caculateValue; | 
						|
                            } | 
						|
                        } | 
						|
                        else | 
						|
                        { | 
						|
                            poduMax = featureValue; | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    poduMax = GetMaxAreaPDJB(feature.ShapeCopy, layerJC_PDT); | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                KGIS.Framework.Utils.LogAPI.Debug("获取坡度级别异常:\r\n"); | 
						|
                KGIS.Framework.Utils.LogAPI.Debug(ex); | 
						|
                throw new Exception("获取坡度级别异常:" + ex.Message); | 
						|
            } | 
						|
            return poduMax; | 
						|
        } | 
						|
        public static Dictionary<IGeometry, IFeature> IdentifyReturnIntersect(IGeometry pGeo, ILayer pLayer) | 
						|
        { | 
						|
            Dictionary<IGeometry, IFeature> result = new Dictionary<IGeometry, IFeature>(); | 
						|
            try | 
						|
            { | 
						|
                if (pGeo == null || pGeo.IsEmpty || pLayer == null) | 
						|
                { | 
						|
                    return result; | 
						|
                } | 
						|
                IIdentify identify = pLayer as IIdentify; | 
						|
                if (identify == null) | 
						|
                    return result; | 
						|
                ESRI.ArcGIS.esriSystem.IArray array = identify.Identify(pGeo); | 
						|
                if (array == null || array.Count < 1) | 
						|
                    return result; | 
						|
                for (int i = 0; i < array.Count; i++) | 
						|
                { | 
						|
                    IRowIdentifyObject row = (IRowIdentifyObject)array.get_Element(i); | 
						|
                    if (row == null) | 
						|
                    { | 
						|
                        continue; | 
						|
                    } | 
						|
                    IFeature f = row.Row as IFeature; | 
						|
                    //此处之所以重新根据OID获取要素,是因为使用(row.Row as IFeature)强制转换过来的要素坐标参考容差不正确,都是默认的千分之一0.001 | 
						|
                    IGeometry geometry = (pLayer as IFeatureLayer).FeatureClass.GetFeature(f.OID).ShapeCopy; | 
						|
                    IGeometry geo = KGIS.Framework.AE.FeatureAPI.InterSect(geometry, pGeo); | 
						|
                    if (geo != null && !geo.IsEmpty) | 
						|
                    { | 
						|
                        result.Add(geo, f); | 
						|
                    } | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
            return result; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 获取当前要素压盖到对应坡度级别面积之和最大的坡度 | 
						|
        /// </summary> | 
						|
        /// <param name="newFeature">要素</param> | 
						|
        /// <param name="layerPodu">坡度图图层</param> | 
						|
        /// <returns>坡度级别</returns> | 
						|
        public static string GetMaxAreaPDJB(IGeometry geometry, IFeatureLayer layerPodu = null) | 
						|
        { | 
						|
            string poduMax = ""; | 
						|
            try | 
						|
            { | 
						|
                if (layerPodu == null || layerPodu.FeatureClass == null) | 
						|
                { | 
						|
                    throw new Exception("未获取到[基础_省级下发坡度图],请检查工作目录坡度图是否设置正确"); | 
						|
                } | 
						|
                if (geometry == null || geometry.IsEmpty) | 
						|
                { | 
						|
                    throw new Exception("图形为空!"); | 
						|
                } | 
						|
                ProjectInfo projectInfo = MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo; | 
						|
                string pdjbFieldName = projectInfo.CODE.StartsWith("11") ? "GDPDJB" : "PDJB"; | 
						|
                int poduindex = layerPodu.FeatureClass.Fields.FindField(pdjbFieldName); | 
						|
                if (poduindex < 0) | 
						|
                { | 
						|
                    throw new Exception($"[基础_省级下发坡度图]图层无{pdjbFieldName}字段!"); | 
						|
                } | 
						|
                if (geometry.SpatialReference.FactoryCode != (layerPodu.FeatureClass as IGeoDataset).SpatialReference.FactoryCode) | 
						|
                { | 
						|
                    geometry.Project((layerPodu.FeatureClass as IGeoDataset).SpatialReference); | 
						|
                } | 
						|
 | 
						|
                ISpatialFilter spatialFilter = new SpatialFilterClass() | 
						|
                { | 
						|
                    Geometry = geometry, | 
						|
                    SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects | 
						|
                }; | 
						|
                Dictionary<ESRI.ArcGIS.Geometry.IGeometry, IFeature> data = new Dictionary<IGeometry, IFeature>(); | 
						|
                IFeatureCursor cursor = layerPodu.FeatureClass.Search(spatialFilter, true); | 
						|
                IFeature fea; | 
						|
                while ((fea = cursor.NextFeature()) != null) | 
						|
                { | 
						|
                    data.Add(fea.ShapeCopy, fea); | 
						|
                } | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); | 
						|
                //Dictionary<ESRI.ArcGIS.Geometry.IGeometry, IFeature> data = IdentifyReturnIntersect(geometry, layerPodu); | 
						|
                if (data == null || data.Count <= 0) | 
						|
                { | 
						|
                    throw new Exception("未正确压盖坡度图图层,请检查工作目录坡度图是否设置正确!"); | 
						|
                } | 
						|
                Dictionary<string, double> pdMj = new Dictionary<string, double>(); | 
						|
                foreach (var item in data) | 
						|
                { | 
						|
                    string pdjb = item.Value.get_Value(poduindex).ToString(); | 
						|
                    if (pdMj.ContainsKey(pdjb)) | 
						|
                    { | 
						|
                        pdMj[pdjb] = pdMj[pdjb] + (item.Key as ESRI.ArcGIS.Geometry.IArea).Area; | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        pdMj.Add(pdjb, (item.Key as ESRI.ArcGIS.Geometry.IArea).Area); | 
						|
                    } | 
						|
                } | 
						|
                if (!System.Diagnostics.Debugger.IsAttached) | 
						|
                { | 
						|
                    LogAPI.Debug(JsonConvert.SerializeObject(pdMj.OrderByDescending(x => x.Value))); | 
						|
                } | 
						|
                poduMax = pdMj.OrderByDescending(x => x.Value).FirstOrDefault().Key; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
            return poduMax; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 北京获取监测类型和管理部门字段值 | 
						|
        /// </summary> | 
						|
        /// <param name="feature"></param> | 
						|
        /// <param name="layerJC_DLTB"></param> | 
						|
        /// <param name="bhjclxList"></param> | 
						|
        /// <param name="dlbm"></param> | 
						|
        /// <param name="ddtcdm"></param> | 
						|
        /// <returns></returns> | 
						|
        public static Dictionary<string, string> GetJCLXAndGLBM(IFeature feature, IFeatureLayer layerJC_DLTB, List<BHJCLX> bhjclxList, string dlbm, string ddtcdm) | 
						|
        { | 
						|
            Dictionary<string, string> keys = new Dictionary<string, string>(); | 
						|
            try | 
						|
            { | 
						|
                if (layerJC_DLTB == null || layerJC_DLTB.FeatureClass == null) | 
						|
                { | 
						|
                    throw new Exception("[基础库_地类图斑]数据源为空,请确认工作目录设置是否正确!"); | 
						|
                } | 
						|
                int jck_dlbmindex = layerJC_DLTB.FeatureClass.Fields.FindField("DLBM"); | 
						|
                if (jck_dlbmindex < 0) | 
						|
                { | 
						|
                    throw new Exception("[基础库_地类图斑]或[单图斑地类图斑更新层]无DLBM字段,请确认工作目录设置是否正确!"); | 
						|
                } | 
						|
                IGeometry geometry = feature.ShapeCopy; | 
						|
                IFeatureClass featureClass = (layerJC_DLTB as ESRI.ArcGIS.Carto.IFeatureLayer).FeatureClass; | 
						|
                if (geometry.SpatialReference.FactoryCode != (featureClass as IGeoDataset).SpatialReference.FactoryCode) | 
						|
                { | 
						|
                    geometry.Project((featureClass as IGeoDataset).SpatialReference); | 
						|
                } | 
						|
                List<IFeature> features = FeatureAPI.Identify(geometry, layerJC_DLTB); | 
						|
                if (features == null || features.Count <= 0) | 
						|
                { | 
						|
                    throw new Exception("未正确压盖[基础库_地类图斑]图层"); | 
						|
                } | 
						|
 | 
						|
                // 存储符合条件的配置项 | 
						|
                List<(BHJCLX Config, double Area)> matchedConfigs = new List<(BHJCLX, double)>(); | 
						|
                foreach (IFeature fea in features) | 
						|
                { | 
						|
                    if (fea.ShapeCopy == null || fea.ShapeCopy.IsEmpty) | 
						|
                    { | 
						|
                        continue; | 
						|
                    } | 
						|
                    double area = (fea.ShapeCopy as IArea).Area; | 
						|
                    if (area <= 50) | 
						|
                    { | 
						|
                        continue; | 
						|
                    } | 
						|
                    string dltbdlbm = fea.get_Value(jck_dlbmindex).ToString(); | 
						|
                    // 遍历所有配置项,检查是否符合条件 | 
						|
                    foreach (BHJCLX config in bhjclxList) | 
						|
                    { | 
						|
                        // 1. 检查NewDLBM是否符合条件 | 
						|
                        bool newDLBMMatched = CheckDLBMCondition(dlbm, config.NewDLBM); | 
						|
                        if (!newDLBMMatched) | 
						|
                        { | 
						|
                            continue; | 
						|
                        } | 
						|
                        // 2. 检查OldDLBM是否符合条件 | 
						|
                        bool oldDLBMMatched = CheckDLBMCondition(dltbdlbm, config.OldDLBM); | 
						|
                        if (!oldDLBMMatched) | 
						|
                        { | 
						|
                            continue; | 
						|
                        } | 
						|
                        // 3. 如果CheckDDTC=true,则需检查DDTCDM是否匹配 | 
						|
                        if (config.CheckDDTC) | 
						|
                        { | 
						|
                            if (string.IsNullOrEmpty(config.DDTCDM)) // 配置未提供DDTCDM,跳过 | 
						|
                            { | 
						|
                                continue; | 
						|
                            } | 
						|
                            if (ddtcdm != config.DDTCDM) // DDTCDM不匹配,跳过 | 
						|
                            { | 
						|
                                continue; | 
						|
                            } | 
						|
                        } | 
						|
                        // 所有条件均满足,记录匹配的配置和面积 | 
						|
                        matchedConfigs.Add((config, area)); | 
						|
                    } | 
						|
                } | 
						|
                // 如果没有匹配项,返回空字典 | 
						|
                if (matchedConfigs.Count == 0) | 
						|
                { | 
						|
                    return keys; | 
						|
                } | 
						|
                // 按优先级(Priority)升序排序,再按面积降序排序 | 
						|
                var sortedConfigs = matchedConfigs | 
						|
                    .OrderBy(x => x.Config.Priority) | 
						|
                    .ThenByDescending(x => x.Area) | 
						|
                    .ToList(); | 
						|
                var mergedConfigs = sortedConfigs | 
						|
                .GroupBy(x => x.Config.JCLX) | 
						|
                .Select(g => new | 
						|
                { | 
						|
                    Config = g.First().Config, | 
						|
                    TotalArea = g.Sum(x => x.Area) | 
						|
                }) | 
						|
                .OrderBy(x => x.Config.Priority) | 
						|
                .ThenByDescending(x => x.TotalArea) | 
						|
                .ToList(); | 
						|
                LogAPI.Debug(Newtonsoft.Json.JsonConvert.SerializeObject(mergedConfigs)); | 
						|
 | 
						|
                // 取优先级最高且面积最大的配置 | 
						|
                BHJCLX bestConfig = mergedConfigs[0].Config; | 
						|
                keys.Add(bestConfig.JCLX, bestConfig.GLBM); | 
						|
                return keys; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                LogAPI.Debug("北京获取监测类型和管理部门失败:\r\n"); | 
						|
                LogAPI.Debug(ex); | 
						|
                throw new Exception("获取监测类型和管理部门异常:" + ex.Message); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 获取空间相交要素的属性值(按面积加权) | 
						|
        /// </summary> | 
						|
        /// <param name="feature">查询要素</param> | 
						|
        /// <param name="targetLayer">目标图层</param> | 
						|
        /// <param name="fieldName">要获取的属性字段名</param> | 
						|
        /// <param name="minArea">最小有效面积(默认0.01)</param> | 
						|
        /// <returns>面积最大的属性值</returns> | 
						|
        public static string GetSpatialAttribute(IFeature feature, IFeatureLayer targetLayer, string fieldName, double minArea = 0.01) | 
						|
        { | 
						|
            if (targetLayer?.FeatureClass == null) | 
						|
            { | 
						|
                throw new ArgumentNullException(nameof(targetLayer), $"[{targetLayer?.Name}]数据源为空,请确认工作目录设置是否正确!"); | 
						|
            } | 
						|
 | 
						|
            int fieldIndex = targetLayer.FeatureClass.Fields.FindField(fieldName); | 
						|
            if (fieldIndex < 0) | 
						|
            { | 
						|
                throw new ArgumentException($"[{targetLayer.Name}]无{fieldName}字段,请确认工作目录设置是否正确!"); | 
						|
            } | 
						|
 | 
						|
            try | 
						|
            { | 
						|
                // 1. 准备查询几何 | 
						|
                IGeometry geometry = feature.ShapeCopy; | 
						|
                IFeatureClass featureClass = targetLayer.FeatureClass; | 
						|
 | 
						|
                // 2. 坐标系统一 | 
						|
                if (geometry.SpatialReference.FactoryCode != ((IGeoDataset)featureClass).SpatialReference.FactoryCode) | 
						|
                { | 
						|
                    geometry.Project(((IGeoDataset)featureClass).SpatialReference); | 
						|
                } | 
						|
 | 
						|
                // 3. 执行空间查询 | 
						|
                //var intersectedFeatures = QueryIntersectedFeatures(geometry, featureClass); | 
						|
                //Dictionary<IGeometry, IFeature> intersectedFeatures = new Dictionary<IGeometry, IFeature>(); | 
						|
                //ISpatialFilter spatialFilter = new SpatialFilterClass | 
						|
                //{ | 
						|
                //    Geometry = geometry, | 
						|
                //    SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects | 
						|
                //}; | 
						|
                //IFeatureCursor cursor = featureClass.Search(spatialFilter, true); | 
						|
                //IFeature fea; | 
						|
                //while ((fea = cursor.NextFeature()) != null) | 
						|
                //{ | 
						|
                //    intersectedFeatures.Add(fea.ShapeCopy, fea); | 
						|
                //} | 
						|
                //if (cursor != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); | 
						|
                //System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); | 
						|
                //if (intersectedFeatures.Count == 0) | 
						|
                //{ | 
						|
                //    throw new InvalidOperationException($"未正确压盖[{targetLayer.Name}]图层"); | 
						|
                //} | 
						|
 | 
						|
                // 4. 按属性分组并计算面积 | 
						|
                Dictionary<string, double> attributeAreas = CalculateAttributeAreas(featureClass, feature, fieldIndex, targetLayer.Name, minArea); | 
						|
 | 
						|
                // 5. 返回面积最大的属性值 | 
						|
                return attributeAreas.OrderByDescending(x => x.Value).FirstOrDefault().Key; | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                LogAPI.Debug($"获取{fieldName}属性失败:\r\n"); | 
						|
                LogAPI.Debug(ex); | 
						|
                throw new Exception($"获取{fieldName}属性异常:" + ex.Message, ex); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 查询相交要素 | 
						|
        /// </summary> | 
						|
        private static Dictionary<IGeometry, IFeature> QueryIntersectedFeatures(IGeometry geometry, IFeatureClass featureClass) | 
						|
        { | 
						|
            var result = new Dictionary<IGeometry, IFeature>(); | 
						|
 | 
						|
            ISpatialFilter spatialFilter = new SpatialFilterClass | 
						|
            { | 
						|
                Geometry = geometry, | 
						|
                SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects | 
						|
            }; | 
						|
 | 
						|
            IFeatureCursor cursor = null; | 
						|
            try | 
						|
            { | 
						|
                cursor = featureClass.Search(spatialFilter, true); | 
						|
                IFeature feature; | 
						|
                while ((feature = cursor.NextFeature()) != null) | 
						|
                { | 
						|
                    result.Add(feature.ShapeCopy, feature); | 
						|
                } | 
						|
            } | 
						|
            finally | 
						|
            { | 
						|
                if (cursor != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); | 
						|
                System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); | 
						|
            } | 
						|
 | 
						|
            return result; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 计算属性面积字典 | 
						|
        /// </summary> | 
						|
        private static Dictionary<string, double> CalculateAttributeAreas(IFeatureClass featureClass, IFeature sourceFeature, int fieldIndex, string layerName, double minArea) | 
						|
        { | 
						|
            Dictionary<IGeometry, string> intersectedFeatures = new Dictionary<IGeometry, string>(); | 
						|
            ISpatialFilter spatialFilter = new SpatialFilterClass | 
						|
            { | 
						|
                Geometry = sourceFeature.ShapeCopy, | 
						|
                SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects | 
						|
            }; | 
						|
            IFeatureCursor cursor = featureClass.Search(spatialFilter, true); | 
						|
            IFeature fea; | 
						|
            while ((fea = cursor.NextFeature()) != null) | 
						|
            { | 
						|
                intersectedFeatures.Add(fea.ShapeCopy, fea.get_Value(fieldIndex)?.ToString() ?? string.Empty); | 
						|
            } | 
						|
            if (cursor != null) System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); | 
						|
            System.Runtime.InteropServices.Marshal.ReleaseComObject(spatialFilter); | 
						|
            if (intersectedFeatures.Count == 0) | 
						|
            { | 
						|
                throw new InvalidOperationException($"未正确压盖[{layerName}]图层"); | 
						|
            } | 
						|
            Dictionary<string, double> result = new Dictionary<string, double>(); | 
						|
 | 
						|
            foreach (var item in intersectedFeatures) | 
						|
            { | 
						|
                double area = FeatureAPI.GetInterArea(item.Key, sourceFeature.ShapeCopy); | 
						|
                //double area = ((IArea)item.Key).Area; | 
						|
                if (area < minArea) continue; | 
						|
 | 
						|
                string attributeValue = item.Value; | 
						|
 | 
						|
                if (result.ContainsKey(attributeValue)) | 
						|
                { | 
						|
                    result[attributeValue] += area; | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    result[attributeValue] = area; | 
						|
                } | 
						|
            } | 
						|
 | 
						|
            return result; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 检查DLBM是否符合配置条件(支持复合条件:StartsWith、in、not in) | 
						|
        /// </summary> | 
						|
        private static bool CheckDLBMCondition(string dlbm, string condition) | 
						|
        { | 
						|
            if (string.IsNullOrEmpty(condition)) | 
						|
            { | 
						|
                return false; | 
						|
            } | 
						|
 | 
						|
            // 1. 分割条件(按 "、" 拆分) | 
						|
            string[] subConditions = condition.Split('、'); | 
						|
 | 
						|
            // 2. 解析条件类型 | 
						|
            bool startsWithOrInMatched = false; // 记录 StartsWith 或 in 是否匹配 | 
						|
            bool notInMatched = true;          // 记录 not in 是否匹配(默认true,若无 not in 则不影响) | 
						|
 | 
						|
            foreach (string subCondition in subConditions) | 
						|
            { | 
						|
                // 2.1 处理StartsWith条件(如 "StartsWith(03|04|11|12)") | 
						|
                if (subCondition.StartsWith("StartsWith(") && subCondition.EndsWith(")")) | 
						|
                { | 
						|
                    string prefix = subCondition.Substring("StartsWith(".Length, subCondition.Length - "StartsWith(".Length - 1); | 
						|
                    string[] prefixes = prefix.Split('|'); | 
						|
                    if (prefixes.Any(p => dlbm.StartsWith(p))) | 
						|
                    { | 
						|
                        startsWithOrInMatched = true; | 
						|
                    } | 
						|
                } | 
						|
                // 2.2 处理in条件(如 "in(1006)") | 
						|
                else if (subCondition.StartsWith("in(") && subCondition.EndsWith(")")) | 
						|
                { | 
						|
                    string valuesStr = subCondition.Substring("in(".Length, subCondition.Length - "in(".Length - 1); | 
						|
                    string[] values = valuesStr.Split('|'); | 
						|
                    if (values.Contains(dlbm)) | 
						|
                    { | 
						|
                        startsWithOrInMatched = true; | 
						|
                    } | 
						|
                } | 
						|
                // 2.3 处理not in条件(如 "not in(1109|1201)") | 
						|
                else if (subCondition.StartsWith("not in(") && subCondition.EndsWith(")")) | 
						|
                { | 
						|
                    string valuesStr = subCondition.Substring("not in(".Length, subCondition.Length - "not in(".Length - 1); | 
						|
                    string[] values = valuesStr.Split('|'); | 
						|
                    if (values.Contains(dlbm)) | 
						|
                    { | 
						|
                        notInMatched = false; // 如果DLBM在not in列表里,直接不匹配 | 
						|
                    } | 
						|
                } | 
						|
                // 2.4 默认情况(直接相等) | 
						|
                else if (dlbm == subCondition) | 
						|
                { | 
						|
                    startsWithOrInMatched = true; | 
						|
                } | 
						|
            } | 
						|
 | 
						|
            // 最终结果 = (StartsWith 或 in 匹配) 且 (not in 匹配) | 
						|
            return startsWithOrInMatched && notInMatched; | 
						|
        } | 
						|
    } | 
						|
}
 | 
						|
 |