You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1325 lines
54 KiB
C#

1 month ago
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<int> listProcessIds = new List<int>();
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;
/// <summary>
/// 搜索所有文件夹
/// </summary>
/// <param name="dirName"></param>
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 "";
}
///// <summary>
///// 创建断层文件
///// </summary>
///// <param name="layerName"></param>
///// <returns></returns>
//public string CreateFault(string layerName)
//{
// InterpretFault fault = DBHelp.Db.Queryable<InterpretFault>().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;
//}
/// <summary>
/// 生成边界
/// </summary>
/// <param name="xyzFile"></param>
/// <param name="outFile"></param>
/// <returns></returns>
//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>() { dfLine }, false);
// return true;
// }
// catch (Exception ex)
// {
// return false;
// }
//}
public bool CreateBorder(string xyzFile, string outFile)
{
try
{
List<Coordinate> coordinates = new List<Coordinate>();
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>() { dfLine }, false);
return true;
}
catch (System.Exception ex)
{
return false;
}
}
//public bool CreateBorder(string xyzFile, string outFile)
//{
// try
// {
// List<Coordinate> coordinates = new List<Coordinate>();
// 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<DfPoint> lstDfPoints = new List<DfPoint>();
// 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>() { dfLine }, false);
// return true;
// }
// catch (System.Exception ex)
// {
// return false;
// }
//}
public bool CreateBorder(DataTable data, string fileName)
{
try
{
int nCount = data.Rows.Count;
List<Coordinate> coordinates = new List<Coordinate>();
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<DfPoint> lstDfPoints = new List<DfPoint>();
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>() { 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);
/// <summary>
/// 终止网格化处理线程
/// </summary>
[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;
}
/// <summary>
/// 网格化处理线程
/// </summary>
public static Thread ProcessThread { get; set; } = null;
public static uint ProcessThreadId { get; set; } = 0;
/// <summary>
///
/// </summary>
/// <param name="para"></param>
/// <param name="outputDir"></param>
/// <param name="fileName"></param>
/// <param name="flag">处理标识:
/// 0-网格化、生成等值线、断层内等值线清理、断层搭接;
/// 1-网格化、生成等值线、断层内等值线清理;
/// 2-网格化、生成等值线
/// 3-网格化。
/// 默认值是0</param>
/// <returns></returns>
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<string, object> dic = new Dictionary<string, object>()
{
{ "--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<DfLine> 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);
///// <summary>
///// 按地层成图
///// </summary>
///// <param name="layerName"></param>
///// <param name="borderFile"></param>
///// <returns></returns>
//public bool CreateLayerMap(string layerName)
//{
// if (GetMapRange()==false) return false;
// CreateBorder();
// //var result = DBHelp.Db.Queryable<WellDepositBoundary, WellBase>(
// // (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<WellDepositBoundary>(layerName);
// var result = DBHelp.Db.Queryable<WellDepositBoundary, WellBase>(
// (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<LineString> 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<DfLine> dfFaults = curveReader.GetDfdLinesByLayer(faultLayer);
List<LineString> cooFaults = new List<LineString>();
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<DfLine> 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<DfLine> dfLinesNew = new List<DfLine>();
// DfdReader curveReader = new DfdReader(curveFile);
// 等值线
List<DfLine> dfCurves = curveReader.GetDfdLinesByLayer(curveLayer, 1);
DfdReader faultReader = new DfdReader(faultFile);
// 断层
List<DfLine> dfFaults = faultReader.GetDfdLinesByLayer(faultLayer);
// 断层
List<LineString> cooFaults = new List<LineString>();
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;
}
/// <summary>
/// 等值线搭接断层
/// </summary>
/// <param name="dStep">网格步长</param>
/// <param name="curveFile">等值线文件</param>
/// <param name="faultFile">断层文件</param>
/// <param name="outFile">结果输出文件</param>
/// <param name="curveLayer">等值线图层</param>
/// <param name="faultLayer">断层图层</param>
public void Extend2Fault(double dStep, string curveFile, string faultFile, string outFile
, string curveLayer = "等值线", string faultLayer = "断层")
{
List<DfLine> 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);
}
}
/// <summary>
/// 等值线搭接断层
/// </summary>
/// <param name="gridFile">网格文件</param>
/// <param name="curveFile">等值线文件</param>
/// <param name="faultFile">断层文件</param>
/// <param name="outFile">结果输出文件</param>
/// <param name="curveLayer">等值线图层</param>
/// <param name="faultLayer">断层图层</param>
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<DfLine> 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<DfLine> dfFaults = curveReader.GetDfdLinesByLayer(faultLayer);
if (dfFaults == null || dfFaults.Count == 0)
{
return false;
}
List<Polygon> cooFaults = new List<Polygon>();
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<Polygon> 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<DfLine> 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<DfLine> 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<WellBase>().Min(w => w.X);
// var vXMax = DBHelp.Db.Queryable<WellBase>().Max(w => w.X);
// var vYMin = DBHelp.Db.Queryable<WellBase>().Min(w => w.Y);
// var vYMax = DBHelp.Db.Queryable<WellBase>().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;
//}
/// <summary>
/// 转换成相对路径
/// </summary>
/// <param name="fullPath">绝对路径</param>
/// <returns>相对路径</returns>
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;
}
/// <summary>
/// 转换到绝对路径
/// </summary>
/// <param name="relativePath">相对路径</param>
/// <returns>绝对路径</returns>
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;
}
/// <summary>
/// Gets the name of the backup file.
/// </summary>
/// <param name="sourceFile">The source file.</param>
/// <returns>System.String.</returns>
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; }
}
}