using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Controls; using ESRI.ArcGIS.DataSourcesGDB; using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.AE; using KGIS.Framework.AE.Enum; using KGIS.Framework.AE.GPHelper; using KGIS.Framework.Commands; using KGIS.Framework.DBOperator; using KGIS.Framework.Maps; using KGIS.Framework.Platform.Helper; using KGIS.Framework.Utils; using KGIS.Framework.Utils.ExtensionMethod; using KGIS.Framework.Utils.Helper; using Kingo.Plugin.AttributeMaintain.View; using Kingo.PluginServiceInterface; using KUI.Windows; using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Runtime.InteropServices; namespace Kingo.Plugin.AttributeMaintain.Commands { /// /// 临时用地关联标识码 /// public class CmdLSYDGLBSM : BaseMenuCommand { private IHookHelper hookHelper = null; private EngineEditorClass pEditor = null; public FrmLSYDGLBSMParameter frmLSYDGLBSMParameter = null; public double AreaRatio { get; set; } public override void OnCreate(object hook) { if (hookHelper == null) { hookHelper = new HookHelperClass(); } hookHelper.Hook = hook; } private void FrmLSYDGLBSMParameter_Closed(object sender, EventArgs e) { if (frmLSYDGLBSMParameter != null) { AreaRatio = frmLSYDGLBSMParameter.AreaRatio; frmLSYDGLBSMParameter = null; } } public override void OnClick() { if (frmLSYDGLBSMParameter == null) { frmLSYDGLBSMParameter = new FrmLSYDGLBSMParameter(); frmLSYDGLBSMParameter.Closed += FrmLSYDGLBSMParameter_Closed; } if (frmLSYDGLBSMParameter.ShowInMainWindow(true) == true) { RelationTBBSM(); } } private void RelationTBBSM() { IWorkspaceAPI workspace = null; IWorkspaceAPI Tempworkspace = null; IFeatureClassAPI dltbFeatureClassAPI = null;//地类图斑 IFeatureClassAPI LSYDFeatureclassAPI = null;//临时用地 IWorkspaceFactory outputWorkspaceFactory = null; IFeatureLayer tempFeatureLayer = null; IFeatureCursor pInsertCursor = null; IFeatureCursor pFeatureCursor = null; IWorkspaceFactory pFtWsFct = null; string TempfilePath = string.Empty; try { if (pEditor == null) { pEditor = new EngineEditorClass(); } if (pEditor.EditState != esriEngineEditState.esriEngineStateNotEditing) { MessageHelper.ShowTips("请先关闭编辑!"); return; } ProjectInfo ProInfo = MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo; string SchemeDBPath = ProInfo.ZLDatabase; string gdbFolder = Directory.GetCurrentDirectory() + "\\Temp\\LSYDGLBSMFile"; if (!System.IO.Directory.Exists(gdbFolder)) { Directory.CreateDirectory(gdbFolder); } PluginServiceInterface.CommonHelper.DelectDir(gdbFolder);//能删除就删除 删除报错不处理 this.ShowLoading("正在提取临时用地数据......", 0, 0); string gdbFileName = Guid.NewGuid().ToString(); string path = System.IO.Path.Combine(gdbFolder, gdbFileName); pFtWsFct = new FileGDBWorkspaceFactory(); pFtWsFct.Create(path, "TempGDB", null, 0); TempfilePath = System.IO.Path.Combine(path, "TempGDB.gdb");//临时数据存放路径 outputWorkspaceFactory = new FileGDBWorkspaceFactoryClass(); workspace = new WorkspaceAPI(outputWorkspaceFactory.OpenFromFile(SchemeDBPath, 0)); //TempfilePath = CreateTempPath();//临时数据存放路径 LSYDFeatureclassAPI = workspace.OpenFeatureClass("LSYDGX"); if (LSYDFeatureclassAPI == null || LSYDFeatureclassAPI.FeatureClass == null || LSYDFeatureclassAPI.FeatureClass.FeatureCount(null) <= 0) { MessageHelper.ShowTips("未找到临时用地更新层或临时用地更新层无数据!"); return; } DLTB_Screen("JC_DLTB", "DLTBGX", "DLTBGXGC", TempfilePath, SchemeDBPath); IWorkspaceFactory TempWorkspaceFactory = new FileGDBWorkspaceFactoryClass(); Tempworkspace = new WorkspaceAPI(TempWorkspaceFactory.OpenFromFile(TempfilePath, 0)); dltbFeatureClassAPI = Tempworkspace.OpenFeatureClass("LSYD"); if (dltbFeatureClassAPI == null || dltbFeatureClassAPI.FeatureClass == null || dltbFeatureClassAPI.FeatureClass.FeatureCount(null) <= 0) { MessageHelper.ShowTips("未找到地类图斑更新层或地类图斑更新层无数据!"); return; } ClearDataFields(LSYDFeatureclassAPI.FeatureClass); var gPParamClassNew = new GPParamClass() { FirstFeatureLayer = new FeatureLayer() { FeatureClass = LSYDFeatureclassAPI.FeatureClass }, SecondFeatureLayer = new FeatureLayer() { FeatureClass = dltbFeatureClassAPI.FeatureClass }, OutFeatureClassPath = $"{TempfilePath}\\Temp_LSYD_Result", IsGetOutPutFeature = true, }; this.UpdateMsg("正在提取数据..."); GeoprocessorHelper.IntersectAnalysis2(gPParamClassNew, ref tempFeatureLayer);//相交分析 string dbPath = Path.GetDirectoryName((MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo).GetProjFilePath()) + @"\BGTJ.sqlite"; IWorkspaceFactory pOutWorkFactory = new SqlWorkspaceFactoryClass(); IWorkspace pOutWork = pOutWorkFactory.OpenFromFile(dbPath, 0); IFeatureWorkspace pWork = (tempFeatureLayer.FeatureClass as FeatureClass).Workspace as IFeatureWorkspace; //使用相交分析的结果 IRDBHelper rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbPath, DatabaseType.SQLite); #region 判断表是否存在 object exist = rdbHelper.ExecuteScalar("select count(*) from sqlite_master where type='table' and name = 'Temp_LSYD_Result'"); if (exist.ToString() == "1") { rdbHelper.ExecuteScalar(" drop table Temp_LSYD_Result "); } #endregion TableToTable(pWork, pOutWork, "Temp_LSYD_Result"); IFeature pFeature = null; IFeatureCursor pFeatureCursorResult = tempFeatureLayer.FeatureClass.Search(null, false); IDictionary result_ObiectId_GLBSM = new Dictionary(); int Index_FIDResult = tempFeatureLayer.FeatureClass.FindField("FID_LSYDGX"); int Index_BSMResult = tempFeatureLayer.FeatureClass.FindField("BSM_1"); int Index_AreaResult = tempFeatureLayer.FeatureClass.FindField("SHAPE_AREA"); string FIDResult = ""; string BSMResult = ""; string AreaResult = ""; while ((pFeature = pFeatureCursorResult.NextFeature()) != null) { FIDResult = pFeature.get_Value(Index_FIDResult).ToString(); BSMResult = pFeature.get_Value(Index_BSMResult).ToString(); AreaResult = pFeature.get_Value(Index_AreaResult).ToString(); if (string.IsNullOrEmpty(AreaResult)) continue; bool changed = double.TryParse(AreaResult, out double shapeAreaRelute); if (changed && shapeAreaRelute > AreaRatio) { if (!result_ObiectId_GLBSM.Keys.Contains(FIDResult)) { result_ObiectId_GLBSM.Add(FIDResult, BSMResult); } else { if (!result_ObiectId_GLBSM[FIDResult].Contains(BSMResult) && !string.IsNullOrWhiteSpace(BSMResult)) { result_ObiectId_GLBSM[FIDResult] = string.Format(@"{0},{1}", result_ObiectId_GLBSM[FIDResult], BSMResult); } } } } int count = LSYDFeatureclassAPI.FeatureClass.FeatureCount(null); pFeatureCursor = LSYDFeatureclassAPI.FeatureClass.Search(null, false); //int Index_BSM = LSYDFeatureclassAPI.FeatureClass.FindField("BSM");//标识码 int Index_ID = LSYDFeatureclassAPI.FeatureClass.FindField("OBJECTID"); int Index_GLTBBSM = LSYDFeatureclassAPI.FeatureClass.FindField("GLTBBSM");//关联图斑标识码 int num = 0; //string BSM = ""; string FID_LSYDGX = ""; while ((pFeature = pFeatureCursor.NextFeature()) != null) { //BSM = pFeature.get_Value(Index_BSM).ToString(); FID_LSYDGX = pFeature.get_Value(Index_ID).ToString(); if (result_ObiectId_GLBSM.Keys.Contains(FID_LSYDGX)) { pFeature.set_Value(Index_GLTBBSM, result_ObiectId_GLBSM[FID_LSYDGX]); pFeature.Store(); } num++; this.UpdateMsg($"正在关联临时用地标识码...{num / count}"); } pFeatureCursor.Flush(); this.CloseLoading(); MessageHelper.ShowTips("临时用地标识码关联成功!"); } catch (Exception ex) { this.CloseLoading(); LogAPI.Debug("临时用地标识码关联异常:" + ex.Message); MessageHelper.ShowError("临时用地标识码关联异常:" + ex.Message); } finally { this.CloseLoading(); if (dltbFeatureClassAPI != null) { dltbFeatureClassAPI.CloseFeatureClass(); } if (LSYDFeatureclassAPI != null) { LSYDFeatureclassAPI.CloseFeatureClass(); } if (workspace != null) { workspace.CloseWorkspace(); } if (pFeatureCursor != null) { Marshal.ReleaseComObject(pFeatureCursor); } if (pInsertCursor != null) { Marshal.ReleaseComObject(pInsertCursor); } if (Tempworkspace != null) { Tempworkspace.CloseWorkspace(); } if (pFtWsFct != null) { Marshal.ReleaseComObject(pFtWsFct); } } } private void ClearDataFields(IFeatureClass featureClass) { try { IFeatureCursor upjz_cursor = featureClass.Update(null, false); IFeature jzfeature = null; int dlbmIndex = featureClass.Fields.FindField("GLTBBSM"); while ((jzfeature = upjz_cursor.NextFeature()) != null) { if (dlbmIndex != -1) jzfeature.set_Value(dlbmIndex, null); upjz_cursor.UpdateFeature(jzfeature); Marshal.ReleaseComObject(jzfeature); } } catch (Exception ex) { LogAPI.Debug("清除字段信息异常:" + ex.Message); LogAPI.Debug(ex); return; } } private string CreateTempPath() { var Path = Directory.GetCurrentDirectory() + "\\Temp\\临时用地数据.gdb"; var TempGDBPath = SysAppPath.GetTemplatePath() + "TempGDB.gdb";//模板 if (Directory.Exists(Path)) { try { Directory.Delete(Path, true); } catch (Exception) { } } Directory.CreateDirectory(Path); CopyDirectInfo(TempGDBPath, Path); return Path; } private static void CopyDirectInfo(string sourceDir, string toDir) { if (!Directory.Exists(sourceDir)) { throw new ApplicationException("未找到文件:" + sourceDir); } if (!Directory.Exists(toDir)) { Directory.CreateDirectory(toDir); } DirectoryInfo directInfo = new DirectoryInfo(sourceDir); FileInfo[] filesInfos = directInfo.GetFiles(); foreach (FileInfo fileinfo in filesInfos) { string fileName = fileinfo.Name; File.Copy(fileinfo.FullName, toDir + @"/" + fileName, true); } } #region TableToTable public bool TableToTable(IFeatureWorkspace pInWork, IWorkspace pOutWork, string tableName, IQueryFilter queryFilter = null) { try { if (pInWork == null || pOutWork == null || string.IsNullOrEmpty(tableName)) return false; IWorkspace2 workspace2 = pInWork as IWorkspace2; if (workspace2 != null) { if (!workspace2.get_NameExists(esriDatasetType.esriDTFeatureClass, tableName)) { return false; } } ITable pInTable = pInWork.OpenTable(tableName); if (pInTable == null) return false; IDataset pIndataset = (IDataset)pInTable; IDatasetName pInDatasetName = (IDatasetName)pIndataset.FullName; IEnumDataset enumDataset = pOutWork.get_Datasets(esriDatasetType.esriDTTable); IDataset dataset; enumDataset.Reset(); while ((dataset = enumDataset.Next()) != null) { string[] names = dataset.Name.Split('.'); if (string.Equals(names[names.Length - 1], tableName, StringComparison.CurrentCultureIgnoreCase)) { dataset.Delete(); break; } } IDataset pOutDataset = (IDataset)pOutWork; IDatasetName pOutDatasetName = new TableNameClass(); pOutDatasetName.WorkspaceName = (IWorkspaceName)pOutDataset.FullName; pOutDatasetName.Name = tableName; IFieldChecker fieldChecker = new FieldCheckerClass(); IFields targetFeatureClassFields = pInTable.Fields; IFields sourceFeatureClassFields = pInTable.Fields; IEnumFieldError enumFieldError; fieldChecker.InputWorkspace = pInWork as IWorkspace; fieldChecker.ValidateWorkspace = pOutWork; fieldChecker.Validate(sourceFeatureClassFields, out enumFieldError, out targetFeatureClassFields); IFeatureDataConverter one2another = new FeatureDataConverterClass(); try { one2another.ConvertTable(pInDatasetName, queryFilter, pOutDatasetName, targetFeatureClassFields, "", 1000, 0); } catch (Exception ex) { LogAPI.Debug("one2another.ConvertTable报错,可能原因:当前工程下BGTJ.sqlite文件只读造成的!"); LogAPI.Debug(ex); throw ex; } finally { Marshal.ReleaseComObject(one2another); } return true; } catch (Exception ex) { LogAPI.Debug(ex); throw ex; } } #endregion /// /// 数据筛选 /// /// 基础数据名称 /// 更新层 /// 更新过程 /// 临时数据路径 /// 基础数据路径 private void DLTB_Screen(string JC, string GX, string GXGC, string TempPath, string filePath) { IFeatureLayer Temp_LSYD = null; IFeatureLayer Temp_DLTB = null; IFeatureLayer JCFC = null; IFeatureLayer GXFC = null; IFeatureLayer GXGCFC = null; IWorkspaceAPI wsAPI = null; IFeatureClassAPI sourceFcAPI = null; try { JCFC = MapsManager.Instance.MapService.GetFeatureLayerByLayerName("地类图斑"); GXGCFC = MapsManager.Instance.MapService.GetFeatureLayerByName("DLTBGXGC");//Scheme.gdb增量更新库 GXFC = MapsManager.Instance.MapService.GetFeatureLayerByName("DLTBGX");//Scheme.gdb增量更新库 #region 擦除 GPParamClass paramClass = new GPParamClass() { FirstFeatureLayer = JCFC, SecondFeatureLayer = GXGCFC, OutFeatureClassPath = $"{TempPath}\\LSYD", IsGetOutPutFeature = true, PreserveAttributes = "ALL" }; GeoprocessorHelper.EraseAnalysis(paramClass, ref Temp_LSYD); #endregion #region 合并 //Common.Model.GPParamClass gPParamClass = new Common.Model.GPParamClass() //{ // FirstFeatureClassPath = $"{TempPath}\\LSYD", // SecondFeatureClassPath = $"{filePath}\\变更成果\\{GX}", // IsGetOutPutFeature = true, // OutFeatureClassPath = $"{TempPath}\\Temp_DLTB", //}; //KGIS.Common.Helper.GeoprocessorHelper.UnionAnalysis(gPParamClass, ref Temp_DLTB); wsAPI = new WorkspaceAPI(TempPath, WorkspaceTypeEnum.GDBFile); sourceFcAPI = wsAPI.OpenFeatureClass("LSYD"); LoadFeatureClass(GXFC, sourceFcAPI.FeatureClass, null); #endregion } catch (Exception ex) { LogAPI.Debug("临时用地标识码关联异常:" + ex.Message); throw ex; } finally { if (sourceFcAPI != null) { sourceFcAPI.CloseFeatureClass(); } if (wsAPI != null) { wsAPI.CloseWorkspace(); } if (Temp_DLTB != null) { Marshal.ReleaseComObject(Temp_DLTB); } if (Temp_LSYD != null) { Marshal.ReleaseComObject(Temp_LSYD); } if (JCFC != null) { Marshal.ReleaseComObject(JCFC); } if (GXFC != null) { Marshal.ReleaseComObject(GXFC); } if (GXGCFC != null) { Marshal.ReleaseComObject(GXGCFC); } } } /// /// 将inFeatureClass要素类中所有符合pQueryFilter的要素复制到saveFeatureClass中,仅复制不做任何修改 /// /// 源要素类 /// 存储要素类 /// 过滤参数 /// public bool LoadFeatureClass(IFeatureLayer inIFeatureLayer, IFeatureClass saveFeatureClass, IQueryFilter pQueryFilter) { //生成两个要素类字段的对应表 Dictionary pFieldsDict = new Dictionary(); this.GetFCFieldsDirectory(inIFeatureLayer.FeatureClass, saveFeatureClass, ref pFieldsDict); IFeatureCursor pinFeatCursor = inIFeatureLayer.FeatureClass.Search(pQueryFilter, false); long nCount = inIFeatureLayer.FeatureClass.FeatureCount(pQueryFilter); IFeature pinFeat = pinFeatCursor.NextFeature(); IFeatureCursor psaveFeatCursor = saveFeatureClass.Insert(true); //使用IFeatureBuffer在内存中产生缓存避免多次打开,关闭数据库 IFeatureBuffer psaveFeatBuf = null; IFeature psaveFeat = null; long n = 0; while (pinFeat != null) { try { psaveFeatBuf = saveFeatureClass.CreateFeatureBuffer(); psaveFeat = psaveFeatBuf as IFeature; if (inIFeatureLayer.FeatureClass.FeatureType == esriFeatureType.esriFTAnnotation) { IAnnotationFeature pAF = (IAnnotationFeature)pinFeat; IAnnotationFeature pNAF = (IAnnotationFeature)psaveFeat; if (pAF.Annotation != null) { pNAF.Annotation = pAF.Annotation; } } psaveFeat.Shape = pinFeat.Shape; foreach (KeyValuePair keyvalue in pFieldsDict) { if (pinFeat.get_Value(keyvalue.Key).ToString() == "") { if (psaveFeat.Fields.get_Field(keyvalue.Value).Type == esriFieldType.esriFieldTypeString) { psaveFeat.set_Value(keyvalue.Value, ""); } else { psaveFeat.set_Value(keyvalue.Value, 0); } } else { psaveFeat.set_Value(keyvalue.Value, pinFeat.get_Value(keyvalue.Key)); } } psaveFeatCursor.InsertFeature(psaveFeatBuf); } catch (Exception) { } finally { psaveFeat = null; n++; if (n % 2000 == 0) { psaveFeatCursor.Flush(); } pinFeat = pinFeatCursor.NextFeature(); } } psaveFeatCursor.Flush(); return true; } private void GetFCFieldsDirectory(IFeatureClass pFCold, IFeatureClass pFCnew, ref Dictionary FieldsDictionary) { for (int i = 0; i < pFCold.Fields.FieldCount; i++) { string tmpstrold = pFCold.Fields.get_Field(i).Name.ToUpper(); switch (tmpstrold) { case "OBJECTID": case "SHAPE": case "SHAPE_LENGTH": case "SHAPE_AREA": case "FID": { //以上字段由系统自动生成 break; } default: { for (int j = 0; j < pFCnew.Fields.FieldCount; j++) { string tmpstrnew = pFCnew.Fields.get_Field(j).Name.ToUpper(); if (tmpstrold == tmpstrnew) { FieldsDictionary.Add(i, j); break; } } break; } } } } public override bool Enabled { get { return KGIS.Framework.Maps.MapsManager.Instance.MapService.GetProjectInfo() == null ? false : true; } } } }