using ESRI.ArcGIS.Geodatabase; using KGIS.Framework.AE; using KGIS.Framework.Maps; using KGIS.Framework.Utils; using KGIS.Framework.Utils.ExtensionMethod; using Kingo.PluginServiceInterface.Model; using Kingo.ThreadManager; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; namespace Kingo.Plugin.DLTB_IDG { public class ProcesHelper { public static ProcesHelper Instance { get; } = new ProcesHelper(); private ProcesHelper() { } public Action ProgressHandle { get; set; } public string ExeGPForProces(string arg, string exeName = "IDGForNDBG.exe") { Byte[] toEncryptArray = Encoding.UTF8.GetBytes(arg); string strParm = Convert.ToBase64String(toEncryptArray); var psi = new ProcessStartInfo(exeName, strParm); psi.UseShellExecute = false; psi.CreateNoWindow = true; psi.RedirectStandardError = true; psi.RedirectStandardInput = true; psi.RedirectStandardOutput = true; var pes = Process.Start(psi); var sbuffer = new StringBuilder(); var sout = pes.StandardOutput; while (!sout.EndOfStream) { var line = sout.ReadLine(); if (String.IsNullOrEmpty(line)) continue; sbuffer.AppendLine(line); if (line.StartsWith("Msg:")) ProgressHandle?.Invoke(line.Replace("Msg:", "")); else { LogAPI.Debug(line); } } pes.WaitForExit(); pes.Close(); String res = sbuffer.ToString(); sbuffer.Clear(); return res; } string outPath = string.Empty; public string ExeGPForProces(IDGParameter gPParam) { string result = string.Empty; try { string strParm = SerializeAPI.SerializeToXML(gPParam); result = ExeGPForProces(strParm); } catch (Exception ex) { result = ex.Message; Console.WriteLine(result); Console.WriteLine(ex.Message); } return result; } public ThreadManager2 ThreadPool = new ThreadManager2(); public void MuitProcessAnalyssis(BaseAnalysisData pCfg) { DateTime StartTime = DateTime.Now; string resultDBPath = string.Empty; try { if (pCfg.TaskList == null) return; foreach (var TaskData in pCfg.TaskList) { if (!AnalyProgress.ContainsKey(TaskData.Code)) AnalyProgress.Add(TaskData.Code, new ProgressModel()); if (TaskData == null) throw new Exception("参数中未指定任务图层!"); IFeatureClass featureClass = MapsManager.Instance.MapService.GetFeatureClassByName("DLTBGX"); int DataCount = featureClass.FeatureCount(null); int subTaskNum = 0; string relTables = string.Join(",", pCfg.RelDataList.Select(x => x.TCMC)); foreach (var relData in pCfg.RelDataList) { if (!relData.SFFX || relData.XZQDM != TaskData.XZQDM) continue; if (string.IsNullOrWhiteSpace(relData.SJLJ)) { pCfg.Message += "未指定图层【" + relData.TCMC + "】的图层路径!"; continue; } subTaskNum++; } int TaskCount = (ProcessManager.Instance.MaxThreadNum) / pCfg.TaskList.Length; if (TaskCount == 0) TaskCount = 1; int f = (int)DataCount / TaskCount; int s = (int)DataCount % TaskCount; int StartIdx = 0; int EndIdx = f; for (int i = 0; i < TaskCount; i++) { StartIdx = i * f; if (i == TaskCount - 1) { f = f + s; } EndIdx = f * (i + 1) - 1; if (EndIdx >= DataCount) EndIdx = DataCount - 1; MultTaskParameter mParm = new MultTaskParameter(); mParm.ProcessName = TaskData.Code; mParm.TaskCode = TaskData.Code; mParm.TaskName = TaskData.Code + (i + 1); mParm.TaskStartIdx = StartIdx; mParm.TaskEndIdx = EndIdx; mParm.Data = TaskData; mParm.TaskConfig = pCfg.Config; mParm.GDBInputDB = pCfg.GDBInputDB; mParm.DataPath = TaskData.SJLJ; mParm.RelatedPath = string.Join(";", pCfg.RelDataList.Select(x => x.SJLJ)); mParm.Related_Name = string.Join(";", pCfg.RelDataList.Select(x => x.TCMC)); mParm.Related_ZD = string.Join(";", pCfg.RelDataList.Select(x => x.ZD)); mParm.Related_SX = string.Join(";", pCfg.RelDataList.Select(x => x.SX)); mParm.OutPath = pCfg.OutDB; TaskInfo task = new TaskInfo(); task.Parameter = mParm; task.ExeFun = new TaskCallback(ExeGPForProces); task.ExeComplatFun = new TaskCallback(TaskRunComplate); int taskDataNum = EndIdx - StartIdx + 1; ThreadPool.AddTask(task); if (AnalyProgress[TaskData.Code].SubProgress == null) AnalyProgress[TaskData.Code].SubProgress = new List(); } } ThreadPool.ExeTask(); } catch (Exception ex) { LogAPI.Debug("分析失败:" + ex.Message); LogAPI.Debug("分析失败:" + ex.StackTrace); throw ex; } finally { } } public void MuitProcessAnalyssis_end(BaseAnalysisData pCfg) { DateTime StartTime = DateTime.Now; string resultDBPath = string.Empty; try { if (pCfg.TaskList == null) return; foreach (var TaskData in pCfg.TaskList) { if (!AnalyProgress.ContainsKey(TaskData.Code)) AnalyProgress.Add(TaskData.Code, new ProgressModel()); if (TaskData == null) throw new Exception("参数中未指定任务图层!"); IFeatureClass featureClass = MapsManager.Instance.MapService.GetFeatureClassByName("DLTBGX"); int DataCount = featureClass.FeatureCount(null); int subTaskNum = 0; string relTables = string.Join(",", pCfg.RelDataList.Select(x => x.TCMC)); foreach (var relData in pCfg.RelDataList) { if (!relData.SFFX || relData.XZQDM != TaskData.XZQDM) continue; if (string.IsNullOrWhiteSpace(relData.SJLJ)) { pCfg.Message += "未指定图层【" + relData.TCMC + "】的图层路径!"; continue; } subTaskNum++; } int TaskCount = (ProcessManager.Instance.MaxThreadNum) / pCfg.TaskList.Length; //if (TaskCount == 0) TaskCount = 1; int f = (int)DataCount / TaskCount; int s = (int)DataCount % TaskCount; int StartIdx = 0; int EndIdx = f; for (int i = 0; i < TaskCount; i++) { StartIdx = i * f; if (i == TaskCount - 1) { f = f + s; } EndIdx = f * (i + 1) - 1; if (EndIdx >= DataCount) EndIdx = DataCount - 1; MultTaskParameter mParm = new MultTaskParameter(); mParm.ProcessName = TaskData.Code; mParm.TaskCode = TaskData.Code; mParm.TaskName = TaskData.Code + (i + 1); mParm.TaskStartIdx = -1; mParm.TaskEndIdx = EndIdx; mParm.Data = TaskData; mParm.TaskConfig = pCfg.Config; mParm.GDBInputDB = pCfg.GDBInputDB; mParm.DataPath = TaskData.SJLJ; mParm.RelatedPath = string.Join(";", pCfg.RelDataList.Select(x => x.SJLJ)); mParm.Related_Name = string.Join(";", pCfg.RelDataList.Select(x => x.TCMC)); mParm.Related_ZD = string.Join(";", pCfg.RelDataList.Select(x => x.ZD)); mParm.Related_SX = string.Join(";", pCfg.RelDataList.Select(x => x.SX)); mParm.OutPath = pCfg.OutDB; TaskInfo task = new TaskInfo(); task.Parameter = mParm; task.ExeFun = new TaskCallback(ExeGPForProces); task.ExeComplatFun = new TaskCallback(TaskRunComplate); ThreadPool.AddTask(task); if (AnalyProgress[TaskData.Code].SubProgress == null) AnalyProgress[TaskData.Code].SubProgress = new List(); } } ThreadPool.ExeTask(); } catch (Exception ex) { LogAPI.Debug("分析失败:" + ex.Message); LogAPI.Debug("分析失败:" + ex.StackTrace); throw ex; } finally { } } public TaskRunCallbackHandler TaskRunComplateCallback; private object TempLock = new object(); private void TaskRunComplate(TaskParameter pTaskParm) { lock (TempLock) { TaskRunComplateCallback?.Invoke(pTaskParm); } } public void ExeGPForProces(TaskParameter pTaskParm) { MultTaskParameter parm = pTaskParm as MultTaskParameter; Dictionary dicParm = new Dictionary(); dicParm.Add("TaskName", parm.TaskName); dicParm.Add("TaskCode", parm.TaskCode); dicParm.Add("DataPath", parm.DataPath); dicParm.Add("TaskList_TCMC", (parm.Data as DataModel).TCMC); dicParm.Add("TaskList_ZD", (parm.Data as DataModel).ZD); dicParm.Add("TaskList_SX", (parm.Data as DataModel).SX); dicParm.Add("StartIdx", parm.TaskStartIdx.ToTrim()); dicParm.Add("EndIdx", parm.TaskEndIdx.ToTrim()); dicParm.Add("OutPath", parm.OutPath); dicParm.Add("RelatedPath", parm.RelatedPath); dicParm.Add("RelLayers", parm.Related_Name); dicParm.Add("Related_SX", parm.Related_SX); dicParm.Add("Related_ZD", parm.Related_ZD); dicParm.Add("GDBInputDB", parm.GDBInputDB); dicParm.Add("SysDBPath", AppDomain.CurrentDomain.BaseDirectory + "\\netcoreapp3.1\\Database\\System.db"); string strParm2 = System.Text.Json.JsonSerializer.Serialize(dicParm); ProcessManager.Instance.WorkerPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "\\netcoreapp3.1", "DataAnalysisProcess"); ProcessManager.Instance.ExeTask(strParm2, UpdateProgress); return; } public static Dictionary AnalyProgress = new Dictionary(); public void UpdateProgress(object data) { string val = data.ToTrim(); string[] valArr = val.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries); if (valArr.Length == 2 && AnalyProgress.Count > 0) { foreach (var item in AnalyProgress.Keys) { var progress = AnalyProgress[item].GetProModel(valArr[0]); if (progress != null) { progress.Value = valArr[1].ToInt(); } } } } } public delegate void TaskRunCallbackHandler(TaskParameter parm); public class BaseAnalysisData { public string Code { get; set; } //数据列表 public DataModel[] TaskList { get; set; } //数据列表 public DataModel[] RelDataList { get; set; } //输出结构 public string OutDB { get; set; } public string GDBInputDB { get; set; } public AnalysisConfig Config { get; set; } public string Message { get; set; } } public class DataModel { public int ID { get; set; } /// /// 文件路径 /// public string SJLJ { get; set; } /// /// 文件路径 /// public string Message { get; set; } /// /// 导入的图层名称 /// public string TCMC { get; set; } /// /// 关键字段 /// public string ZD { get; set; } /// /// 是否需要分析 /// public bool SFFX { get; set; } /// /// 是否任务图层 /// public bool SFRW { get; set; } /// /// 关键属性 /// public string SX { get; set; } /// /// 图层别名 /// public string TCBM { get; set; } public DataType DataType { get; set; } /// /// 行政区名称 /// public string XZQMC { get; set; } /// /// 行政区代码 /// public string XZQDM { get; set; } public string Code => XZQDM + XZQMC; /// /// 截图(图层)名称 /// public string JTMC { get; set; } } public enum DataType { Folder = 1, GDB = 2, SHP = 4, MDB = 8, IMG = 16, TIFF = 32, PNG = 64, ZIP = 128, Featrue = 256, Table = 512, DB = 1024, Excel = 2048, Default = 0 } public class AnalysisConfig { /// /// 是否涉密 /// public bool SFSM { get; set; } /// /// 是否截取矢量 /// public bool ShpScreen { get; set; } /// /// 是否截取影像 /// public bool ImgScreen { get; set; } /// /// 矢量比例 /// public double ShpResolution { get; set; } /// /// 影像比例 /// public double ImgResolution { get; set; } /// /// 照片最大尺寸 /// public int MaxSize { get; set; } /// /// 照片最小尺寸 /// public int MinSize { get; set; } /// /// 外扩范围倍数 /// public double GeoBuffSize { get; set; } public string SavePath { get; set; } public string GeoType { get; set; } public int ImgWKID { get; set; } public int ShpWKID { get; set; } } public class MultTaskParameter : TaskParameter { /// /// 分析进度查询表示 /// public string ProcessName { get; set; } /// /// 任务数据路径 /// public string DataPath { get; set; } /// /// 参考数据路径 /// public string RelatedPath { get; set; } /// /// 参考数据图层名 /// public string Related_Name { get; set; } /// /// 参考数据关键字段 /// public string Related_ZD { get; set; } /// /// 参考数据关键属性 /// public string Related_SX { get; set; } /// /// 输出路径 /// public override string OutPath { get; set; } public string GDBInputDB { get; set; } } public class ProgressModel { private int _Count = 0; private int _Value = 0; public string ProName { get; set; } /// /// 总个数 /// public int Count { get { return GetCount(); } set { _Count = value; } } /// /// 当前处理个数 /// public int Value { get { return GetValue(); } set { _Value = value; } } public double Percentage => Count == 0 ? 0 : Math.Round((double)Value / Count, 2); public List SubProgress { get; set; } private int GetCount() { if (SubProgress != null) { _Count = SubProgress.Sum(s => s.Count); } return _Count; } private int GetValue() { if (SubProgress != null) { _Value = SubProgress.Sum(s => s.Value); } return _Value; } public ProgressModel GetProModel(string ProName) { if (this.ProName == ProName) return this; else if (SubProgress != null) { return SubProgress.FirstOrDefault(f => f.ProName == ProName); } else return null; } } }