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

1068 lines
47 KiB

using ESRI.ArcGIS.DataSourcesGDB;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using Kingo.Crypto;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Kingo.RuleCheck.CheckHelper
{
public class DBToMDBHelper
{
/// <summary>
/// db路径
/// </summary>
private string DBPath { get; set; }
/// <summary>
/// 省级解密DB包
/// </summary>
/// <param name="dbPath"></param>
/// <param name="SM2PrivateKey"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public DataTable SJDecryptDB(string dbPath, string SM2PrivateKey,out string tempDBPath)
{
if (string.IsNullOrWhiteSpace(dbPath))
{
throw new Exception("DBPath参数为空,无法转换!");
}
string tempFolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(dbPath), "质检文件夹");
if (!System.IO.Directory.Exists(tempFolder))
{
System.IO.Directory.CreateDirectory(tempFolder);
}
try
{
string[] files = System.IO.Directory.GetFiles(tempFolder, "*.*");
if (files != null)
{
foreach (var item in files)
{
System.IO.File.Delete(item);
}
}
}
catch
{
}
tempDBPath = System.IO.Path.Combine(tempFolder, System.IO.Path.GetFileNameWithoutExtension(dbPath) + "_checkTemp.db");
System.IO.File.Copy(dbPath, tempDBPath, true);
this.DBPath = tempDBPath;
DataTable dataTable = ExecuteDataTable("SELECT WKID,Encrypted,pwd FROM ysj");
string sfjm = dataTable.Rows[0][1].ToString();
if (sfjm == "1")
{
if (dataTable.Rows[0][2] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中加密字段(Encrypted)为1,标识是加密包,但Pwd(密码字段)为空!");
}
string pwd = dataTable.Rows[0][2].ToString();
if (string.IsNullOrWhiteSpace(SM2PrivateKey))
{
throw new Exception("db包是加密包,但非对称加密私钥(SM2PrivateKey)参数为空!");
}
DecryptDB(System.Text.Encoding.UTF8.GetString(Kingo.Crypto.SM2.Decrypt(SM2PrivateKey, pwd)));
}
return ExecuteDataTable("select tbbsm from wyrw where fwy<>1 or fwy is null");
}
/// <summary>
/// 将DB矢量化为单个MDB(预处理时只矢量化一个mdb)
/// </summary>
/// <param name="dbPath">需要矢量化的DB文件路径</param>
/// <param name="dbKey">如果db存在密码,则将密码传输过来</param>
/// <param name="saveMDBPath">矢量化后MDB文件路径(可选参数)</param>
/// <param name="tolerance">坐标参考容差:默认0.0001</param>
/// <returns>矢量化后MDB文件路径</returns>
public string DBToSingleMdb(string dbPath, string SM2PrivateKey = "", string dbKey = "", string saveMDBPath = "", double tolerance = 0.0001)
{
IWorkspaceFactory2 wsFactory = null;
IWorkspace workspace = null;
try
{
if (string.IsNullOrWhiteSpace(dbPath))
{
throw new Exception("DBPath参数为空,无法转换!");
}
string tempFolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(dbPath), "质检文件夹");
if (!System.IO.Directory.Exists(tempFolder))
{
System.IO.Directory.CreateDirectory(tempFolder);
}
try
{
string[] files = System.IO.Directory.GetFiles(tempFolder, "*.*");
if (files != null)
{
foreach (var item in files)
{
System.IO.File.Delete(item);
}
}
}
catch
{
}
string tempDBPath = System.IO.Path.Combine(tempFolder, System.IO.Path.GetFileNameWithoutExtension(dbPath) + "_checkTemp.db");
System.IO.File.Copy(dbPath, tempDBPath, true);
this.DBPath = tempDBPath;
if (string.IsNullOrWhiteSpace(saveMDBPath))
{
saveMDBPath = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + ".mdb");
CreateLocalWorkspace(saveMDBPath);
}
//System.IO.File.Copy(tempMDB, saveMDBPath, true);
DataTable hasTable = ExecuteDataTable("SELECT name FROM sqlite_master WHERE type = 'table' and name<>'sqlite_sequence' ORDER BY name;");
if (hasTable == null || hasTable.Rows.Count <= 0)
{
return saveMDBPath;
//throw new Exception("db文件数据为空!");
}
DataTable dataTable = ExecuteDataTable("SELECT WKID,Encrypted,pwd FROM ysj");
if (dataTable == null || dataTable.Rows.Count <= 0)
{
throw new Exception("db包元数据(YSJ)表为空,无法获取矢量化必要的坐标参考WKID!");
}
if (dataTable.Rows[0][0] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中WKID坐标参考为空!");
}
string wkidStr = dataTable.Rows[0][0].ToString();
if (string.IsNullOrWhiteSpace(wkidStr) || wkidStr.Equals("0"))
{
throw new Exception("db包元数据(YSJ)表中WKID坐标参考为空!");
}
if (dataTable.Rows[0][1] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中是否加密字段(Encrypted)为空!");
}
string sfjm = dataTable.Rows[0][1].ToString();
if (sfjm == "1")
{
if (dataTable.Rows[0][2] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中加密字段(Encrypted)为1,标识是加密包,但Pwd(密码字段)为空!");
}
string pwd = dataTable.Rows[0][2].ToString();
if (string.IsNullOrWhiteSpace(SM2PrivateKey))
{
throw new Exception("db包是加密包,但非对称加密私钥(SM2PrivateKey)参数为空!");
}
DecryptDB(System.Text.Encoding.UTF8.GetString(Kingo.Crypto.SM2.Decrypt(SM2PrivateKey, pwd)));
}
wsFactory = new AccessWorkspaceFactoryClass();
workspace = wsFactory.OpenFromFile(saveMDBPath, 0);
IProjectedCoordinateSystem spatialReference = GeometryConvertHelper.CreateProjectedCoordinateSystem(int.Parse(wkidStr));
IFeatureDataset featureDataset = null;
try
{
featureDataset = (workspace as IFeatureWorkspace).OpenFeatureDataset("TDBZSJJ");
}
catch
{
featureDataset = CreateFeatureDataset(workspace, "TDBZSJJ", spatialReference);
}
SetGeoDatasetSpatialReference(workspace, spatialReference, tolerance);
//设置坐标参考精度XYUnits 为二万分之一
try
{
workspace.ExecuteSQL(string.Format("UPDATE GDB_SpatialRefs SET XYUnits = 20000 ,XYTolerance = {0}", tolerance));
}
catch
{
}
foreach (DataRow dr in hasTable.Rows)
{
CreateFeatureClassAndImportData(featureDataset, dr[0] as string, dbKey);
}
return saveMDBPath;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (workspace != null)
{
try
{
IDatabaseCompact databaseCompact = workspace as IDatabaseCompact;
databaseCompact.Compact();
}
catch
{
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace);
}
if (wsFactory != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(wsFactory);
}
}
}
/// <summary>
/// 将DB根据外业任务图斑图层矢量化为多个MDB
/// </summary>
/// <param name="dbPath">需要矢量化的DB文件路径</param>
/// <param name="dbPath">需要矢量化的DB文件路径</param>
/// <param name="sProcessDataPath">过程数据文件</param>
/// <param name="dbKey">如果db存在密码,则将密码传输过来</param>
/// <param name="saveMDBPath">矢量化后MDB文件路径(可选参数)</param>
/// <param name="tolerance">坐标参考容差:默认0.0001</param>
/// <returns>矢量化后MDB文件路径</returns>
public List<string> DBToMdb(string dbPath, out string sProcessDataPath, string SM2PrivateKey = "", string dbKey = "", string saveMDBPath = "", double tolerance = 0.0001)
{
List<string> mdbList = new List<string>();
if (string.IsNullOrWhiteSpace(dbPath))
{
throw new Exception("DBPath参数为空,无法转换!");
}
string tempFolder = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(dbPath), "质检文件夹");
//过程数据路径
sProcessDataPath = System.IO.Path.Combine(tempFolder, DateTime.Now.ToString("yyyyMMddHHmmss") + $".mdb");
if (!System.IO.Directory.Exists(tempFolder))
{
System.IO.Directory.CreateDirectory(tempFolder);
}
try
{
string[] files = System.IO.Directory.GetFiles(tempFolder, "*.*");
if (files != null)
{
foreach (var item in files)
{
System.IO.File.Delete(item);
}
}
}
catch
{
}
string tempDBPath = System.IO.Path.Combine(tempFolder, System.IO.Path.GetFileNameWithoutExtension(dbPath) + "_checkTemp.db");
System.IO.File.Copy(dbPath, tempDBPath, true);
this.DBPath = tempDBPath;
DataTable dataTable = ExecuteDataTable("SELECT WKID,Encrypted,pwd FROM ysj");
if (dataTable == null || dataTable.Rows.Count <= 0)
{
throw new Exception("db包元数据(YSJ)表为空,无法获取矢量化必要的坐标参考WKID!");
}
if (dataTable.Rows[0][0] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中WKID坐标参考为空!");
}
string wkidStr = dataTable.Rows[0][0].ToString();
if (string.IsNullOrWhiteSpace(wkidStr) || wkidStr.Equals("0"))
{
throw new Exception("db包元数据(YSJ)表中WKID坐标参考为空!");
}
if (dataTable.Rows[0][1] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中是否加密字段(Encrypted)为空!");
}
string sfjm = dataTable.Rows[0][1].ToString();
if (sfjm == "1")
{
if (dataTable.Rows[0][2] is DBNull)
{
throw new Exception("db包元数据(YSJ)表中加密字段(Encrypted)为1,标识是加密包,但Pwd(密码字段)为空!");
}
string pwd = dataTable.Rows[0][2].ToString();
if (string.IsNullOrWhiteSpace(SM2PrivateKey))
{
throw new Exception("db包是加密包,但非对称加密私钥(SM2PrivateKey)参数为空!");
}
DecryptDB(System.Text.Encoding.UTF8.GetString(Kingo.Crypto.SM2.Decrypt(SM2PrivateKey, pwd)));
}
DataTable hasTable = ExecuteDataTable("SELECT name FROM sqlite_master WHERE type = 'table' and name<>'sqlite_sequence' ORDER BY name;");
if (hasTable == null || hasTable.Rows.Count <= 0)
{
return mdbList;
}
DataTable wyrwTable = ExecuteDataTable("select tbbsm from wyrw where fwy<>1 or fwy is null;");
if (wyrwTable == null || wyrwTable.Rows.Count <= 0)
{
return mdbList;
}
foreach (DataRow item in wyrwTable.Rows)
{
string tbbsm = item["tbbsm"].ToString();
//if (string.IsNullOrWhiteSpace(saveMDBPath))
//{
saveMDBPath = System.IO.Path.Combine(tempFolder, Guid.NewGuid().ToString().Replace("-", "") + $"_{tbbsm}.mdb");
//}
string mdbPath = DBToMdb(dbPath, tbbsm, tempFolder, hasTable, wkidStr, SM2PrivateKey, dbKey, saveMDBPath, sProcessDataPath, tolerance);
mdbList.Add(mdbPath);
}
return mdbList;
}
/// <summary>
/// 生成参考图层
/// </summary>
/// <param name="dicReferenceData">辅助数据</param>
/// <param name="sProcessDataPath"></param>
public void CreateProcessData(Dictionary<string, string> dicReferenceData, string sProcessDataPath)
{
IFeatureClass featureClass = null;
try
{
if (!dicReferenceData.ContainsKey("JCK_DLTB"))
throw new Exception("未检测到参考数据,基础库DLTB");
string sBaseDataPath = dicReferenceData["JCK_DLTB"];
if (!dicReferenceData.ContainsKey("PDT"))
throw new Exception("未检测到参考数据,坡度图");
string sPDTPath = dicReferenceData["PDT"];
if (!dicReferenceData.ContainsKey("LNGD"))
throw new Exception("未检测到参考数据,历年耕地");
string sLNGDPath = dicReferenceData["LNGD"];
GeoprocessorHelper.FeatureClassToFeatureClass(sBaseDataPath, sProcessDataPath, "DLTB", ref featureClass, false);
GeoprocessorHelper.FeatureClassToFeatureClass(sLNGDPath, sProcessDataPath, "LNGD", ref featureClass, false);
GeoprocessorHelper.FeatureClassToFeatureClass(sPDTPath, sProcessDataPath, "PDT", ref featureClass, false);
//DTBDLTBGX与基础库叠加
GeoprocessorHelper.IntersectAnalysis(new List<string> { $"{sProcessDataPath}\\DTBDLTBGX", $"{sProcessDataPath}\\DLTB" }, $"{sProcessDataPath}\\Inter", ref featureClass, false);
#region 生成N图层 提取->擦除
GeoprocessorHelper.SelectAnalysis($"{sProcessDataPath}\\DLTB", $"{sProcessDataPath}\\JCK_N", "bsm in (select bsm_1 from Inter)", ref featureClass, false);
GeoprocessorHelper.EraseAnalysis($"{sProcessDataPath}\\JCK_N", $"{sProcessDataPath}\\DTBDLTBGX", $"{sProcessDataPath}\\Erase_N", ref featureClass, false);
GeoprocessorHelper.MultipartToSinglepart($"{sProcessDataPath}\\Erase_N", $"{sProcessDataPath}\\N", ref featureClass, true);
//生成五要素
GenerateAttributeHelper.CheckExtFiled(featureClass);
GenerateAttributeHelper.SetFeatureAttribute(featureClass);
#endregion
#region LNGD_R 叠加
GeoprocessorHelper.IntersectAnalysis(new List<string> { $"{sProcessDataPath}\\Inter", $"{sProcessDataPath}\\LNGD" }, $"{sProcessDataPath}\\LNGD_R", ref featureClass, false);
#endregion
#region HFSX_R 叠加
GeoprocessorHelper.IntersectAnalysis(new List<string> { $"{sProcessDataPath}\\Inter", $"{sProcessDataPath}\\PDT" }, $"{sProcessDataPath}\\HFSX_R", ref featureClass, false);
#endregion
}
catch (Exception ex)
{
throw new Exception("生成单图斑建库N图层异常:" + ex.Message);
}
finally
{
if (featureClass != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(featureClass);
}
}
}
/// <summary>
/// 将DB矢量化为MDB
/// </summary>
/// <param name="dbPath">需要矢量化的DB文件路径</param>
/// <param name="dbKey">如果db存在密码,则将密码传输过来</param>
/// <param name="saveMDBPath">矢量化后MDB文件路径(可选参数)</param>
/// <param name="sProcessDataPath">过程数据路径</param>
/// <param name="tolerance">坐标参考容差:默认0.0001</param>
/// <returns>矢量化后MDB文件路径</returns>
private string DBToMdb(string dbPath, string tbbsm, string tempFolder, DataTable hasTable, string wkidStr, string SM2PrivateKey = "", string dbKey = "", string saveMDBPath = "", string sProcessDataPath = "", double tolerance = 0.0001)
{
IWorkspaceFactory2 wsFactory = null;
IWorkspace workspace = null;
try
{
CreateLocalWorkspace(saveMDBPath);
wsFactory = new AccessWorkspaceFactoryClass();
workspace = wsFactory.OpenFromFile(saveMDBPath, 0);
IProjectedCoordinateSystem spatialReference = GeometryConvertHelper.CreateProjectedCoordinateSystem(int.Parse(wkidStr));
IFeatureDataset featureDataset = null;
try
{
featureDataset = (workspace as IFeatureWorkspace).OpenFeatureDataset("TDBZSJJ");
}
catch
{
featureDataset = CreateFeatureDataset(workspace, "TDBZSJJ", spatialReference);
}
SetGeoDatasetSpatialReference(workspace, spatialReference, tolerance);
//设置坐标参考精度XYUnits 为二万分之一
try
{
workspace.ExecuteSQL(string.Format("UPDATE GDB_SpatialRefs SET XYUnits = 20000 ,XYTolerance = {0}", tolerance));
}
catch
{
}
foreach (DataRow dr in hasTable.Rows)
{
string tableName = dr[0].ToString().ToUpper();
string whereSql = "";
if (tableName == "DTBDLTBGX" || tableName == "GJFKJG" || tableName == "LABEL" || tableName == "NYYSRESULT" || tableName == "RETURNCOMMENTS" || tableName == "SJSHBZ" || tableName == "WYSKETCH" || tableName == "DTBDLTBGXGC" || tableName == "WYRW")
{
whereSql = $" where tbbsm='{tbbsm}'";
}
else if (tableName == "WYHCCG")
{
whereSql = $" where hcrwbsm='{tbbsm}'";
}
else if (tableName == "WYHCFJ")
{
whereSql = $" where hcjlbsm='{tbbsm}'";
}
else if (tableName == "FJGX")
{
whereSql = $" where tbbsm in (select bsm from DTBDLTBGX where tbbsm ='{tbbsm}')";
}
else if (tableName == "DTBCCWJQGX" || tableName == "DTBCZCDYDGX" || tableName == "DTBGFBQGX" || tableName == "DTBLMFWGX" || tableName == "DTBLSYDGX" || tableName == "DTBTTQGX" || tableName == "PZWJ")
{
whereSql = $" where bsm in (select bsm from DTBDLTBGX where tbbsm ='{tbbsm}')";
}
CreateFeatureClassAndImportData(featureDataset, dr[0] as string, dbKey, whereSql, sProcessDataPath);
}
return saveMDBPath;
}
catch (Exception ex)
{
throw ex;
}
finally
{
if (workspace != null)
{
try
{
IDatabaseCompact databaseCompact = workspace as IDatabaseCompact;
databaseCompact.Compact();
}
catch
{
}
System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace);
}
if (wsFactory != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(wsFactory);
}
}
}
/// <summary>
/// 解密db
/// </summary>
/// <param name="dbPath"></param>
/// <param name="sm4PrivateKey">对称加密秘钥</param>
private void DecryptDB(string sm4PrivateKey, string dbKey = "")
{
try
{
List<string> listTableName = new List<string>() { "dtbdltbgx", "wyrw" , "DTBDLTBGXGC" };
foreach (var item in listTableName)
{
DataTable dataTable = ExecuteDataTable($"select bsm,egeometry from {item}", null, dbKey);
if (dataTable == null || dataTable.Rows.Count <= 0)
{
return;
}
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 = GeometryConvertHelper.ConverJsonToIGeoemtry(geometryStr);
}
catch
{
throw ex;
}
}
ExecuteSQL(string.Format(excuteSQL, geometryStr, dataRow["bsm"], item), dbKey);
}
}
ExecuteSQL("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>
/// <param name="sProcessDataPath"></param>
private void CreateFeatureClassAndImportData(IFeatureDataset featureDataset, string tableName, string dbKey = "", string whereSql = "", string sProcessDataPath = "")
{
ITable table = null;
try
{
DataTable dataTable = ExecuteDataTable($"select * from {tableName} {whereSql}", null, dbKey);
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 "wyhccg":
case "wyhcfj":
case "fjgx":
//创建必要字段OBJECTID,SHAPE
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, "");
}
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);
table.DeleteSearchedRows(null);
}
catch
{
table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable;
}
break;
//case "wysketch"://预处理指导草图
// //创建必要字段OBJECTID,SHAPE
// CreateMainField(fields as IFieldsEdit, esriGeometryType.esriGeometryPolygon, null);
// break;
//case "sjshbz"://省级审核标注
// Dictionary<string, string> dciBZTable = new Dictionary<string, string>();
// dciBZTable.Add("点", "SHBZPoint");
// dciBZTable.Add("线", "SHBZLine");
// dciBZTable.Add("面", "SHBZPolygon");
// foreach (var item in dciBZTable)
// {
// //创建必要字段OBJECTID,SHAPE
// CreateMainField(fields as IFieldsEdit, esriGeometryType.esriGeometryPolygon, null);
// table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable;
// dataTable = ExecuteDataTable($"select * from {tableName}", null, dbKey);
// if (dataTable.Rows.Count <= 0)
// {
// return;
// }
// DataTableImportToMDB(dataTable, table);
// }
// break;
//case "label"://外业草图
// //创建必要字段OBJECTID,SHAPE
// CreateMainField(fields as IFieldsEdit, esriGeometryType.esriGeometryPolygon, null);
// table = featureDataset.CreateFeatureClass(tableName, fields, null, null, esriFeatureType.esriFTSimple, "Shape", "") as ITable;
// break;
default:
return;
}
//dataTable = ExecuteDataTable($"select * from {tableName}", null, dbKey);
//if (dataTable.Rows.Count <= 0)
//{
// return;
//}
DataTableImportToMDB(dataTable, table);
//单图斑地类图斑更新层生成五要素
if (table != null && tableName.Equals("dtbdltbgx", StringComparison.CurrentCultureIgnoreCase))
{
GenerateAttributeHelper.CheckExtFiled(table as IFeatureClass);
GenerateAttributeHelper.SetFeatureAttribute(table as IFeatureClass);
//合并单图斑地类图斑更新层
if (System.IO.File.Exists(sProcessDataPath))
{
IWorkspaceFactory2 wsFactory = new AccessWorkspaceFactoryClass();
IWorkspace workspace = wsFactory.OpenFromFile(sProcessDataPath, 0);
ITable pTable = (workspace as IFeatureWorkspace).OpenTable("DTBDLTBGX");
DataTableImportToMDB(dataTable, pTable);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pTable);
System.Runtime.InteropServices.Marshal.ReleaseComObject(workspace);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wsFactory);
}
else
System.IO.File.Copy(featureDataset.Workspace.PathName, sProcessDataPath);
}
}
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)
{
rowBuffer.set_Value(index, dr[dc.ColumnName]);
}
//处理图形
if (dc.ColumnName.EndsWith("geometry", 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 = GeometryConvertHelper.ConverJsonToIGeoemtry(dr[dc.ColumnName] as string, esriGeometryType.esriGeometryPoint);
break;
case esriGeometryType.esriGeometryPolyline:
geometry = GeometryConvertHelper.ConverJsonToIGeoemtry(dr[dc.ColumnName] as string, esriGeometryType.esriGeometryPolyline);
break;
case esriGeometryType.esriGeometryPolygon:
geometry = GeometryConvertHelper.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, IProjectedCoordinateSystem 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>
/// <returns></returns>
private IFields GetFieldsByDataTable(DataTable dataTable)
{
try
{
IFields fields = new FieldsClass();
IFieldsEdit pFieldsEdit = (IFieldsEdit)fields;
foreach (DataColumn column in dataTable.Columns)
{
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;
}
else if (column.DataType == typeof(int) || column.DataType == typeof(int?))
{
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
{
pFieldEdit.Type_2 = esriFieldType.esriFieldTypeString;
}
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.ToUpper().Equals("CHECK_CODE") ||
column.ColumnName.ToUpper().Equals("POINTS_JSON"))
{
pFieldEdit.Length_2 = column.MaxLength;
}
//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="sql">查询语句</param>
/// <param name="parameters">参数</param>
/// <returns></returns>
private DataTable ExecuteDataTable(string sql, SQLiteParameter[] parameters = null, string keyCode = "")
{
try
{
using (SQLiteConnection connection = new SQLiteConnection("Data Source=" + this.DBPath))
{
using (SQLiteCommand command = new SQLiteCommand(sql, connection))
{
if (parameters != null)
{
command.Parameters.AddRange(parameters);
}
SQLiteDataAdapter adapter = new SQLiteDataAdapter(command);
DataTable data = new DataTable();
try
{
adapter.Fill(data);
}
catch
{
if (!string.IsNullOrWhiteSpace(keyCode))
connection.SetPassword(keyCode);
adapter.Fill(data);
}
return data;
}
}
}
catch (Exception ex)
{
throw new Exception("无法数据包:" + ex.Message);
}
}
/// <summary>
/// DB执行SQL
/// </summary>
/// <param name="sql"></param>
/// <param name="dbPath"></param>
/// <returns></returns>
private bool ExecuteSQL(string sql, string keyCode)
{
using (SQLiteConnection conn = new SQLiteConnection("Data Source=" + this.DBPath))
{
if (!string.IsNullOrWhiteSpace(keyCode))
{
conn.SetPassword(keyCode);
}
conn.Open();
using (SQLiteCommand cmd = new SQLiteCommand(conn))
{
try
{
cmd.CommandText = sql;
cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
}
conn.Close();
}
return true;
}
/// <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 static IWorkspace CreateLocalWorkspace(string pPath)
{
string gdbExtention = System.IO.Path.GetExtension(pPath).ToLower();
switch (gdbExtention)
{
case ".gdb":
return CreateWorkspace<FileGDBWorkspaceFactoryClass>(pPath);
case ".mdb":
return CreateWorkspace<AccessWorkspaceFactoryClass>(pPath);
default:
return null;
}
}
/// <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>
/// 对称解密
/// </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;
}
}
}
}