using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using DfdIO; using NetTopologySuite.Geometries; using NetTopologySuite.Operation.Distance; using NetTopologySuite.Precision; //using SqlSugar; //using WorkData; //using WorkData.Entity; //using DQ.Construction.Util; //using WorkData; using NetTopologySuite.Operation.Relate; using System.Diagnostics; using NetTopologySuite.Algorithm; using System.Runtime.InteropServices; //using ParameterDQ.Construction.Util; using NeighborInterpolator; using System.Security.Permissions; using System.Data.SqlClient; using NetTopologySuite.Index.Strtree; namespace Construction.BatchCreateMap { public delegate void ProgressEvent(string eventName, int curentStep); public class LayerCreate { private const double Zero = 1E-5; public ProgressEvent ProgressChanged; public static string ExePath { get; set; } = string.Empty; public static string XYZPath // dfCreatef(x,y) { get { return Path.Combine(ExePath, "GridModel.exe"); } } //public static string IdmPath //{ // get // { // return Path.Combine(ExePath, "GridModel.exe"); // } //} //string onCurveModelPath = "C:\\DF42\\bin\\CurveModel.exe";//等值线 private List listProcessIds = new List(); public void KillProgress() { for (int i = 0; i < listProcessIds.Count; i++) { try { Process process = Process.GetProcessById(listProcessIds[i]); process.Kill(); process.WaitForExit(500); // 等待进程退出 } catch (ArgumentException) { // 进程已退出 } catch (System.ComponentModel.Win32Exception ex) { // 处理权限不足等异常 } listProcessIds.RemoveAt(i); i--; } } public static string CurveModelPath { get { return Path.Combine(ExePath, "CurveModel.exe"); } } //private static string _BorderFile; //public static string BorderFile //{ // get // { // //string strFile = WorkData.Config.ProjectPath + "\\result\\border.dfd"; // //if (File.Exists(strFile)) // //{ // // return strFile; // //} // return _BorderFile; // } // set // { // _BorderFile = value; // } //} //private double _XMin, _XMax, _YMin, _YMax; /// /// 搜索所有文件夹 /// /// public string SearchFolder(string dirName, string layerName) //参数为指定的目录 { string strFind = ""; //在指定目录及子目录下查找文件 DirectoryInfo dir = new DirectoryInfo(dirName); try { foreach (DirectoryInfo d in dir.GetDirectories()) // 查找子目录 { strFind = SearchFolder(dir + "\\" + d.ToString(), layerName); if (strFind.Length > 0) { return strFind; } } // 文件处理 foreach (FileInfo f in dir.GetFiles("*.*")) // 查找文件 { if (Path.GetFileNameWithoutExtension(f.Name) .Equals(layerName, StringComparison.CurrentCultureIgnoreCase)) { strFind = f.FullName; return strFind; } } } catch (Exception e) { Console.WriteLine(e.Message); return ""; } return ""; } ///// ///// 创建断层文件 ///// ///// ///// //public string CreateFault(string layerName) //{ // InterpretFault fault = DBHelp.Db.Queryable().Single( // it => it.CW.ToUpper()==layerName.ToUpper()); // if (fault ==null||fault.FILE_DATA==null||fault.FILE_DATA.Length==0) { return ""; } // string strFaultData = System.Text.Encoding.Default.GetString(fault.FILE_DATA); // // 生成断层文件 // DfdFormat dfdFormat = new DfdFormat(); // string strFault = dfdFormat.DataToDfdString(strFaultData,new char[] { '\t' , ' ' }, "断层", LineDataFormat.XYName); // string strWriteFile = WorkData.Config.ProjectPath + "\\middle\\"+ layerName+"_f.dfd"; // using (StreamWriter sw = new StreamWriter(strWriteFile,false, Encoding.Default)) // { // sw.WriteLine(strFault); // } // return strWriteFile; //} /// /// 生成边界 /// /// /// /// //public bool CreateBorderForRange(string xyzFile, string outFile) //{ // try // { // var range = ParameterDataWriter.ReadXYZRange(xyzFile); // DfLine dfLine = new DfLine(); // dfLine.Points.Add(new DfPoint(range.XMin.Value, range.YMin.Value)); // dfLine.Points.Add(new DfPoint(range.XMin.Value, range.YMax.Value)); // dfLine.Points.Add(new DfPoint(range.XMax.Value, range.YMax.Value)); // dfLine.Points.Add(new DfPoint(range.XMax.Value, range.YMin.Value)); // dfLine.Points.Add(new DfPoint(range.XMin.Value, range.YMin.Value)); // dfLine.Layer = "边界"; // DfdWriter dfdWriter = new DfdWriter(outFile); // dfdWriter.WriteDfdLine(new List() { dfLine }, false); // return true; // } // catch (Exception ex) // { // return false; // } //} public bool CreateBorder(string xyzFile, string outFile) { try { List coordinates = new List(); string strLine = ""; using (StreamReader sr = new StreamReader(xyzFile, Encoding.Default)) { string[] straXY; double dX = 0, dY = 0; while (sr.Peek() > -1) { strLine = sr.ReadLine(); straXY = strLine.Split(','); if (straXY.Length < 3) { continue; } if (double.TryParse(straXY[0] + "", out dX) && double.TryParse(straXY[1] + "", out dY)) { coordinates.Add(new Coordinate(dX, dY)); } } } //PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.MaximumPreciseValue); //GeometryFactory factory = new GeometryFactory(precisionModel, 0); var convexHullOp = new ConvexHull(coordinates, GeometryFactory.Default); var ch = convexHullOp.GetConvexHull(); //Trace.WriteLine("ConvexHull:"); //Trace.WriteLine($"Geometry type: {ch.GeometryType}"); //Trace.WriteLine($"Number of points: {ch.NumPoints}"); //Trace.WriteLine("Before Simplify:"); //Trace.WriteLine(string.Format("Geometry type: {0}", ch.GeometryType)); //if (ch is Polygon p) //{ // var ring = (LinearRing)p.ExteriorRing; // Trace.WriteLine(string.Format("Exterior ring orientation: {0}", ring.IsCCW ? "counter-clockwise" : "clockwise")); // //p.Reverse(); // //ring = (LinearRing)p.ExteriorRing; // //Trace.WriteLine(string.Format("Exterior ring orientation: {0}", ring.IsCCW ? "counter-clockwise" : "clockwise")); //} //Trace.WriteLine(ch.AsText()); //actual = actual.Reverse(); //foreach (Coordinate coor in actual.Coordinates) //{ // Trace.WriteLine($"{coor.X},{coor.Y}"); //} //double dTolerance = 1E-7; //Geometry geoSimplify = NetTopologySuite.Simplify.TopologyPreservingSimplifier.Simplify(actual, dTolerance); //Trace.WriteLine("After Simplify:"); //foreach (Coordinate coor in geoSimplify.Coordinates) //{ // Trace.WriteLine($"{coor.X},{coor.Y}"); //} //CoordinateList lstBorder = PointsHull.Brahamscan(ch.Coordinates, 10); DfLine dfLine = new DfLine(); foreach (Coordinate coor in ch.Coordinates) { dfLine.Points.Add(new DfPoint(coor.X, coor.Y)); } dfLine.Layer = "边界"; DfdWriter dfdWriter = new DfdWriter(outFile); dfdWriter.WriteDfdLine(new List() { dfLine }, false); return true; } catch (System.Exception ex) { return false; } } //public bool CreateBorder(string xyzFile, string outFile) //{ // try // { // List coordinates = new List(); // string strLine = ""; // using (StreamReader sr = new StreamReader(xyzFile, Encoding.Default)) // { // string[] straXY; // double dX = 0, dY = 0; // while (sr.Peek() > -1) // { // strLine = sr.ReadLine(); // straXY = strLine.Split(','); // if(straXY.Length < 3) // { // continue; // } // if (Double.TryParse(straXY[0] + "", out dX) // && Double.TryParse(straXY[1] + "", out dY)) // { // coordinates.Add(new Coordinate(dX, dY)); // } // } // } // PrecisionModel precisionModel = new PrecisionModel(PrecisionModel.MaximumPreciseValue); // GeometryFactory factory = new GeometryFactory(precisionModel, 0); // var ch = new ConvexHull(coordinates, factory); // var actual = ch.GetConvexHull(); // List lstDfPoints = new List(); // for (int i = 2; i < actual.Coordinates.Count(); i++) // { // lstDfPoints.Add(new DfPoint(actual.Coordinates[i].X, actual.Coordinates[i].Y)); // } // DfLine dfLine = new DfLine(lstDfPoints); // dfLine.Layer = "边界"; // //string strBorderMap = WorkData.Config.ProjectPath + "\\result\\border.dfd"; // DfdWriter dfdWriter = new DfdWriter(outFile); // dfdWriter.WriteDfdLine(new List() { dfLine }, false); // return true; // } // catch (System.Exception ex) // { // return false; // } //} public bool CreateBorder(DataTable data, string fileName) { try { int nCount = data.Rows.Count; List coordinates = new List(); double dX = 0, dY = 0; for (int i = 0; i < nCount; i++) { if (Double.TryParse(data.Rows[i]["X"] + "", out dX) && Double.TryParse(data.Rows[i]["Y"] + "", out dY)) { coordinates.Add(new Coordinate(dX, dY)); } } GeometryFactory factory = new GeometryFactory(); MultiPoint pts = factory.CreateMultiPointFromCoords(coordinates.ToArray()); Geometry hull = pts.ConvexHull(); List lstDfPoints = new List(); for (int i = 0; i < hull.Coordinates.Count(); i++) { lstDfPoints.Add(new DfPoint(hull.Coordinates[i].X, hull.Coordinates[i].Y)); } DfLine dfLine = new DfLine(lstDfPoints); dfLine.Layer = "边界"; //string strBorderMap = WorkData.Config.ProjectPath + "\\result\\border.dfd"; DfdWriter dfdWriter = new DfdWriter(fileName); dfdWriter.WriteDfdLine(new List() { dfLine }, false); return true; } catch (System.Exception ex) { return false; } } public void AppendFile(string fileSource, string fileAppend) { string strAppendData = ""; using (StreamReader sr = new StreamReader(fileAppend, Encoding.Default)) { strAppendData = sr.ReadToEnd(); } using (StreamWriter sw = new StreamWriter(fileSource, true, Encoding.Default)) { sw.WriteLine(strAppendData); } } [Flags] public enum ThreadAccess : int { TERMINATE = (0x0001), SUSPEND_RESUME = (0x0002), GET_CONTEXT = (0x0008), SET_CONTEXT = (0x0010), SET_INFORMATION = (0x0020), QUERY_INFORMATION = (0x0040), SET_THREAD_TOKEN = (0x0080), IMPERSONATE = (0x0100), DIRECT_IMPERSONATION = (0x0200) } [DllImport("kernel32.dll")] static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId); [DllImport("kernel32.dll")] private static extern uint GetCurrentThreadId(); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool CloseHandle(IntPtr hObject); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool TerminateThread(IntPtr hThread, uint dwExitCode); /// /// 终止网格化处理线程 /// [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] public bool AboutGridProcess() { if (ProcessThread != null) { //// 获取线程ID //IntPtr handle = OpenThread(ThreadAccess.TERMINATE, false, ProcessThreadId); //// 终止线程 //if (handle != IntPtr.Zero) //{ // TerminateThread(handle, 0); // 或者其他的退出码 // CloseHandle(handle); // ProcessThreadId = 0; // return true; //} //return false; // 强制终止线程 ProcessThread.Interrupt(); ProcessThread.Abort(); ProcessThread.Join(); } return false; } /// /// 网格化处理线程 /// public static Thread ProcessThread { get; set; } = null; public static uint ProcessThreadId { get; set; } = 0; /// /// /// /// /// /// /// 处理标识: /// 0-网格化、生成等值线、断层内等值线清理、断层搭接; /// 1-网格化、生成等值线、断层内等值线清理; /// 2-网格化、生成等值线 /// 3-网格化。 /// 默认值是0 /// public bool CreateLayerMapWithPara(GridCreateParameter para, string outputDir, string fileName , int flag = 0) { ProcessThread = null; if (!outputDir.EndsWith("\\")) { outputDir += "\\"; } string strInput = Convert2AbsolutePath(para.DataRootPath, para.Input); string strOutput = Convert2AbsolutePath(para.DataRootPath, para.Output); string strOutline = Convert2AbsolutePath(para.DataRootPath, para.Outline); strOutline = string.IsNullOrEmpty(strOutline) ? "NULL" : strOutline; string strFaultFile = Convert2AbsolutePath(para.DataRootPath, para.Faultage); strFaultFile = string.IsNullOrEmpty(strFaultFile) ? "NULL" : strFaultFile; string strParaFile = para.FilePath; //string strFaultFile = para.Faultage; string strCurveFile = $"{outputDir}{fileName}.kev"; string strDfgFile = $"{outputDir}{fileName}.dfg"; if (para.CreateType == ModelCreateType.Curvature) { // 最小曲率法 //bool bResult = false; //ProcessThread = new Thread(new ThreadStart(() => //{ // ProcessThreadId = GetCurrentThreadId(); // try // { // ModelCreateCurvature.BuildMinCurvatureGrid3(strInput, strFaultFile, strOutline, // (ulong)para.M, /*(ulong)para.N,*/ -1, 0.0001, 0.0, 0, strCurveFile // , 0, 64 // , para.CurveSpace, para.LableSpace, para.Times // , para.XMin, para.YMin, para.XMax, para.YMax); // bResult = processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); // } // catch (ThreadAbortException ex) // { // bResult = false; // } //}), 20 * 1024 * 1024); //ProcessThread.Start(); //ProcessThread.Join(); //return bResult; Dictionary dic = new Dictionary() { { "--source-point-file",$"\"{strInput}\"" }, { "--fault",$"\"{strFaultFile}\"" }, { "--breakline",$"\"{strOutline}\"" }, { "--x-nodes-count",(ulong)para.M }, { "--max-iteration", -1 }, { "--residual", 0.0001 }, { "--fill-value", 0.0}, { "--fault-edge-level",0 }, { "--output-file", $"\"{strCurveFile}\"" }, { "--estimate-factor",0 }, { "--corner-weight", 64 }, { "--contour-step", para.CurveSpace }, { "--contour-mark-step", para.LableSpace }, { "--insert-times", para.Times }, { "--smooth-times", para.Smooth }, { "--area", $"{para.XMin},{para.YMin},{para.XMax},{para.YMax}" }, }; string strParameter = string.Join(" ", dic.Select(x => $"{x.Key} {x.Value}")); // 执行网格化模块 Process p = new Process(); p.StartInfo.FileName = "SurfaceGrid.exe"; //exe程序文件地址 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = false; p.StartInfo.RedirectStandardOutput = false; p.StartInfo.RedirectStandardError = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = strParameter; // 参数 多个参数使用空格分开 p.Start(); listProcessIds.Add(p.Id); p.WaitForExit(); p.Close(); return processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); } else if (para.CreateType == ModelCreateType.IDM) { // 反距离加权法 IntPtr pEvent = IntPtr.Zero; if (ProgressChanged != null) { pEvent = Marshal.GetFunctionPointerForDelegate(ProgressChanged); } bool bResult = false; ProcessThread = new Thread(new ThreadStart(() => { ProcessThreadId = GetCurrentThreadId(); try { // SetDllDirectory(System.Windows.Forms.Application.StartupPath); ModelCreateIDW.IDWModelCreate(strInput, strOutline, strFaultFile, strCurveFile, para.M, para.Smooth, 3, pEvent, para.Times, para.CurveSpace, para.LableSpace , para.XMin, para.YMin, para.XMax, para.YMax); bResult = processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); } catch (ThreadAbortException) { bResult = false; } }), 2621440); ProcessThread.Start(); ProcessThread.Join(); return bResult; } else if (para.CreateType == ModelCreateType.NatureNeighbor) { // 自然临近法 bool bResult = false; ProcessThread = new Thread(new ThreadStart(() => { ProcessThreadId = GetCurrentThreadId(); try { GridCreator creater = new GridCreator(); creater.Create(strInput, strCurveFile, strOutline , para.M, para.N, para.Times, para.CurveSpace, para.LableSpace , para.XMin, para.YMin, para.XMax, para.YMax); bResult = processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); } catch (ThreadAbortException ex) { bResult = false; } })); ProcessThread.Start(); ProcessThread.Join(); return bResult; } else if(para.CreateType == ModelCreateType.QuikGrid) { bool bResult = QuikGridCS.Interface.QuikGridCreate(strInput, strCurveFile, para.M, para.N, para.CurveSpace, para.LableSpace, para.Smooth); //bResult = processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); return bResult; } else if(para.CreateType == ModelCreateType.GmtSplineGrid) { //样条插值 string strParameter = ""; string strOutputFile = $"{outputDir}{fileName}.grd"; string outputFile = $"{outputDir}{fileName}.kev"; strParameter = string.Format("\"{0}\" \"{1}\" \"{2}\" \"{3}\" \"{4}\" {5} {6} {7} {8} {9} {10} {11} {12}" , strInput, strOutputFile, strFaultFile , strOutline, outputFile, para.XStep , 0, para.CurveSpace, para.LableSpace , para.XMin, para.YMin, para.XMax, para.YMax ); string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location; string exeDir = Path.GetDirectoryName(exePath); string exeFilePath = Path.Combine(exeDir, "GmtSurfaceGrid.exe"); Trace.WriteLine(strParameter); // 执行网格化模块 Process p = new Process(); p.StartInfo.FileName = exeFilePath; //exe程序文件地址 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = strParameter; // 参数 多个参数使用空格分开 p.Start(); p.WaitForExit(); string output = p.StandardOutput.ReadToEnd(); string error = p.StandardError.ReadToEnd(); string result = string.IsNullOrWhiteSpace(error) ? output : error; int exitCode = p.ExitCode; p.Close(); bool state = (exitCode == 0 ? true : false); return state; } else { // 最小张力法 string strParameter = ""; if (strOutline.Equals("NULL", StringComparison.CurrentCultureIgnoreCase)) { strParameter = string.Format("\"{0}\" \"{1}\" {2} \"{3}\" \"{4}\" {5} {6} {7} {8} {9} {10} {11}" , strInput, strOutput, para.Times , strOutline, strFaultFile , para.M, para.Smooth, 0 // 最后一项为断层优先级 , para.XMin, para.YMin, para.XMax, para.YMax); } else { strParameter = string.Format("\"{0}\" \"{1}\" {2} \"{3}\" \"{4}\" {5} {6} {7}" , strInput, strOutput, para.Times , strOutline, strFaultFile , para.M, para.Smooth, 0); // 最后一项为断层优先级 } // CreateBorder(); Trace.WriteLine(strParameter); // 执行网格化模块 Process p = new Process(); p.StartInfo.FileName = XYZPath; //exe程序文件地址 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = false; p.StartInfo.RedirectStandardOutput = false; p.StartInfo.RedirectStandardError = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = strParameter; // 参数 多个参数使用空格分开 p.Start(); p.WaitForExit(); p.Close(); if (flag >= 3) return true; // 等值线 string strCurveParameter = ""; strCurveParameter += "\"" + strOutput + "\""; strCurveParameter += " "; strCurveParameter += "\"" + strCurveFile + "\""; if (strFaultFile.Equals("NULL")) { strFaultFile = null; } if (strFaultFile != null && strFaultFile.Length > 0) { strCurveParameter += " \"" + strFaultFile + "\" " + para.CurveSpace; } else { strCurveParameter += " NULL " + para.CurveSpace; } if (para.LableSpace > 0) { strCurveParameter += " " + para.LableSpace; } Trace.WriteLine(strCurveParameter); p = new System.Diagnostics.Process(); p.StartInfo.FileName = CurveModelPath; // exe程序文件地址 p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardInput = false; p.StartInfo.RedirectStandardOutput = false; p.StartInfo.RedirectStandardError = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.Arguments = strCurveParameter; // 参数多个参数使用空格分开 p.Start(); p.WaitForExit(); p.Close(); // 追加断层 if (strFaultFile != null && strFaultFile.Length > 0) AppendFile(strCurveFile, strFaultFile); return processAfterGrid(outputDir, fileName, flag, strFaultFile, strCurveFile, strDfgFile); } } private bool processAfterGrid(string outputDir, string fileName, int flag, string strFaultFile, string strCurveFile, string strDfgFile) { if (flag >= 2) return true; // 断层清理 if (ClearLineInFault(strCurveFile, "等值线", "断层") == false) { return true; } // 断层搭接 if (flag >= 1) { return true; } // 读取网格信息 DfgReader dfg = new DfgReader(strDfgFile); dfg.ReadHead(); double dStepX = dfg.DeltX; double dStepY = dfg.DeltY; List extendCurves = LineOfExtend2Fault(Math.Max(dStepX, dStepY) * 2, strCurveFile, strFaultFile, "等值线", "断层"); string strCurveFileBak = (outputDir + fileName + "_Curve.kev"); File.Copy(strCurveFile, strCurveFileBak, true); DfdWriter dfdWriter = new DfdWriter(strCurveFile); dfdWriter.WriteDfg(strDfgFile, "背景", false); dfdWriter.WriteDfdLine(extendCurves, true); // 追加断层 if (strFaultFile != null && strFaultFile.Length > 0) AppendFile(strCurveFile, strFaultFile); return true; } [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] static extern bool SetDllDirectory(string lpPathName); ///// ///// 按地层成图 ///// ///// ///// ///// //public bool CreateLayerMap(string layerName) //{ // if (GetMapRange()==false) return false; // CreateBorder(); // //var result = DBHelp.Db.Queryable( // // (boundary, wellBase) => new JoinQueryInfos( // // JoinType.Left, boundary.JH == wellBase.JH) // // )//.Where(boundary => boundary[layerName] == layerName) // // .Select((boundary, wellBase) => // // new {X = wellBase.X, Y=wellBase.Y, Z = boundary.Jxz } // // ).ToList(); // string strColumnName = DBHelp.GetColumnName(layerName); // var result = DBHelp.Db.Queryable( // (boundary, wellBase) => new JoinQueryInfos( // JoinType.Left, boundary.JH==wellBase.JH)) // .Select("wellBase.X, wellBase.Y,boundary."+strColumnName).ToDataTable(); // string strDataFile = WorkData.Config.ProjectPath + @"\temp\" + layerName + ".xyz"; // // 写散点文件 // using (StreamWriter sw = new StreamWriter(strDataFile, false, Encoding.Default)) // { // for(int i = 0; i < result.Rows.Count; i++) // { // var line = result.Rows[i]; // sw.WriteLine("{0},{1},{2}", line[0], line[1], line[2]); // } // } // string strFaultFile = CreateFault(layerName); // // 写参数文件 // string strParaFile = WorkData.Config.ProjectPath + @"\middle\" + layerName + ".ini"; // Parameter util = new Parameter(); // util.FilePath = strParaFile; // util.Input = strDataFile; // util.Output = WorkData.Config.ProjectPath + @"\temp\" + layerName + ".f(x,y)"; // util.Outline = BorderFile; // if (strFaultFile.Length > 0) // { // util.Faultage = strFaultFile; // 断层 // } // util.XMax = _XMin; // util.XMax = _XMax; // util.YMin = _YMin; // util.YMax = _YMax; // util.M = 640; // util.N = 304; // util.Times = 1; // util.WriteData(); // return CreateLayerMapWithPara(layerName, util); //} private bool Extent2Fault(DfLine line, List cooFaults, double dStep, DfLine lineDes) { bool bSuccess = false; int nPtCount = line.Points.Count; line.CopyTo(lineDes); double dDistanceStart = dStep; double dDistanceEnd = dStep; LineString faultStart = null; LineString faultEnd = null; Coordinate ptStart1 = new Coordinate(line.Points[1].X, line.Points[1].Y); Coordinate ptStart2 = new Coordinate(line.Points[0].X, line.Points[0].Y); Coordinate ptEnd1 = new Coordinate(line.Points[nPtCount - 2].X, line.Points[nPtCount - 2].Y); Coordinate ptEnd2 = new Coordinate(line.Points[nPtCount - 1].X, line.Points[nPtCount - 1].Y); if (ptStart1.Equals2D(ptStart2) || ptEnd1.Equals2D(ptEnd2)) { return false; } bool bSkipHead = false; bool bSkipTail = false; for (int i = 0; i < cooFaults.Count; i++) { //if(faultEnd !=null && faultStart!=null) //{ // break; //} // 首节点 if (bSkipHead == false) { double dDistance = new DistanceOp(cooFaults[i], new Point(ptStart2)).Distance(); if (dDistance <= dDistanceStart) { if (dDistance < Zero) { bSkipHead = true; } else { dDistanceStart = dDistance; faultStart = cooFaults[i]; } } } // 尾节点 if (bSkipTail == false)// faultEnd == null && { double dDistance = new DistanceOp(cooFaults[i], new Point(ptEnd2)).Distance(); if (dDistance <= dDistanceEnd) { if (dDistance < Zero) { bSkipTail = true; } else { dDistanceEnd = dDistance; faultEnd = cooFaults[i]; } } } } if (faultStart != null && bSkipHead != true) { var crossPt = GetCrossPt(ptStart1, ptStart2, faultStart, dStep); lineDes.Points.Insert(0, new DfPoint(crossPt.X, crossPt.Y)); bSuccess = true; } if (faultEnd != null && bSkipTail != true) { var crossPt = GetCrossPt(ptEnd1, ptEnd2, faultEnd, dStep); lineDes.Points.Add(new DfPoint(crossPt.X, crossPt.Y)); bSuccess = true; } return bSuccess; } public bool LineOfExtend2Fault(string fileName, double dStep, string curveLayer = "等值线", string faultLayer = "断层") { // 读取所有断层 DfdReader curveReader = new DfdReader(fileName); List dfFaults = curveReader.GetDfdLinesByLayer(faultLayer); List cooFaults = new List(); foreach (DfLine fault in dfFaults) { int nCount = fault.Points.Count; if (nCount < 4) continue; Coordinate[] coordinates = new Coordinate[nCount]; for (int i = 0; i < nCount; i++) { coordinates[i] = new Coordinate(fault.Points[i].X, fault.Points[i].Y); } cooFaults.Add(new LineString(coordinates)); } // 逐行读取 DfdElementReader elementReader = new DfdElementReader(fileName); string strFileBack = CreateBackupFileName(fileName); StreamWriter sw = new StreamWriter(strFileBack, false, Encoding.Default); string strLayerSub = curveLayer + "\\"; string strLine; while ((strLine = elementReader.ReadLine()) != null) { //Trace.WriteLine(strLine); if ((elementReader.LayerName == curveLayer || elementReader.LayerName.StartsWith(strLayerSub)) && elementReader.CurElementType == DfdIO.Elements.ElementType.ELEMENT_LINE) { DfLine eleLine = elementReader.ReadLineElement(); if (eleLine.Points.Count < 2) { // 忽略无效曲线 elementReader.CurElementType = DfdIO.Elements.ElementType.ELEMENT_NONE; } else { // 进行延伸处理 DfLine lineNew = new DfLine(); Extent2Fault(eleLine, cooFaults, dStep, lineNew); string strLineData = lineNew.ToString(false); sw.WriteLine(strLineData); elementReader.CurElementType = DfdIO.Elements.ElementType.ELEMENT_NONE; } } else { sw.WriteLine(strLine); } } sw.Flush(); sw.Close(); elementReader.EndReader(); File.Delete(fileName); File.Copy(strFileBack, fileName); return true; } private List LineOfExtend2Fault(double dStep, string curveFile, string faultFile , string curveLayer = "等值线", string faultLayer = "断层") { DfdReader curveReader = new DfdReader(curveFile); if (faultFile == null || faultFile.Length == 0) { return curveReader.GetDfdLinesByLayer(curveLayer, 1); } List dfLinesNew = new List(); // DfdReader curveReader = new DfdReader(curveFile); // 等值线 List dfCurves = curveReader.GetDfdLinesByLayer(curveLayer, 1); DfdReader faultReader = new DfdReader(faultFile); // 断层 List dfFaults = faultReader.GetDfdLinesByLayer(faultLayer); // 断层 List cooFaults = new List(); foreach (DfLine fault in dfFaults) { int nCount = fault.Points.Count; Coordinate[] coordinates = new Coordinate[nCount]; for (int i = 0; i < nCount; i++) { coordinates[i] = new Coordinate(fault.Points[i].X, fault.Points[i].Y); } cooFaults.Add(new LineString(coordinates)); } Coordinate ptStart1, ptStart2; Coordinate ptEnd1, ptEnd2; //DistanceOp op; double dDistanceStart = dStep, dDistanceEnd = dStep; //Coordinate cooClosestPtStart=null, cooClosestPtEnd = null; LineString faultStart = null, faultEnd = null; //int nPtCount = 0; //Parallel.ForEach(dfCurves,(line, loopState) => //FormProcess prog = new FormProcess(); //prog.Show(); // TODO:多CPU,去重复运算 int nCurvesCount = dfCurves.Count; int nIndex = 0; int nStep = 0; foreach (DfLine line in dfCurves) { int nPtCount = line.Points.Count; if (nPtCount < 2) continue; DfLine lineNew = line.Copy(); //cooClosestPtStart = null; //cooClosestPtEnd = null; dDistanceStart = dStep; dDistanceEnd = dStep; faultStart = null; faultEnd = null; ptStart1 = new Coordinate(line.Points[1].X, line.Points[1].Y); ptStart2 = new Coordinate(line.Points[0].X, line.Points[0].Y); ptEnd1 = new Coordinate(line.Points[nPtCount - 2].X, line.Points[nPtCount - 2].Y); ptEnd2 = new Coordinate(line.Points[nPtCount - 1].X, line.Points[nPtCount - 1].Y); for (int i = 0; i < cooFaults.Count; i++) { // 首节点 double dDistance = new DistanceOp(cooFaults[i], new Point(ptStart2)).Distance(); // 到断层的距离小于阈值 if (dDistance <= dDistanceStart) { dDistanceStart = dDistance; faultStart = cooFaults[i]; } // 尾节点 dDistance = new DistanceOp(cooFaults[i], new Point(ptEnd2)).Distance(); if (dDistance <= dDistanceEnd) { dDistanceEnd = dDistance; faultEnd = cooFaults[i]; } } if (faultStart != null) { var crossPt = GetCrossPt(ptStart1, ptStart2, faultStart, dStep); lineNew.Points.Insert(0, new DfPoint(crossPt.X, crossPt.Y)); } if (faultEnd != null) { var crossPt = GetCrossPt(ptEnd1, ptEnd2, faultEnd, dStep); lineNew.Points.Add(new DfPoint(crossPt.X, crossPt.Y)); } dfLinesNew.Add(lineNew); //} nIndex++; nStep = (int)(((double)nIndex / (double)nCurvesCount) * 100); ProgressChanged?.Invoke("断层搭接", nStep); } return dfLinesNew; } /// /// 等值线搭接断层 /// /// 网格步长 /// 等值线文件 /// 断层文件 /// 结果输出文件 /// 等值线图层 /// 断层图层 public void Extend2Fault(double dStep, string curveFile, string faultFile, string outFile , string curveLayer = "等值线", string faultLayer = "断层") { List extendCurves = LineOfExtend2Fault(dStep, curveFile, faultFile, curveLayer, faultLayer); DfdWriter dfdWriter = new DfdWriter(outFile); dfdWriter.WriteDfdLine(extendCurves, true); // 追加断层 if (faultFile != null && faultFile.Length > 0) { AppendFile(outFile, faultFile); } } /// /// 等值线搭接断层 /// /// 网格文件 /// 等值线文件 /// 断层文件 /// 结果输出文件 /// 等值线图层 /// 断层图层 public void Extend2Fault(string gridFile, string curveFile, string faultFile, string outFile , string curveLayer = "等值线", string faultLayer = "断层") { // 读取网格信息 DfgReader dfg = new DfgReader(gridFile); dfg.ReadHead(); double dStepX = dfg.DeltX; double dStepY = dfg.DeltY; double dStep = Math.Max(dStepX, dStepY) * 2; List extendCurves = LineOfExtend2Fault(dStep, curveFile, faultFile, curveLayer, faultLayer); DfdWriter dfdWriter = new DfdWriter(outFile); dfdWriter.WriteDfdLine(extendCurves, true); // 追加断层 if (faultFile != null && faultFile.Length > 0) { AppendFile(outFile, faultFile); } } public bool ClearLineInFault(string fileName , string curveLayer = "等值线", string faultLayer = "断层") { // 读取所有断层 DfdReader curveReader = new DfdReader(fileName); List dfFaults = curveReader.GetDfdLinesByLayer(faultLayer); if (dfFaults == null || dfFaults.Count == 0) { return false; } List cooFaults = new List(); foreach (DfLine fault in dfFaults) { if (!fault.IsPolyline) { continue; } fault.CloseData(); int nCount = fault.Points.Count; if (nCount < 4) continue; Coordinate[] coordinates = new Coordinate[nCount]; for (int i = 0; i < nCount; i++) { coordinates[i] = new Coordinate(fault.Points[i].X, fault.Points[i].Y); } cooFaults.Add(new Polygon(new LinearRing(coordinates))); } // 逐行读取 DfdElementReader elementReader = new DfdElementReader(fileName); string strFileBack = CreateBackupFileName(fileName); StreamWriter sw = new StreamWriter(strFileBack, false, Encoding.Default); string strLayerSub = curveLayer + "\\"; string strLine; while ((strLine = elementReader.ReadLine()) != null) { if ((elementReader.LayerName == curveLayer || elementReader.LayerName.StartsWith(strLayerSub)) && elementReader.CurElementType == DfdIO.Elements.ElementType.ELEMENT_LINE) { DfLine eleLine = elementReader.ReadLineElement(); // 发现包含在断层内,则忽略该线. if (eleLine.Points.Count < 2 || isLineInFaults(cooFaults, eleLine)) { elementReader.CurElementType = DfdIO.Elements.ElementType.ELEMENT_NONE; } else { string strLineData = eleLine.ToString(false); sw.WriteLine(strLineData); elementReader.CurElementType = DfdIO.Elements.ElementType.ELEMENT_NONE; } } else { sw.WriteLine(strLine); } } sw.Flush(); sw.Close(); elementReader.EndReader(); File.Delete(fileName); File.Copy(strFileBack, fileName); File.Delete(strFileBack); return true; } private bool isLineInFaults(List cooFaults, DfLine eleLine) { int nCount = eleLine.Points.Count; Coordinate[] points = new Coordinate[nCount]; for (int i = 0; i < nCount; i++) { points[i] = new Coordinate(eleLine.Points[i].X, eleLine.Points[i].Y); } foreach (Polygon polygon in cooFaults) { LineString cooLine = new LineString(points); var im = RelateOp.Relate(polygon, cooLine); if (im.IsCovers()) { return true; } } return false; } private Coordinate GetCrossPt(Coordinate pt1, Coordinate pt2, Geometry fault, double offset) { double dXOffset, dYOffset; double dR = Math.Sqrt((pt2.Y - pt1.Y) * (pt2.Y - pt1.Y) + (pt2.X - pt1.X) * (pt2.X - pt1.X)); double dT = dR + offset; dXOffset = pt1.X + (pt2.X - pt1.X) / dR * dT; dYOffset = pt1.Y + (pt2.Y - pt1.Y) / dR * dT; Coordinate[] linePts = new Coordinate[] { pt2, new Coordinate(dXOffset, dYOffset) }; LineString linear = new LineString(linePts); var crossPts = EnhancedPrecisionOp.Intersection(linear, fault); if (crossPts.Coordinates.Count() == 0) { return linePts[0]; } if (crossPts.Coordinates.Count() == 1) { return crossPts.Coordinates[0]; } // 返回距离最近的点 double dDistanceNear = double.MaxValue; Coordinate cooNear = crossPts.Coordinates[0]; foreach (Coordinate coor in crossPts.Coordinates) { double dDis1 = (pt1.X - coor.X) * (pt1.X - coor.X) + (pt1.Y - coor.Y) * (pt1.Y - coor.Y); double dDis2 = (pt2.X - coor.X) * (pt2.X - coor.X) + (pt2.Y - coor.Y) * (pt2.Y - coor.Y); if (dDis1 < dDistanceNear) { dDistanceNear = dDis1; cooNear = coor; } if (dDis2 < dDistanceNear) { dDistanceNear = dDis2; cooNear = coor; } } return cooNear; //if (pt1.X > pt2.X) //{ // return crossPts.Coordinates[crossPts.Coordinates.Count() - 1]; //} //else //{ // return crossPts.Coordinates[0]; //} } public void Curve2Fault(string drawFile, string curveLayer, string faultLayer) { DfdReader faultReader = new DfdReader(drawFile); List dfFaults = faultReader.GetDfdLinesByLayer(faultLayer); string strDfgFile = Path.GetDirectoryName(drawFile) + "\\" + Path.GetFileNameWithoutExtension(drawFile) + ".cfg"; if (!File.Exists(strDfgFile)) { strDfgFile = Path.GetDirectoryName(drawFile) + "\\" + Path.GetFileNameWithoutExtension(drawFile) + ".dfg"; } // 读取网格信息 DfgReader dfg = new DfgReader(strDfgFile); dfg.ReadHead(); double dStepX = dfg.DeltX; double dStepY = dfg.DeltY; List extendCurves = LineOfExtend2Fault(Math.Max(dStepX, dStepY) * 2, drawFile, drawFile, curveLayer); DfdWriter dfdWriter = new DfdWriter(drawFile); // 写背景色 dfdWriter.WriteDfg(strDfgFile, "背景", false); // 写等值线 dfdWriter.WriteDfdLine(extendCurves, true); // 写断层 dfdWriter.WriteDfdLine(dfFaults, true); } //private bool GetMapRange() //{ // var vXMin = DBHelp.Db.Queryable().Min(w => w.X); // var vXMax = DBHelp.Db.Queryable().Max(w => w.X); // var vYMin = DBHelp.Db.Queryable().Min(w => w.Y); // var vYMax = DBHelp.Db.Queryable().Max(w => w.Y); // if(vXMin == null||vXMax==null||vYMin==null||vYMax==null) // { // return false; // } // _XMin =vXMin.Value; // _XMax=vXMax.Value; // _YMin =vYMin.Value; // _YMax =vYMax.Value; // return true; //} /// /// 转换成相对路径 /// /// 绝对路径 /// 相对路径 public string Convert2RelativePath(string root, string fullPath) { if (string.IsNullOrWhiteSpace(fullPath)) { return string.Empty; } string strReturn = fullPath; if (fullPath.StartsWith(root, StringComparison.CurrentCultureIgnoreCase)) { strReturn = fullPath.Remove(0, root.Length + 1); } return strReturn; } /// /// 转换到绝对路径 /// /// 相对路径 /// 绝对路径 public string Convert2AbsolutePath(string root, string relativePath) { if (string.IsNullOrWhiteSpace(relativePath)) { return string.Empty; } if (string.IsNullOrEmpty(root)) { return relativePath; } string strReturn = relativePath; if (!relativePath.StartsWith(root, StringComparison.CurrentCultureIgnoreCase)) { strReturn = Path.Combine(root, relativePath); } return strReturn; } /// /// Gets the name of the backup file. /// /// The source file. /// System.String. public static string CreateBackupFileName(string sourceFile) { try { if (string.IsNullOrEmpty(sourceFile)) { return null; } string strExt = Path.GetExtension(sourceFile); string strFile = Path.GetDirectoryName(sourceFile) + "\\" + Path.GetFileNameWithoutExtension(sourceFile) + "_bak" + strExt; return strFile; } catch (Exception ex) { Trace.WriteLine(ex.Message); return null; } } } public class LayerXyz { public double X { get; set; } public double Y { get; set; } public double Z { get; set; } } }