年度变更建库软件5.0版本
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.

1393 lines
66 KiB

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 Kingo.PluginServiceInterface;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
namespace Kingo.Plugin.DTBJK.Helper
{
public class DecompressionDB
{
/// <summary>
/// 将多个db合并输出到gdb中
/// </summary>
public void MultDBToGDB(List<Kingo.PluginServiceInterface.Model.ExportEntity> 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<string> exportTables = new List<string>() { "WYRW", "DTBDLTBGX" };
foreach (IGrouping<string, Kingo.PluginServiceInterface.Model.ExportEntity> group in groupValue)
{
List<Kingo.PluginServiceInterface.Model.ExportEntity> 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
{
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=''");
}
}
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);
}
}
}
/// <summary>
/// 将多个db合并输出到gdb中
/// </summary>
public void MultDBToGDB(Dictionary<string, string> 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);
}
}
}
/// <summary>
/// 将DB矢量化为GDB
/// </summary>
/// <param name="dbPath">需要矢量化的DB文件路径</param>
/// <param name="dbKey">如果db存在密码,则将密码传输过来</param>
/// <param name="saveGDBPath">矢量化后MDB文件路径(可选参数)</param>
/// <param name="tolerance">坐标参考容差:默认0.0001</param>
/// <returns>矢量化后MDB文件路径</returns>
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, 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);
}
rdbHelper = RDBFactory.CreateDbHelper(dbPath, DatabaseType.SQLite);
//saveGDBPath = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + ".mdb");
List<string> lst = new List<string>() { "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)
{
GaussCalculateLibrary.CoordinateReferenceMapping coordinateReferenceMapping = GaussCalculateLibrary.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);
}
}
}
/// <summary>
/// 解密db
/// </summary>
/// <param name="dbPath"></param>
/// <param name="sm4PrivateKey">对称加密秘钥</param>
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<string> listTableName = new List<string>();
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<string>() { "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);
}
}
/// <summary>
/// 创建要素类并导入数据
/// </summary>
/// <param name="featureDataset"></param>
/// <param name="tableName"></param>
/// <param name="dbKey"></param>
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<string, string> dciBZTable = new Dictionary<string, string>();
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<string, string>();
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<int, string> dciBZTable1 = new Dictionary<int, string>();
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);
}
}
}
/// <summary>
/// DataTable数据插入到MDB
/// </summary>
/// <param name="dataTable"></param>
/// <param name="featureClassAPI"></param>
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);
}
}
}
/// <summary>
/// 创建要素数据集
/// </summary>
/// <param name="workspace"></param>
/// <param name="code"></param>
/// <param name="datasetName"></param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 根据datatable创建矢量图层字段
/// </summary>
/// <param name="dataTable"></param>
/// <param name="decompressionDB">解压db</param>
/// <returns></returns>
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;
}
}
/// <summary>
/// 建立主要字段(OBJECTID和SHAPE)
/// </summary>
/// <param name="pFieldsEdit">IFieldsEdit,把OBJECTID和SHAPE字段加进去</param>
/// <param name="pSpatialReference">空间参数</param>
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);
}
/// <summary>
/// 给指定工作空间中的对象设置空间参考
/// </summary>
/// <param name="pWS">工作空间</param>
/// <param name="pSR">空间参考对象</param>
/// <param name="pTolerance">数据库容差</param>
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;
}
}
/// <summary>
/// 创建本地工作空间
/// </summary>
/// <param name="pPath">文件路径</param>
/// <returns></returns>
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<FileGDBWorkspaceFactoryClass>(pPath);
break;
case ".mdb":
if (System.IO.File.Exists(pPath))
{
throw new Exception("创建MDB失败:" + pPath + "已存在!");
}
workspace = CreateWorkspace<AccessWorkspaceFactoryClass>(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;
}
/// <summary>
/// 创建本地工作空间
/// </summary>
/// <typeparam name="T">工作空间类型</typeparam>
/// <param name="pPath">文件路径</param>
/// <returns>IWorkspace</returns>
private static IWorkspace CreateWorkspace<T>(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;
}
}
/// <summary>
/// JSON图图形转IGeometry
/// </summary>
/// <param name="jsonGeometry">图形串</param>
/// <param name="geometryType">图形类型:点,线、面</param>
/// <param name="wkid">输出图形坐标参考wkid,4490:CGCS2000球面坐标参考,默认输出CGCS2000球面坐标参考的json图形</param>
/// <param name="isGeograhicCoordinateSystem">是地理坐标参考</param>
/// <returns></returns>
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);
}
}
}
/// <summary>
/// 对称解密
/// </summary>
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;
}
}
}
}