using ESRI.ArcGIS.DataSourcesGDB; using ESRI.ArcGIS.esriSystem; using ESRI.ArcGIS.Geodatabase; using ESRI.ArcGIS.Geometry; using KGIS.Framework.DBOperator; using KGIS.Framework.Maps; using KGIS.Framework.Utils; using Kingo.Crypto; using System; using System.Collections.Generic; using System.Data; using System.Linq; namespace Kingo.PluginServiceInterface.Helper { public class DecompressionDB { /// /// 将多个db合并输出到gdb中 /// public void MultDBToGDB(List lstExport, string saveGDBPath, int wkid, string dbKey = "") { IWorkspace workspace = null; IFeatureDataset featureDataset = null; try { string tempPath = SysAppPath.GetTempPath(); try { //清空临时文件夹输出的临时成果包 if (!string.IsNullOrWhiteSpace(tempPath) && System.IO.Directory.Exists(tempPath)) { string[] files = System.IO.Directory.GetFiles(tempPath, "*.ExportTemp"); if (files != null) { foreach (var item in files) { System.IO.File.Delete(item); } } } } catch { } workspace = CreateLocalWorkspace(saveGDBPath, ref featureDataset, "TDBZSJJ", wkid); var groupValue = lstExport.GroupBy(x => x.BID); List exportTables = new List() { "WYRW", "DTBDLTBGX" }; foreach (IGrouping group in groupValue) { List lst = null; IRDBHelper rdbHelper = null; try { lst = group.ToList(); rdbHelper = RDBFactory.CreateDbHelper($"{lst[0].PackagePath}{(MapsManager.Instance.CurrProjectInfo as ProjectInfo).Pathpassword}", DatabaseType.SQLite); foreach (var tableName in exportTables) { DataTable dataTable = null; ITable table = null; try { if (tableName == "DTBDLTBGX") dataTable = rdbHelper.ExecuteDatatable("data", $"select * from {tableName} where (isDelete ISNULL or isDelete = '' or isDelete <> '1' ) and TBBSM IN('{string.Join("','", lst.Select(x => x.TBBSM))}')", true); else dataTable = rdbHelper.ExecuteDatatable("data", $"select * from {tableName} where TBBSM IN('{string.Join("','", lst.Select(x => x.TBBSM))}')", true); if (dataTable == null) { return; } try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); } catch { IFields fields = GetFieldsByDataTable(dataTable); //创建必要字段OBJECTID,SHAPE CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } DataTableImportToMDB(dataTable, table); //更新记录每个图斑对应的包名称,用来导入成果数据时,与任务包匹配导入 if (tableName.Equals("WYRW")) { if (table.Fields.FindField("BID") == -1) { //建立OBJECTID字段 IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "BID"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString; table.AddField(pField); } featureDataset.Workspace.ExecuteSQL($"update WYRW set BID='{group.Key}' where BID is null or BID=''"); } else if (tableName.Equals("DTBDLTBGX")) { //湖南新增字段“JCBH”,对应任务图斑的监测编号 if (table.Fields.FindField("JCBH") == -1) { //建立JCBH字段 IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "JCBH"; pFieldEdit.AliasName_2 = "监测编号"; pFieldEdit.Length_2 = 50; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString; table.AddField(pField); } featureDataset.Workspace.ExecuteSQL($"update DTBDLTBGX set JCBH=TBBSM"); } } catch (Exception ex) { throw ex; } finally { if (table != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(table); } } } } catch (Exception ex) { throw new Exception(lst[0].PackageName + "导出异常:" + ex.Message); } finally { if (rdbHelper != null) { rdbHelper.DisConnect(); } } } } catch (Exception ex) { LogAPI.Debug("批量导出成果失败:" + ex); throw ex; } finally { if (featureDataset != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(featureDataset); } if (workspace != null) { try { IDatabaseCompact databaseCompact = workspace as IDatabaseCompact; databaseCompact.Compact(); } catch { } System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace); } } } /// /// 将多个db合并输出到gdb中 /// public void MultDBToGDB(Dictionary dicPath, string saveGDBPath, int wkid, string SM2PrivateKey = "", string dbKey = "", double tolerance = 0.0001) { IWorkspace workspace = null; IFeatureDataset featureDataset = null; try { string tempPath = KGIS.Framework.Utils.SysAppPath.GetTempPath(); try { //清空临时文件夹输出的临时成果包 if (!string.IsNullOrWhiteSpace(tempPath) && System.IO.Directory.Exists(tempPath)) { string[] files = System.IO.Directory.GetFiles(tempPath, "*.ExportTemp"); if (files != null) { foreach (var item in files) { System.IO.File.Delete(item); } } } } catch { } foreach (var item in dicPath) { ITable table = null; IRDBHelper rdbHelper = null; try { if (string.IsNullOrWhiteSpace(item.Value) || !System.IO.File.Exists(item.Value)) { throw new Exception("未找到db文件:" + item); } //拷贝db到临时文件夹,防止修改或损坏了原始任务包 string dbPath = System.IO.Path.Combine(tempPath, Guid.NewGuid().ToString().Replace("-", "") + ".db"); System.IO.File.Copy(item.Value, dbPath, true); rdbHelper = RDBFactory.CreateDbHelper(dbPath, DatabaseType.SQLite); DataTable hasTable = rdbHelper.ExecuteDatatable("data", "SELECT name FROM sqlite_master WHERE type = 'table' and name<>'sqlite_sequence' ORDER BY name;", true); if (hasTable == null || hasTable.Rows.Count <= 0) { LogAPI.Debug("db文件数据为空:未找到db文件中存在表!"); return; } DecryptDB(rdbHelper, hasTable, SM2PrivateKey, ref wkid); if (workspace == null || featureDataset == null) { workspace = CreateLocalWorkspace(saveGDBPath, ref featureDataset, "TDBZSJJ", wkid); } foreach (DataRow dr in hasTable.Rows) { string tableName = dr[0] as string; //只导出外业任务表 if (!tableName.Equals("wyrw", StringComparison.CurrentCultureIgnoreCase) && !tableName.Equals("dtbdltbgx", StringComparison.CurrentCultureIgnoreCase)) { continue; } CreateFeatureClassAndImportData(rdbHelper, featureDataset, tableName, true, dbKey, saveGDBPath); if (!tableName.Equals("wyrw", StringComparison.CurrentCultureIgnoreCase)) { continue; } //只需要将外业任务表增加PackName字段,DTBDLTBGX图层通过TBBSM与外业任务表关联 table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); if (table.Fields.FindField("PackName") == -1) { //建立OBJECTID字段 IField pField = new FieldClass(); IFieldEdit pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "PackName"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString; table.AddField(pField); } //更新记录每个图斑对应的包名称,用来导入成果数据时,与任务包匹配导入 featureDataset.Workspace.ExecuteSQL($"update {tableName} set PackName='{item.Key}' where PackName is null or PackName=''"); } } catch (Exception ex) { throw new Exception(dicPath.Keys + "导出失败:" + ex.Message); } finally { if (rdbHelper != null) { rdbHelper.DisConnect(); } } } } catch (Exception ex) { throw ex; } finally { if (featureDataset != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(featureDataset); } if (workspace != null) { try { IDatabaseCompact databaseCompact = workspace as IDatabaseCompact; databaseCompact.Compact(); } catch { } System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace); } } } /// /// 将DB矢量化为GDB /// /// 需要矢量化的DB文件路径 /// 如果db存在密码,则将密码传输过来 /// 矢量化后MDB文件路径(可选参数) /// 坐标参考容差:默认0.0001 /// 矢量化后MDB文件路径 public string DBToGDB(string dbPath, string saveGDBPath, int wkid, string SM2PrivateKey = "", string dbKey = "", double tolerance = 0.0001) { IWorkspace workspace = null; IFeatureDataset featureDataset = null; IRDBHelper rdbHelper = null; try { if (string.IsNullOrWhiteSpace(dbPath) || !System.IO.File.Exists(dbPath)) { throw new Exception("未找到db文件:" + dbPath); } rdbHelper = RDBFactory.CreateDbHelper($"{dbPath}{(MapsManager.Instance.CurrProjectInfo as ProjectInfo).Pathpassword}", DatabaseType.SQLite); DataTable hasTable = rdbHelper.ExecuteDatatable("data", "SELECT name FROM sqlite_master WHERE type = 'table' and name<>'sqlite_sequence' ORDER BY name;", true); if (hasTable == null || hasTable.Rows.Count <= 0) { throw new Exception("db文件中存在表!"); } DecryptDB(rdbHelper, hasTable, SM2PrivateKey, ref wkid); if (workspace == null || featureDataset == null) { workspace = CreateLocalWorkspace(saveGDBPath, ref featureDataset, "TDBZSJJ", wkid, tolerance); } foreach (DataRow dr in hasTable.Rows) { CreateFeatureClassAndImportData(rdbHelper, featureDataset, dr[0] as string, false, dbKey, saveGDBPath); } return saveGDBPath; } catch (Exception ex) { throw ex; } finally { if (rdbHelper != null) { rdbHelper.DisConnect(); } if (workspace != null) { try { IDatabaseCompact databaseCompact = workspace as IDatabaseCompact; databaseCompact.Compact(); } catch { } System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace); } } } public string BGFWToGDB(string dbPath, string saveGDBPath, string SM2PrivateKey = "", int wkid = -1, double tolerance = 0.0001) { IWorkspace workspace = null; ITable table = null; IFeatureDataset featureDataset = null; ICursor cursor = null; IRDBHelper rdbHelper = null; try { if (string.IsNullOrWhiteSpace(dbPath) || !System.IO.File.Exists(dbPath)) { throw new Exception("未找到db文件:" + dbPath); } try { rdbHelper = RDBFactory.CreateDbHelper($"{dbPath}", DatabaseType.SQLite); } catch { rdbHelper = RDBFactory.CreateDbHelper($"{dbPath}{(MapsManager.Instance.CurrProjectInfo as ProjectInfo).Pathpassword}", DatabaseType.SQLite); } //saveGDBPath = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + ".mdb"); List lst = new List() { "DTBDLTBGX", "DTBCCWJQGX", "DTBCZCDYDGX", "DTBGFBQGX", "DTBLMFWGX", "DTBLSYDGX", "DTBTTQGX", "DTBDLTBGXGC" }; foreach (var tableName in lst) { DataTable hasTable = rdbHelper.ExecuteDatatable("data", $"SELECT name FROM sqlite_master WHERE type = 'table' and name='{tableName}' ORDER BY name;", true); if (hasTable == null || hasTable.Rows.Count <= 0) { LogAPI.Debug($"db文件中不存在变更范围表({tableName})!"); continue; } DataTable dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName}", true); if (dataTable == null) { LogAPI.Debug($"变更范围表({tableName})表无数据!"); continue; } if (wkid <= 0 && dataTable != null && dataTable.Rows.Count > 0) { try { DataRow dataRow = dataTable.Rows[0]; string geometryStr = dataRow["egeometry"] as string; geometryStr = SM4Decrypt(geometryStr, System.Text.Encoding.UTF8.GetString(SM2.Decrypt(SM2PrivateKey, dataRow["PWD_SHAPE"] as string))); ESRI.ArcGIS.Geometry.IGeometry geometry = ConverJsonToIGeoemtry(geometryStr); wkid = geometry.SpatialReference.FactoryCode; if (wkid <= 0 || wkid == 4490) { KGIS.Framework.AE.GaussCalculate.CoordinateReferenceMapping coordinateReferenceMapping = KGIS.Framework.AE.GaussCalculate.CoordinateHelper.ListCoordinateReference.FirstOrDefault(x => (geometry.Envelope.XMin > x.MinX && geometry.Envelope.XMax < x.MaxX)); if (coordinateReferenceMapping != null) { wkid = coordinateReferenceMapping.WKID; } } } catch (Exception ex) { throw ex; } } if (workspace == null) { workspace = CreateLocalWorkspace(saveGDBPath, ref featureDataset, "TDBZSJJ", wkid, tolerance); } IFields fields = GetFieldsByDataTable(dataTable, true); /* 修改时间:2022-10-11 * 修改人:高山 * 修改原因: DTBDLTBGXGC 也需要矢量化 */ //if (tableName.Equals("DTBDLTBGXGC"))//属性表 //{ // //创建字段 // CreateMainField(fields as IFieldsEdit, null, esriGeometryType.esriGeometryNull); // try // { // table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); // table.DeleteSearchedRows(null); // } // catch // { // table = (featureDataset.Workspace as IFeatureWorkspace).CreateTable(tableName, fields, null, null, ""); // } //} //else//矢量表 //{ if (!dataTable.Columns.Contains("EGEOMETRY") || !dataTable.Columns.Contains("PWD_SHAPE")) { LogAPI.Debug($"变更范围表({tableName})表缺少EGEOMETRY和PWD_SHAPE字段!"); continue; } //创建必要字段OBJECTID,SHAPE CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); table.DeleteSearchedRows(null); } catch { table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } //} cursor = table.Insert(true); IRowBuffer rowBuffer = table.CreateRowBuffer(); int indexShape = table.FindField("Shape"); foreach (DataRow dr in dataTable.Rows) { foreach (DataColumn dc in dataTable.Columns) { int index = table.FindField(dc.ColumnName); if (index > -1 && !dc.ColumnName.Equals("shape", StringComparison.CurrentCultureIgnoreCase)) { if ((dr[dc.ColumnName] as byte[]) != null) { IMemoryBlobStream pMBS = new MemoryBlobStreamClass(); IMemoryBlobStreamVariant varBlobStream = (IMemoryBlobStreamVariant)pMBS; object objValue = dr[dc.ColumnName]; varBlobStream.ImportFromVariant(objValue); rowBuffer.set_Value(index, varBlobStream); } else { rowBuffer.set_Value(index, dr[dc.ColumnName]); } } //处理图形 if ((dc.ColumnName.EndsWith("geometry", StringComparison.CurrentCultureIgnoreCase) || dc.ColumnName.Equals("shape", StringComparison.CurrentCultureIgnoreCase)) && indexShape > -1 && !string.IsNullOrWhiteSpace(dr[dc.ColumnName] as string)) { IGeometry geometry = null; string geometryString = string.Empty; try { geometryString = SM4Decrypt(dr[dc.ColumnName] as string, System.Text.Encoding.UTF8.GetString(SM2.Decrypt(SM2PrivateKey, dr["PWD_SHAPE"] as string))); } catch (Exception ex) { geometryString = dr[dc.ColumnName] as string; LogAPI.Debug("字段解密失败:" + ex.Message); } IFeatureClass featureClass = table as IFeatureClass; if (featureClass != null) { switch (featureClass.ShapeType) { case esriGeometryType.esriGeometryPoint: geometry = ConverJsonToIGeoemtry(geometryString, esriGeometryType.esriGeometryPoint); break; case esriGeometryType.esriGeometryPolyline: geometry = ConverJsonToIGeoemtry(geometryString, esriGeometryType.esriGeometryPolyline); break; case esriGeometryType.esriGeometryPolygon: geometry = ConverJsonToIGeoemtry(geometryString); break; } } if (geometry != null) { geometry.Project((table as IGeoDataset).SpatialReference); rowBuffer.set_Value(indexShape, geometry); } } } cursor.InsertRow(rowBuffer); } cursor.Flush(); System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); cursor = null; } return saveGDBPath; } catch (Exception ex) { throw ex; } finally { if (cursor != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); } if (table != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(table); } if (featureDataset != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(featureDataset); } if (workspace != null) { try { IDatabaseCompact databaseCompact = workspace as IDatabaseCompact; databaseCompact.Compact(); } catch { } System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace); } } } /// /// 解密db /// /// /// 对称加密秘钥 private void DecryptDB(IRDBHelper rdbHelper, DataTable hasTable, string SM2PrivateKey, ref int wkid) { string sm4PrivateKey = string.Empty; try { DataTable dataTableYSJ = rdbHelper.ExecuteDatatable("ysj", "SELECT WKID,Encrypted,pwd FROM ysj", true); if (dataTableYSJ == null || dataTableYSJ.Rows.Count <= 0) { throw new Exception("db包元数据(YSJ)表为空,无法获取矢量化必要的坐标参考WKID!"); } object obj = dataTableYSJ.Rows[0][0]; int dbWKID = 0; if (!(obj is DBNull) && obj != null && int.TryParse(obj.ToString(), out dbWKID)) { if (dbWKID > 1000) { wkid = dbWKID; } } if (wkid <= 1000) { throw new Exception("db包元数据(YSJ)表中WKID坐标参考为空!"); } if (dataTableYSJ.Rows[0][1] is DBNull || dataTableYSJ.Rows[0][1] == null) { throw new Exception("db包元数据(YSJ)表中是否加密字段(Encrypted)为空!"); } string sfjm = dataTableYSJ.Rows[0][1].ToString(); if (sfjm == "1") { if (dataTableYSJ.Rows[0][2] is DBNull) { throw new Exception("db包元数据(YSJ)表中加密字段(Encrypted)为1,标识是加密包,但Pwd(密码字段)为空!"); } string pwd = dataTableYSJ.Rows[0][2].ToString(); if (string.IsNullOrWhiteSpace(SM2PrivateKey)) { throw new Exception("任务包是加密的,未检测到加密狗!"); } sm4PrivateKey = System.Text.Encoding.UTF8.GetString(Kingo.Crypto.SM2.Decrypt(SM2PrivateKey, pwd)); } else { return; } List listTableName = new List(); if (hasTable != null && hasTable.Rows.Count > 0) { foreach (DataRow item in hasTable.Rows) { string tableName = item[0] as string; if (tableName.Equals("dtbdltbgx", StringComparison.CurrentCultureIgnoreCase) || tableName.Equals("wyrw", StringComparison.CurrentCultureIgnoreCase)) { listTableName.Add(tableName); } } } //else //{ // listTableName = new List() { "dtbdltbgx", "wyrw" }; //} foreach (var item in listTableName) { DataTable dataTable = rdbHelper.ExecuteDatatable(item, $"select bsm,egeometry from {item}", true); if (dataTable == null || dataTable.Rows.Count <= 0) { continue; } string excuteSQL = "update {2} set egeometry='{0}' where bsm='{1}'"; foreach (DataRow dataRow in dataTable.Rows) { string geometryStr = dataRow["egeometry"] as string; try { geometryStr = SM4Decrypt(geometryStr, sm4PrivateKey); } catch (Exception ex) { try { ESRI.ArcGIS.Geometry.IGeometry geometry = ConverJsonToIGeoemtry(geometryStr); } catch { throw ex; } } rdbHelper.ExecuteNonQueryWithException(string.Format(excuteSQL, geometryStr, dataRow["bsm"], item), CommandType.Text); //ExecuteSQL(dbPath, string.Format(excuteSQL, geometryStr, dataRow["bsm"], item), dbKey); } } //质检解密db时,需要修改解密后的db //if (hasTable == null) //{ rdbHelper.ExecuteNonQueryWithException("update ysj set Encrypted=0,pwd=null", CommandType.Text); //ExecuteSQL(dbPath, "update ysj set Encrypted=0,pwd=null", dbKey); //} } catch (Exception ex) { throw new Exception("解密任务包异常:" + ex.Message); } } /// /// 创建要素类并导入数据 /// /// /// /// private void CreateFeatureClassAndImportData(IRDBHelper rdbHelper, IFeatureDataset featureDataset, string tableName, bool isMultExport = false, string dbKey = "", string saveGDBPath = "") { ITable table = null; try { DataTable dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName} where 1=2", true); if (dataTable == null) { return; } IFields fields = GetFieldsByDataTable(dataTable); switch (tableName.ToLower()) { //属性表 case "ysj": case "dtbdltbgxgc": case "nyysresult": case "dtbccwjqgx": case "dtbczcdydgx": case "dtblsydgx": case "dtbgfbqgx": case "dtblmfwgx": case "dtbttqgx": case "returncomments": case "gjfkjg": case "wyhccg": case "wyhcrw": case "wyhcfj": case "fjgx": case "pzwj": //创建必要字段OBJECTID,SHAPE CreateMainField(fields as IFieldsEdit, null, esriGeometryType.esriGeometryNull); try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); if (!isMultExport)//不是批量导出的需要清空图层,批量输出任务的不需要清空 { table.DeleteSearchedRows(null); } } catch { table = (featureDataset.Workspace as IFeatureWorkspace).CreateTable(tableName, fields, null, null, ""); } break; case "dtbdltbgx"://变更范围 case "wyrw"://外业任务 //创建必要字段OBJECTID,SHAPE CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(tableName); if (!isMultExport)//不是批量导出的需要清空图层,批量输出任务的不需要清空 { table.DeleteSearchedRows(null); } } catch { table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } //单图斑地类图斑更新层生成五要素 //if (table != null && tableName.Equals("dtbdltbgx", StringComparison.CurrentCultureIgnoreCase)) //{ // GenerateAttributeHelper.CheckExtFiled(table as IFeatureClass); // GenerateAttributeHelper.SetFeatureAttribute(table as IFeatureClass); //} break; case "wysketch"://预处理指导草图 Dictionary dciBZTable = new Dictionary(); dciBZTable.Add("点", "MarkPoint"); dciBZTable.Add("线", "MarkLine"); dciBZTable.Add("面", "MarkPolygon"); foreach (var item in dciBZTable) { fields = GetFieldsByDataTable(dataTable); //创建必要字段OBJECTID,SHAPE switch (item.Key) { case "点": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPoint); break; case "线": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolyline); break; case "面": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); break; } try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(item.Value); if (!isMultExport)//不是批量导出的需要清空图层,批量输出任务的不需要清空 { table.DeleteSearchedRows(null); } } catch { table = featureDataset.CreateFeatureClass(item.Value, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName} where bzlx='{item.Key}'", true); if (dataTable.Rows.Count <= 0) { continue; } DataTableImportToMDB(dataTable, table); } return; case "sjshbz"://省级审核标注 dciBZTable = new Dictionary(); dciBZTable.Add("点", "SHBZPoint"); dciBZTable.Add("线", "SHBZLine"); dciBZTable.Add("面", "SHBZPolygon"); foreach (var item in dciBZTable) { fields = GetFieldsByDataTable(dataTable); //创建必要字段OBJECTID,SHAPE switch (item.Key) { case "点": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPoint); break; case "线": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolyline); break; case "面": CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); break; } try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(item.Value); if (!isMultExport)//不是批量导出的需要清空图层,批量输出任务的不需要清空 { table.DeleteSearchedRows(null); } } catch { table = featureDataset.CreateFeatureClass(item.Value, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName} where bzlx='{item.Key}'", true); if (dataTable.Rows.Count <= 0) { continue; } DataTableImportToMDB(dataTable, table); } return; case "label"://外业草图 Dictionary dciBZTable1 = new Dictionary(); dciBZTable1.Add(0, "WYCTPoint"); dciBZTable1.Add(1, "WYCTLine"); dciBZTable1.Add(2, "WYCTPolygon"); foreach (var item in dciBZTable1) { fields = GetFieldsByDataTable(dataTable); //创建必要字段OBJECTID,SHAPE switch (item.Key) { case 0: CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPoint); break; case 1: CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolyline); break; case 2: CreateMainField(fields as IFieldsEdit, (featureDataset as IGeoDataset).SpatialReference, esriGeometryType.esriGeometryPolygon); break; } try { table = (featureDataset.Workspace as IFeatureWorkspace).OpenTable(item.Value); if (!isMultExport)//不是批量导出的需要清空图层,批量输出任务的不需要清空 { table.DeleteSearchedRows(null); } } catch { table = featureDataset.CreateFeatureClass(item.Value, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable; } dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName} where TYPE={item.Key}", true); if (dataTable.Rows.Count <= 0) { continue; } DataTableImportToMDB(dataTable, table); } return; default: return; } if (tableName.ToUpper() == "WYHCFJ") { dataTable = rdbHelper.ExecuteDatatable(tableName, $"select BSM,HCLX,HCJLBSM,DKID,FJMC,FJLX,FJLJ,MODE,SEQUENCE,SUBTYPE,ARG,ARG2,ARG3,IS_SELECTED,CJSJ,LENGTH,POINTS_JSON,HCRY,GROUP_INDEX,GROUPCODE,SUBTASKID,CHECK_CODE from {tableName}", true); } else { dataTable = rdbHelper.ExecuteDatatable(tableName, $"select * from {tableName}", true); } if (dataTable.Rows.Count <= 0) { return; } DataTableImportToMDB(dataTable, table); //如果是解压,则将照片解析到文件夹中 if (tableName.Equals("wyhcfj", StringComparison.CurrentCultureIgnoreCase)) { string fjSavePath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(saveGDBPath), "外业照片"); if (!System.IO.Directory.Exists(fjSavePath)) { System.IO.Directory.CreateDirectory(fjSavePath); } foreach (DataRow item in dataTable.Rows) { string excuteSQL = string.Format("select ARG4 from wyhcfj where bsm='{0}'", item["BSM"]); byte[] content = rdbHelper.ReadBlobToBytes(excuteSQL, null); string fjmc = item["FJMC"] as string; if (string.IsNullOrWhiteSpace(fjmc)) { fjmc = Guid.NewGuid().ToString().Replace("-", ""); } string imagePath = System.IO.Path.Combine(fjSavePath, fjmc); //byte[] content = item["ARG4"] as byte[]; if (content == null || content.Length <= 0) { continue; } //照片不存在时下载照片 if (!System.IO.File.Exists(imagePath)) { System.IO.File.WriteAllBytes(imagePath, content); } } } } catch (Exception ex) { throw ex; } finally { if (table != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(table); } } } /// /// DataTable数据插入到MDB /// /// /// private void DataTableImportToMDB(DataTable dataTable, ITable table) { ICursor cursor = null; try { cursor = table.Insert(true); IRowBuffer rowBuffer = table.CreateRowBuffer(); int indexShape = table.FindField("Shape"); foreach (DataRow dr in dataTable.Rows) { foreach (DataColumn dc in dataTable.Columns) { int index = table.FindField(dc.ColumnName); if (index > -1 && !dc.ColumnName.Equals("shape", StringComparison.CurrentCultureIgnoreCase)) { if ((dr[dc.ColumnName] as byte[]) != null) { IMemoryBlobStream pMBS = new MemoryBlobStreamClass(); IMemoryBlobStreamVariant varBlobStream = (IMemoryBlobStreamVariant)pMBS; object objValue = dr[dc.ColumnName]; varBlobStream.ImportFromVariant(objValue); rowBuffer.set_Value(index, varBlobStream); } else { rowBuffer.set_Value(index, dr[dc.ColumnName]); } } //处理图形 if ((dc.ColumnName.EndsWith("geometry", StringComparison.CurrentCultureIgnoreCase) || dc.ColumnName.Equals("shape", StringComparison.CurrentCultureIgnoreCase)) && indexShape > -1 && !string.IsNullOrWhiteSpace(dr[dc.ColumnName] as string)) { IGeometry geometry = null; IFeatureClass featureClass = table as ESRI.ArcGIS.Geodatabase.IFeatureClass; if (featureClass != null) { switch (featureClass.ShapeType) { case esriGeometryType.esriGeometryPoint: geometry = ConverJsonToIGeoemtry(dr[dc.ColumnName] as string, esriGeometryType.esriGeometryPoint); break; case esriGeometryType.esriGeometryPolyline: geometry = ConverJsonToIGeoemtry(dr[dc.ColumnName] as string, esriGeometryType.esriGeometryPolyline); break; case esriGeometryType.esriGeometryPolygon: geometry = ConverJsonToIGeoemtry(dr[dc.ColumnName] as string); break; } } if (geometry != null) { geometry.Project((table as IGeoDataset).SpatialReference); rowBuffer.set_Value(indexShape, geometry); } } } cursor.InsertRow(rowBuffer); } cursor.Flush(); } catch (Exception ex) { throw ex; } finally { if (cursor != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(cursor); } } } /// /// 创建要素数据集 /// /// /// /// /// public static IFeatureDataset CreateFeatureDataset(IWorkspace workspace, string datasetName, ISpatialReference spatialReference) { try { IFeatureWorkspace featureWorkspace = (IFeatureWorkspace)workspace; ////确定是否支持高精度存储空间 //Boolean supportsHighPrecision = false; //IWorkspaceProperties workspaceProperties = (IWorkspaceProperties)workspace; //IWorkspaceProperty workspaceProperty = workspaceProperties.get_Property // (esriWorkspacePropertyGroupType.esriWorkspacePropertyGroup, // (int)esriWorkspacePropertyType.esriWorkspacePropSupportsHighPrecisionStorage); //if (workspaceProperty.IsSupported) //{ // supportsHighPrecision = Convert.ToBoolean(workspaceProperty.PropertyValue); //} ////设置投影精度 //IControlPrecision2 controlPrecision = (IControlPrecision2)spatialReference; //controlPrecision.IsHighPrecision = supportsHighPrecision; //设置容差 //ISpatialReferenceResolution spatialRefResolution = (ISpatialReferenceResolution)spatialReference; //spatialRefResolution.ConstructFromHorizon(); //spatialRefResolution.SetDefaultXYResolution(); //ISpatialReferenceTolerance spatialRefTolerance = (ISpatialReferenceTolerance)spatialReference; //spatialRefTolerance.SetDefaultXYTolerance(); //创建要素集 IFeatureDataset featureDataset = featureWorkspace.CreateFeatureDataset(datasetName, spatialReference); return featureDataset; } catch (Exception ex) { throw ex; } } /// /// 根据datatable创建矢量图层字段 /// /// /// 解压db /// private IFields GetFieldsByDataTable(DataTable dataTable, bool bgfw = false) { try { IFields fields = new FieldsClass(); IFieldsEdit pFieldsEdit = (IFieldsEdit)fields; foreach (DataColumn column in dataTable.Columns) { if (bgfw && (column.ColumnName.Equals("egeometry", StringComparison.CurrentCultureIgnoreCase) || column.ColumnName.Equals("pwd_shape", StringComparison.CurrentCultureIgnoreCase))) { continue; } if (column.ColumnName.Equals("shape", StringComparison.CurrentCultureIgnoreCase)) { continue; } IField pField = new FieldClass(); IFieldEdit pFieldEdit = (IFieldEdit)pField; if (!string.IsNullOrWhiteSpace(column.Caption)) { pFieldEdit.AliasName_2 = column.Caption; } if (column.DataType == typeof(string)) { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString; pFieldEdit.Length_2 = 999999999; } else if (column.DataType == typeof(int) || column.DataType == typeof(int?) || column.DataType == typeof(Int32) || column.DataType == typeof(Int32?) || column.DataType == typeof(Int64) || column.DataType == typeof(Int64?)) { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeInteger; } else if (column.DataType == typeof(float) || column.DataType == typeof(float) || column.DataType == typeof(double) || column.DataType == typeof(double?) || column.DataType == typeof(decimal) || column.DataType == typeof(decimal?)) { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDouble; } else if (column.DataType == typeof(DateTime) || column.DataType == typeof(DateTime?)) { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeDate; } else if (column.DataType == typeof(byte[])) { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeBlob; } else { pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString; pFieldEdit.Length_2 = 999999999; } pFieldEdit.Name_2 = column.ColumnName; if (!(column.DefaultValue is DBNull)) { pFieldEdit.DefaultValue_2 = column.DefaultValue; } else { pFieldEdit.DefaultValue_2 = DBNull.Value; } pFieldEdit.IsNullable_2 = column.AllowDBNull; if (column.ColumnName.ToLower().EndsWith("geometry") || column.ColumnName.ToLower().Equals("bz") || column.ColumnName.ToLower().Equals("pwd") || column.ColumnName.ToUpper().Equals("CHECK_CODE") || column.ColumnName.ToUpper().Equals("POINTS_JSON")) { pFieldEdit.Length_2 = 999999999; } //pFieldEdit.Precision_2 = column.; pFieldsEdit.AddField(pField); } return fields; } catch (Exception ex) { throw ex; } } /// /// 建立主要字段(OBJECTID和SHAPE) /// /// IFieldsEdit,把OBJECTID和SHAPE字段加进去 /// 空间参数 private static void CreateMainField(IFieldsEdit pFieldsEdit, ISpatialReference pSpatialReference, esriGeometryType pGeometryType = esriGeometryType.esriGeometryNull) { IField pField; IFieldEdit pFieldEdit; //建立OBJECTID字段 pField = new FieldClass(); pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "OBJECTID"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeOID; pFieldsEdit.AddField(pField); if (pGeometryType == esriGeometryType.esriGeometryNull) { return; } //建立shap字段 pField = new FieldClass(); pFieldEdit = pField as IFieldEdit; pFieldEdit.Name_2 = "SHAPE"; pFieldEdit.Type_2 = esriFieldType.esriFieldTypeGeometry; IGeometryDef pGeometryDef = new GeometryDefClass(); IGeometryDefEdit pGeometryDefEdit = pGeometryDef as IGeometryDefEdit; pGeometryDefEdit.GeometryType_2 = pGeometryType; pGeometryDefEdit.SpatialReference_2 = pSpatialReference; pFieldEdit.GeometryDef_2 = pGeometryDef; pFieldsEdit.AddField(pField); } /// /// 给指定工作空间中的对象设置空间参考 /// /// 工作空间 /// 空间参考对象 /// 数据库容差 private void SetGeoDatasetSpatialReference(IWorkspace pWS, ISpatialReference pSR, double pTolerance) { try { //double a = 0; //double b = 0; //double c = 0; //double d = 0; //pSR.SetDomain(-100000000, 0, 0, 0); //pSR.GetDomain(out a, out b, out c, out d); if (pSR != null) { ISpatialReferenceResolution toleranceResolution = pSR as ISpatialReferenceResolution; toleranceResolution.set_XYResolution(true, 0.00005); ISpatialReferenceTolerance tolerance = pSR as ISpatialReferenceTolerance; if (tolerance != null) { tolerance.XYTolerance = pTolerance; tolerance.ZTolerance = pTolerance; tolerance.MTolerance = pTolerance; } } IEnumDataset pEnumDataset = pWS.Datasets[esriDatasetType.esriDTFeatureDataset]; IDataset ds = null; if (pEnumDataset != null) { while ((ds = pEnumDataset.Next()) != null) { if (ds is IGeoDataset) { if ((ds as IGeoDataset).SpatialReference != pSR) (ds as IGeoDatasetSchemaEdit).AlterSpatialReference(pSR); } } } pEnumDataset = pWS.Datasets[esriDatasetType.esriDTFeatureClass]; if (pEnumDataset == null) { return; } while ((ds = pEnumDataset.Next()) != null) { if (ds is IGeoDataset) { if ((ds as IGeoDataset).SpatialReference != pSR) (ds as IGeoDatasetSchemaEdit).AlterSpatialReference(pSR); } } //设置坐标参考精度XYUnits 为二万分之一 try { pWS.ExecuteSQL(string.Format("UPDATE GDB_SpatialRefs SET XYUnits = 20000 ,XYTolerance = {0}", pTolerance)); //pWS.ExecuteSQL("UPDATE GDB_SpatialRefs SET FalseX=0,FalseY=0,XYUnits=100000,FalseZ=0,ZUnits=0,FalseM=0,MUnits=0,XYTolerance=0.0001,ZTolerance=0,MTolerance=0"); } catch (Exception ex) { throw new Exception("设置坐标参考坐标精度和容差异常:" + ex.Message); } } catch (Exception ex) { throw ex; } } /// /// 创建本地工作空间 /// /// 文件路径 /// private IWorkspace CreateLocalWorkspace(string pPath, ref IFeatureDataset featureDataset, string featureDatasetName = "TDBZSJJ", int wkid = -1, double tolerance = 0.0001) { IWorkspace workspace = null; try { string gdbExtention = System.IO.Path.GetExtension(pPath).ToLower(); switch (gdbExtention) { case ".gdb": if (System.IO.Directory.Exists(pPath)) { throw new Exception("创建GDB失败:" + pPath + "已存在!"); } workspace = CreateWorkspace(pPath); break; case ".mdb": if (System.IO.File.Exists(pPath)) { throw new Exception("创建MDB失败:" + pPath + "已存在!"); } workspace = CreateWorkspace(pPath); break; default: return null; } //wsFactory = new FileGDBWorkspaceFactoryClass(); //workspace = wsFactory.OpenFromFile(saveGDBPath, 0); if (!string.IsNullOrWhiteSpace(featureDatasetName)) { ISpatialReference spatialReference = CreteSpatialReference(wkid); SetGeoDatasetSpatialReference(workspace, spatialReference, tolerance); try { featureDataset = (workspace as IFeatureWorkspace).OpenFeatureDataset(featureDatasetName); } catch { featureDataset = CreateFeatureDataset(workspace, featureDatasetName, spatialReference); } } } catch (Exception ex) { throw ex; } return workspace; } /// /// 创建本地工作空间 /// /// 工作空间类型 /// 文件路径 /// IWorkspace private static IWorkspace CreateWorkspace(string pPath) where T : IWorkspaceFactory, new() { if (string.IsNullOrEmpty(pPath)) { return null; } try { string sDirName = System.IO.Path.GetDirectoryName(pPath); string sFileName = System.IO.Path.GetFileName(pPath); IWorkspaceName pWorkspaceName = new T().Create(sDirName, sFileName, null, 0); if (pWorkspaceName == null) { return null; } return (pWorkspaceName as IName).Open() as IWorkspace; } catch (Exception ex) { throw ex; } } /// /// JSON图图形转IGeometry /// /// 图形串 /// 图形类型:点,线、面 /// 输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形 /// 是地理坐标参考 /// private IGeometry ConverJsonToIGeoemtry(string jsonGeometry, esriGeometryType geometryType = esriGeometryType.esriGeometryPolygon, int wkid = 4490) { try { using (ESRI.ArcGIS.ADF.ComReleaser comReleaser = new ESRI.ArcGIS.ADF.ComReleaser()) { IJSONReader reader = new ESRI.ArcGIS.esriSystem.JSONReaderClass(); comReleaser.ManageLifetime(reader); reader.ReadFromString(jsonGeometry); JSONConverterGeometryClass jsonConverter = new JSONConverterGeometryClass(); comReleaser.ManageLifetime(jsonConverter); IGeometry geometry = jsonConverter.ReadGeometry(reader, geometryType, false, false); if (geometry == null || geometry.IsEmpty) { throw new Exception("转换后图形为空!"); } //此处发现湖南抽取过来的图形Simplify之后图形变化较大,会删除节点,所以湖南暂时不执行图形简化操作 if (!SysConfigsOprator.GetAppsetingValueByKey("ArearName").Equals("43")) { ESRI.ArcGIS.Geometry.ITopologicalOperator topological = geometry as ESRI.ArcGIS.Geometry.ITopologicalOperator; if (!topological.IsSimple) { topological.Simplify(); } } ISpatialReference spatialReference = CreteSpatialReference(wkid); if (wkid > 0) { if (geometry.SpatialReference == null) { geometry.SpatialReference = spatialReference; } else if (wkid != geometry.SpatialReference.FactoryCode) { geometry.Project(spatialReference); } } return geometry; } } catch (Exception ex) { throw ex; } } private static ISpatialReference CreteSpatialReference(int WKID) { ISpatialReference spatialReference = null; ISpatialReferenceFactory2 pSpatialRefFac = null; try { pSpatialRefFac = new SpatialReferenceEnvironmentClass(); try { spatialReference = pSpatialRefFac.CreateGeographicCoordinateSystem(WKID); } catch { spatialReference = pSpatialRefFac.CreateProjectedCoordinateSystem(WKID); } return spatialReference; } catch (Exception ex) { throw ex; } finally { if (pSpatialRefFac != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(pSpatialRefFac); } } } /// /// 对称解密 /// private static string SM4Decrypt(string txtWord, string key) { try { //if (string.IsNullOrWhiteSpace(PubKeySM2)) //{ // PrvKeySM4 = KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM4K"); //} SM4 sm4 = new SM4(); sm4.secretKey = key; sm4.hexString = true; return sm4.DecryptECB(txtWord); } catch (Exception ex) { throw ex; } } } }