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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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; }
}
}