using ESRI.ArcGIS.Carto; using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.AE; using KGIS.Framework.AE.GPHelper; using KGIS.Framework.DBOperator; using KGIS.Framework.Platform; using KGIS.Framework.Utils; using KGIS.Framework.Utils.ExtensionMethod; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace WpfApp1.Helper { public class AttributeBatchAssignmentHelper { /// /// 属性批量赋值 /// /// 基础地类图斑 /// 变更范围 /// public void AttributeBatchAssignment(IFeatureLayer jldltbFeatureLayer, IFeatureLayer bgtbFeatureLayer, string xzqdm, string temppath) { IFeatureCursor pCursor = null; IFeature feature = null; List liststr = null; IFeatureLayer JCDLTB_DLTBBGLayer = null; IRDBHelper rdbHelper = null; try { string dbpath = temppath + "\\BGTJ.sqlite"; rdbHelper = rdbHelper = RDBFactory.CreateDbHelper("Data Source=" + dbpath, DatabaseType.SQLite); if (rdbHelper == null) { throw new Exception("数据库连接打开失败:" + dbpath); } DataTable dtDict = rdbHelper.ExecuteDatatable("Sys_DicType", $"SELECT CODE,NAME FROM Sys_DicDetail WHERE OWNERDIC='2' ", true); DataTable dicDt = rdbHelper.ExecuteDatatable("Dic", string.Format("SELECT * from Sys_Dicdetail where OWNERDIC=32"), true); List DicsZZSX = KGIS.Framework.Utils.Utility.TBToList.ToList(dicDt); dicDt = rdbHelper.ExecuteDatatable("Dic", string.Format("SELECT * from Sys_Dicdetail where OWNERDIC=31"), true); List DicsXHLX = KGIS.Framework.Utils.Utility.TBToList.ToList(dicDt); string tableName = "result" + DateTime.Now.ToString("HHmmss"); string dbName = "result" + DateTime.Now.ToString("HHmmss"); string templeteGDBPath = Path.Combine(SysAppPath.GetCurrentAppPath(), "Template", "TempGDB.gdb"); string resultPath = Path.Combine(temppath, "Union_DLTBBG_DLTB"); if (!Directory.Exists(resultPath)) { Directory.CreateDirectory(resultPath); } string savePath = Path.Combine(resultPath, dbName + ".gdb"); CopyDirectory(templeteGDBPath, savePath, true); string outPath = Path.Combine(savePath, tableName); GPParamClass gPParamClass = new GPParamClass { FirstFeatureLayer = bgtbFeatureLayer, SecondFeatureLayer = jldltbFeatureLayer, OutFeatureClassPath = outPath, IsGetOutPutFeature = true }; GeoprocessorHelper.IntersectAnalysis(gPParamClass, ref JCDLTB_DLTBBGLayer); string templeteDBPath = Path.Combine(SysAppPath.GetCurrentAppPath(), "Template", "result.db"); string resultDBPath = Path.Combine(resultPath, dbName + ".db"); File.Copy(templeteDBPath, resultDBPath, true); rdbHelper = RDBFactory.CreateDbHelper(string.Format("Data Source={0};Initial Catalog=sqlite;Integrated Security=True;Max Pool Size=10;", resultDBPath), DatabaseType.SQLite); SetFeatureEllipsoidArea(JCDLTB_DLTBBGLayer.FeatureClass, rdbHelper, resultDBPath, tableName); var featurecount = 0; var count = bgtbFeatureLayer.FeatureClass.FeatureCount(null); pCursor = bgtbFeatureLayer.FeatureClass.Update(null, true); #region 属性 int iQSDWDM = bgtbFeatureLayer.FeatureClass.Fields.FindField("QSDWDM");//权属单位代码 int iQSDWMC = bgtbFeatureLayer.FeatureClass.Fields.FindField("QSDWMC");//权属单位名称 int iZLDWDM = bgtbFeatureLayer.FeatureClass.Fields.FindField("ZLDWDM");//坐落单位代码 int iZLDWMC = bgtbFeatureLayer.FeatureClass.Fields.FindField("ZLDWMC");//坐落单位名称 int iMSSM = bgtbFeatureLayer.FeatureClass.Fields.FindField("MSSM");//描述说明 int iDLBM = bgtbFeatureLayer.FeatureClass.Fields.FindField("DLBM");//地类编码 int iDLMC = bgtbFeatureLayer.FeatureClass.Fields.FindField("DLMC");//地类名称 int iQSXZ = bgtbFeatureLayer.FeatureClass.Fields.FindField("QSXZ");//权属性质 int iGDPDJB = bgtbFeatureLayer.FeatureClass.Fields.FindField("GDPDJB");//耕地坡度级别 int iKCDLXS = bgtbFeatureLayer.FeatureClass.Fields.FindField("KCXS");//扣除地类系数 int iKCDLBM = bgtbFeatureLayer.FeatureClass.Fields.FindField("KCDLBM");//扣除地类编码 int iGDLX = bgtbFeatureLayer.FeatureClass.Fields.FindField("GDLX");//耕地类型 int iGDDB = bgtbFeatureLayer.FeatureClass.Fields.FindField("GDDB");//耕地等别 int iTBXHDM = bgtbFeatureLayer.FeatureClass.Fields.FindField("TBXHDM");//图斑细化代码 int iTBXHMC = bgtbFeatureLayer.FeatureClass.Fields.FindField("TBXHMC");//图斑细化名称 int iZZSXDM = bgtbFeatureLayer.FeatureClass.Fields.FindField("ZZSXDM");//种植属性代码 int iZZSXMC = bgtbFeatureLayer.FeatureClass.Fields.FindField("ZZSXMC");//种植属性名称 int iCZCSXM = bgtbFeatureLayer.FeatureClass.Fields.FindField("CZCSXM");//城镇村属性码 int iXZDWKD = bgtbFeatureLayer.FeatureClass.Fields.FindField("XZDWKD");//线状地物宽度 int iBZ = bgtbFeatureLayer.FeatureClass.Fields.FindField("BZ");//备注 int iFRDBS = bgtbFeatureLayer.FeatureClass.Fields.FindField("FRDBS");//飞入地标识 int iBSM = bgtbFeatureLayer.FeatureClass.Fields.FindField("BSM");//标识码 #endregion var data = rdbHelper.ExecuteDatatable("table", $"select FID_DLTBBG,SHAPE_Area,QSDWDM_1,QSDWMC_1,ZLDWDM_1,ZLDWMC_1,MSSM_1,QSXZ_1,FRDBS_1 from {tableName} ", true); int bsm = 1; while ((feature = pCursor.NextFeature()) != null) { featurecount++; //if (featurecount % 100 == 0 || featurecount == count) // this.UpdateMsg($"属性批量维护...【{featurecount}/{count}】"); string strDLBM = feature.Value[iDLBM].ToTrim(); if (!string.IsNullOrEmpty(strDLBM) && strDLBM.Length > 2) { strDLBM = strDLBM.Substring(0, 2); } #region 属性赋值 var datarow = data.Select($"FID_DLTBBG={feature.OID} ", "SHAPE_Area desc"); DataRow dr = null; if (datarow.Length > 0) { dr = datarow[0]; } else { LogAPI.Debug($"属性批量维护失败:未查找到{feature.OID}对应的基础地类图斑数据!"); continue; } //权属/坐落单位属性 //权属、坐落单位代码及名称未赋值的,按照基础地类图斑数据进行赋值。 if (string.IsNullOrEmpty(feature.Value[iQSDWDM].ToTrim())) feature.Value[iQSDWDM] = dr["QSDWDM_1"]; if (string.IsNullOrEmpty(feature.Value[iQSDWMC].ToTrim())) feature.Value[iQSDWMC] = dr["QSDWMC_1"]; if (string.IsNullOrEmpty(feature.Value[iZLDWDM].ToTrim())) feature.Value[iZLDWDM] = dr["ZLDWDM_1"]; if (string.IsNullOrEmpty(feature.Value[iZLDWMC].ToTrim())) feature.Value[iZLDWMC] = dr["ZLDWMC_1"]; //地类名称 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { var dtrow = dtDict.Select($"CODE = '{feature.Value[iDLBM].ToString()}'"); if (dtrow.Length > 0) feature.Value[iDLMC] = dtrow[0]["NAME"].ToString(); } //权属性质 if (feature.Value[iQSXZ].ToString() == "21" || feature.Value[iQSXZ].ToString() == "41") { feature.Value[iMSSM] = "01"; } else if (string.IsNullOrEmpty(feature.Value[iQSXZ].ToTrim())) { feature.Value[iQSXZ] = dr["QSXZ_1"]; } //耕地坡度级别/扣除地类系数/扣除地类编码 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { if (strDLBM != "01" && !string.IsNullOrEmpty(feature.Value[iGDDB].ToTrim())) { feature.Value[iGDDB] = null; } if (strDLBM != "01" && !string.IsNullOrEmpty(feature.Value[iKCDLXS].ToTrim())) { feature.Value[iKCDLXS] = 0; } if (strDLBM != "01" && !string.IsNullOrEmpty(feature.Value[iKCDLBM].ToTrim())) { feature.Value[iKCDLBM] = null; } if (strDLBM != "01" && !string.IsNullOrEmpty(feature.Value[iGDPDJB].ToTrim())) { feature.Value[iGDPDJB] = null; } } //耕地类型/耕地等别 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { if (strDLBM != "01" && !string.IsNullOrWhiteSpace(feature.Value[iGDLX].ToTrim())) { feature.Value[iGDLX] = ""; } if (strDLBM != "01" && !string.IsNullOrWhiteSpace(feature.Value[iGDDB].ToTrim())) { feature.Value[iGDDB] = null; } } //图斑细化代码/图斑细化名称 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { //非01类图斑,图斑细化代码标注HDGD、HQGD、LQGD、MQGD、SHGD、SMGD、YJGD的需清空。 liststr = new List() { "HDGD", "HQGD", "LQGD", "MQGD", "SHGD", "SMGD", "YJGD" }; if (strDLBM != "01" && liststr.Contains(feature.Value[iTBXHDM].ToString())) { feature.Value[iTBXHDM] = ""; feature.Value[iTBXHMC] = ""; } //非06类用地,TBXHDM字段为HDGY、GTGY、MTGY、SNGY、BLGY、DLGY的需清空。 liststr = new List() { "HDGY", "GTGY", "MTGY", "SNGY", "BLGY", "DLGY" }; if (strDLBM != "06" && liststr.Contains(feature.Value[iTBXHDM].ToString())) { feature.Value[iTBXHDM] = ""; feature.Value[iTBXHMC] = ""; } //非04类图斑,标注GCCD的需清除。 if (strDLBM != "04" && feature.Value[iTBXHDM].ToString() == "GCCD") { feature.Value[iTBXHDM] = ""; feature.Value[iTBXHMC] = ""; } //非03类,0404的图斑,标注LJTM的需要清除。 if (strDLBM != "03" && feature.Value[iDLBM].ToString() != "0404" && feature.Value[iTBXHDM].ToString() == "LJTM") { feature.Value[iTBXHDM] = ""; feature.Value[iTBXHMC] = ""; } //地类编码字段前2位非01、02、03、04,且不等于0601、0602、1001、1003,或属于湿地的,不能进行图斑细化标注 liststr = new List() { "01", "02", "03", "04", "0601", "0602", "1001", "1003", "0303", "0304", "0306", "0402", "0603", "1105", "1106", "1108" }; if (!liststr.Contains(strDLBM) && !liststr.Contains(feature.Value[iDLBM].ToString()) && !liststr.Contains(feature.Value[iDLBM].ToString())) { feature.Value[iTBXHDM] = ""; feature.Value[iTBXHMC] = ""; } } //细化代码覆盖名称赋值 if (!string.IsNullOrWhiteSpace(feature.Value[iTBXHDM].ToTrim())) { DataDicTionary XHMC = DicsXHLX.FirstOrDefault(x => x.CODE == feature.Value[iTBXHDM].ToTrim()); if (XHMC != null) feature.Value[iTBXHMC] = XHMC.NAME; } //种植属性代码/种植属性名称 liststr = new List() { "LS", "FLS", "LYFL", "XG", "LLJZ", "WG" }; if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { //非01类图斑,种植属性代码标注LS、FLS、LYFL、XG、LLJZ、WG的需要清空; if (strDLBM != "01" && !strDLBM.StartsWith("01") && liststr.Contains(feature.Value[iZZSXDM].ToTrim())) { feature.Value[iZZSXDM] = ""; feature.Value[iZZSXMC] = ""; } //非0301、0302、0305、0307、0404、1104、1104A,0201、0202、0203、0204、0201K、0202K、0203K、0204K、0301K、0302K、0307K、0403K、1104K的种植属性代码填写JKHF、GCHF的需清空。 liststr = new List() { "0301", "0302", "0305", "0307", "0404", "1104", "1104A", "0201", "0202", "0203", "0204", "0201K", "0202K", "0203K", "0204K", "0301K", "0302K", "0307K", "0403K", "1104K" }; if (!liststr.Contains(feature.Value[iDLBM].ToTrim()) && (feature.Value[iZZSXDM].ToTrim() == "JKHF" || feature.Value[iZZSXDM].ToTrim() == "GCHF")) { feature.Value[iZZSXDM] = ""; feature.Value[iZZSXMC] = ""; } //地类编码字段前2位为04(不包括0404、0403K)、05、06、07、08、09、10、11(不包括1104、1104A、1104K)、12,或属于湿地的,不能进行种植属性标注或恢复属性标注; liststr = new List() { "04", "05", "06", "07", "08", "09", "10", "11", "12", "0303", "0304", "0306", "0402", "0603", "1105", "1106", "1108" }; var liststr1 = new List() { "0404", "0403K", "1104", "1104A", "1104K" }; if ((liststr.Contains(strDLBM) || liststr.Contains(feature.Value[iDLBM].ToTrim())) && !liststr1.Contains(feature.Value[iDLBM].ToTrim())) { feature.Value[iZZSXDM] = ""; feature.Value[iZZSXMC] = ""; } } //种植属性名称覆盖赋值 if (!string.IsNullOrWhiteSpace(feature.Value[iZZSXDM].ToTrim())) { DataDicTionary XHZZ = DicsZZSX.FirstOrDefault(x => x.CODE == feature.Value[iZZSXDM].ToTrim()); if (XHZZ != null) feature.Value[iZZSXMC] = XHZZ.NAME; } //城镇村属性码 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { //1001、1002、1003、1007、1008、1009、1109的图斑,城镇村属性码应为空 liststr = new List() { "1001", "1002", "1003", "1007", "1008", "1009", "1109" }; if (liststr.Contains(feature.Value[iDLBM].ToString())) { feature.Value[iCZCSXM] = ""; } } //线状地物宽度 if (!string.IsNullOrEmpty(feature.Value[iDLBM].ToTrim())) { //非线性图斑要清除线状地物宽度 liststr = new List() { "1001", "1002", "1003", "1004", "1006", "1009", "1101", "1107", "1107A", "1203" }; if (!liststr.Contains(feature.Value[iDLBM].ToString()) && feature.Value[iXZDWKD].ToString() != "0") { feature.Value[iXZDWKD] = 0; } } #endregion feature.Value[iBSM] = $"{xzqdm}2110{(bsm++).ToString().PadLeft(8, '0')}"; feature.Store(); } pCursor.Flush(); } catch (Exception ex) { LogAPI.Debug("属性批量维护失败:" + ex.Message); LogAPI.Debug("属性批量维护失败:" + ex.StackTrace); } finally { if (pCursor != null) Marshal.ReleaseComObject(pCursor); if (feature != null) Marshal.ReleaseComObject(feature); if (rdbHelper != null) { rdbHelper.DisConnect(); rdbHelper = null; } //if (bgtbFeatureLayer != null) // Marshal.ReleaseComObject(bgtbFeatureLayer); //if (jldltbFeatureLayer != null) // Marshal.ReleaseComObject(jldltbFeatureLayer); } } /// /// 拷贝模板gdb文件夹 /// /// /// /// public static void CopyDirectory(string SourcePath, string DestinationPath, bool overwriteexisting) { try { SourcePath = SourcePath.EndsWith(@"\") ? SourcePath : SourcePath + @"\"; DestinationPath = DestinationPath.EndsWith(@"\") ? DestinationPath : DestinationPath + @"\"; if (Directory.Exists(SourcePath)) { if (Directory.Exists(DestinationPath) == false) Directory.CreateDirectory(DestinationPath); foreach (string fls in Directory.GetFiles(SourcePath)) { FileInfo flinfo = new FileInfo(fls); flinfo.CopyTo(DestinationPath + flinfo.Name, overwriteexisting); } foreach (string drs in Directory.GetDirectories(SourcePath)) { DirectoryInfo drinfo = new DirectoryInfo(drs); CopyDirectory(drs, DestinationPath + drinfo.Name, overwriteexisting); } } } catch (Exception ex) { throw ex; } } private void SetFeatureEllipsoidArea(IFeatureClass featureClass, IRDBHelper rdbHelper, string dbPath, string tableName) { ICursor pCursor = null; IRow pRow = null; try { if (featureClass == null) { return; } IFeatureClassAPI featureClassAPI = new FeatureClassAPI(featureClass); int shapeIndex = featureClass.Fields.FindField("SHAPE"); if (shapeIndex < 0) { throw new Exception("未找到SHAPE字段"); } List listSQL = new List(); string fieldStr = string.Empty; string insertField = string.Empty; Dictionary listFieldIndex = new Dictionary(); for (int f = 0; f < featureClassAPI.FeatureClass.Fields.FieldCount; f++) { IField field = featureClassAPI.FeatureClass.Fields.Field[f]; if (field.Name.ToUpper() == "SHAPE") { continue; } switch (field.Type) { case esriFieldType.esriFieldTypeSmallInteger: case esriFieldType.esriFieldTypeInteger: case esriFieldType.esriFieldTypeOID: fieldStr += field.Name + " INTEGER,"; insertField += field.Name + ","; listFieldIndex.Add(f, false); break; case esriFieldType.esriFieldTypeDouble: case esriFieldType.esriFieldTypeSingle: fieldStr += field.Name + " NUMERIC,"; insertField += field.Name + ","; listFieldIndex.Add(f, false); break; case esriFieldType.esriFieldTypeString: case esriFieldType.esriFieldTypeDate: fieldStr += field.Name + " TEXT,"; insertField += field.Name + ","; listFieldIndex.Add(f, true); break; } } string createTableSQL = string.Format("CREATE TABLE {1} ({0})", fieldStr.TrimEnd(','), tableName); rdbHelper.ExecuteNonQueryWithException(createTableSQL, CommandType.Text); string insertSQL = "insert into " + tableName + "(" + insertField.TrimEnd(',') + ")values({0});"; int count = featureClassAPI.FeatureClass.FeatureCount(null); int i = 0; pCursor = (featureClass as ITable).Search(null, true); while ((pRow = pCursor.NextRow()) != null) { string value = string.Empty; foreach (var item in listFieldIndex) { object obj = pRow.get_Value(item.Key); if (item.Value) { if (obj == null || string.IsNullOrWhiteSpace(obj.ToString())) { value += "'',"; } else { value += "'" + obj.ToString().Replace("'", "") + "',"; } } else { if (obj == null || string.IsNullOrWhiteSpace(obj.ToString())) { obj = 0; } value += obj + ","; } } listSQL.Add(string.Format(insertSQL, value.TrimEnd(','))); i++; //if (i % 100 == 0 || i == count) // this.UpdateMsg($"正在数据写入...【{i}/{count}】"); if (listSQL.Count > 6000) { InsertDB(listSQL, dbPath); listSQL.Clear(); } else if (i == count) { InsertDB(listSQL, dbPath); listSQL.Clear(); } } } catch (Exception ex) { throw ex; } finally { if (pCursor != null) { Marshal.ReleaseComObject(pCursor); } if (pRow != null) { Marshal.ReleaseComObject(pRow); } } } /// /// 多线程插入数据到db中 /// /// /// private void InsertDB(List listSQL, string dbPath) { try { using (BlockingCollection blockingCollection = new BlockingCollection()) { listSQL.ForEach(x => blockingCollection.Add(x)); blockingCollection.CompleteAdding(); int taskNum = 5; Task[] tasks = new Task[taskNum]; for (int i = 0; i < taskNum; i++) { tasks[i] = Task.Factory.StartNew(() => { ExcuteThead(blockingCollection, dbPath); }); } Task.WaitAll(tasks); for (int i = 0; i < taskNum; i++) { tasks[i].Dispose(); } } } catch (Exception ex) { throw ex; } } private void ExcuteThead(BlockingCollection blockingCollection, string dbPath) { IRDBHelper rdbHelper = null; string sqlDe = string.Empty; try { rdbHelper = RDBFactory.CreateDbHelper(string.Format("Data Source={0};Initial Catalog=sqlite;Integrated Security=True;Max Pool Size=10;", dbPath), DatabaseType.SQLite); if (rdbHelper == null) { throw new Exception("执行成果接收时打开数据库连接字符串失败!"); } rdbHelper.BeginTransaction(); foreach (string sql in blockingCollection.GetConsumingEnumerable()) { sqlDe = sql; rdbHelper.ExecuteNonQueryWithException(sql, CommandType.Text); } rdbHelper.Commit(); } catch (Exception ex) { if (rdbHelper != null) { rdbHelper.Rollback(); } LogAPI.Debug(sqlDe); LogAPI.Debug(ex); throw ex; } finally { if (rdbHelper != null) { rdbHelper.DisConnect(); } } } } }