|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using DfdIO;
|
|
|
|
|
using NetTopologySuite.Geometries;
|
|
|
|
|
using NetTopologySuite.Operation.Distance;
|
|
|
|
|
using NetTopologySuite.Precision;
|
|
|
|
|
using NetTopologySuite.Operation.Relate;
|
|
|
|
|
using System.Diagnostics;
|
|
|
|
|
using NetTopologySuite.Algorithm;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
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 =>
|
|
|
|
|
Path.Combine(ExePath, "GridModel.exe");
|
|
|
|
|
|
|
|
|
|
public static string CurveModelPath =>
|
|
|
|
|
Path.Combine(ExePath, "CurveModel.exe");
|
|
|
|
|
|
|
|
|
|
private Encoding GB2312 => Encoding.GetEncoding("GB2312");
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 进程管理
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
private List<int> listProcessIds = new List<int>();
|
|
|
|
|
|
|
|
|
|
public void KillProgress()
|
|
|
|
|
{
|
|
|
|
|
for (int i = listProcessIds.Count - 1; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Process process = Process.GetProcessById(listProcessIds[i]);
|
|
|
|
|
process.Kill();
|
|
|
|
|
process.WaitForExit(500);
|
|
|
|
|
}
|
|
|
|
|
catch (ArgumentException)
|
|
|
|
|
{
|
|
|
|
|
// 进程已退出,忽略
|
|
|
|
|
}
|
|
|
|
|
catch (System.ComponentModel.Win32Exception)
|
|
|
|
|
{
|
|
|
|
|
// 权限不足等系统异常,忽略
|
|
|
|
|
}
|
|
|
|
|
listProcessIds.RemoveAt(i);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>网格化处理线程</summary>
|
|
|
|
|
public static Thread ProcessThread { get; set; } = null;
|
|
|
|
|
public static uint ProcessThreadId { get; set; } = 0;
|
|
|
|
|
|
|
|
|
|
[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);
|
|
|
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
|
|
|
static extern bool SetDllDirectory(string lpPathName);
|
|
|
|
|
|
|
|
|
|
/// <summary>终止网格化处理线程</summary>
|
|
|
|
|
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
|
|
|
|
|
public bool AboutGridProcess()
|
|
|
|
|
{
|
|
|
|
|
if (ProcessThread != null)
|
|
|
|
|
{
|
|
|
|
|
ProcessThread.Interrupt();
|
|
|
|
|
ProcessThread.Abort();
|
|
|
|
|
ProcessThread.Join();
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 核心:按参数创建地层图
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 按参数创建地层图。
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="flag">
|
|
|
|
|
/// 处理标识:
|
|
|
|
|
/// 0 — 网格化 + 等值线 + 断层内等值线清理 + 断层搭接;
|
|
|
|
|
/// 1 — 网格化 + 等值线 + 断层内等值线清理;
|
|
|
|
|
/// 2 — 网格化 + 等值线;
|
|
|
|
|
/// 3 — 仅网格化。
|
|
|
|
|
/// 默认值为 0。
|
|
|
|
|
/// </param>
|
|
|
|
|
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 strCurveFile = $"{outputDir}{fileName}.kev";
|
|
|
|
|
string strDfgFile = $"{outputDir}{fileName}.dfg";
|
|
|
|
|
|
|
|
|
|
var ctx = new GridCreateContext
|
|
|
|
|
{
|
|
|
|
|
Parameter = para,
|
|
|
|
|
InputFile = strInput,
|
|
|
|
|
OutputFile = strOutput,
|
|
|
|
|
OutlineFile = strOutline,
|
|
|
|
|
FaultFile = strFaultFile,
|
|
|
|
|
CurveFile = strCurveFile,
|
|
|
|
|
DfgFile = strDfgFile,
|
|
|
|
|
OutputDir = outputDir,
|
|
|
|
|
FileName = fileName,
|
|
|
|
|
Flag = flag,
|
|
|
|
|
ProgressChanged = ProgressChanged,
|
|
|
|
|
ProcessIds = listProcessIds,
|
|
|
|
|
GridModelExePath = XYZPath,
|
|
|
|
|
CurveModelExePath = CurveModelPath,
|
|
|
|
|
RunPostProcessing = (faultFile) =>
|
|
|
|
|
processAfterGrid(outputDir, fileName, flag, faultFile, strCurveFile, strDfgFile),
|
|
|
|
|
AppendFile = AppendFile,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return GridCreatorFactory.Get(para.CreateType).Execute(ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 dStep = Math.Max(dfg.DeltX, dfg.DeltY) * 2;
|
|
|
|
|
|
|
|
|
|
List<DfLine> extendCurves = LineOfExtend2Fault(dStep, strCurveFile, strFaultFile, "等值线", "断层");
|
|
|
|
|
|
|
|
|
|
string strCurveFileBak = CreateBackupFileName(strCurveFile);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 边界生成
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
public bool CreateBorder(string xyzFile, string outFile)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<Coordinate> coordinates = new List<Coordinate>();
|
|
|
|
|
using (StreamReader sr = new StreamReader(xyzFile, GB2312))
|
|
|
|
|
{
|
|
|
|
|
double dX = 0, dY = 0;
|
|
|
|
|
while (sr.Peek() > -1)
|
|
|
|
|
{
|
|
|
|
|
string strLine = sr.ReadLine();
|
|
|
|
|
string[] 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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var convexHullOp = new ConvexHull(coordinates, GeometryFactory.Default);
|
|
|
|
|
var ch = convexHullOp.GetConvexHull();
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool CreateBorder(DataTable data, string fileName)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
List<Coordinate> coordinates = new List<Coordinate>();
|
|
|
|
|
double dX = 0, dY = 0;
|
|
|
|
|
for (int i = 0; i < data.Rows.Count; 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 = "边界";
|
|
|
|
|
DfdWriter dfdWriter = new DfdWriter(fileName);
|
|
|
|
|
dfdWriter.WriteDfdLine(new List<DfLine>() { dfLine }, false);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 断层搭接
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
/// <summary>等值线搭接断层(按网格文件读取步长)</summary>
|
|
|
|
|
public void Extend2Fault(string gridFile, string curveFile, string faultFile, string outFile,
|
|
|
|
|
string curveLayer = "等值线", string faultLayer = "断层")
|
|
|
|
|
{
|
|
|
|
|
DfgReader dfg = new DfgReader(gridFile);
|
|
|
|
|
dfg.ReadHead();
|
|
|
|
|
double dStep = Math.Max(dfg.DeltX, dfg.DeltY) * 2;
|
|
|
|
|
WriteExtendedCurves(dStep, curveFile, faultFile, outFile, curveLayer, faultLayer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>等值线搭接断层(直接指定步长)</summary>
|
|
|
|
|
public void Extend2Fault(double dStep, string curveFile, string faultFile, string outFile,
|
|
|
|
|
string curveLayer = "等值线", string faultLayer = "断层")
|
|
|
|
|
{
|
|
|
|
|
WriteExtendedCurves(dStep, curveFile, faultFile, outFile, curveLayer, faultLayer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void WriteExtendedCurves(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>
|
|
|
|
|
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 = BuildFaultGeometries(dfFaults, minPoints: 4);
|
|
|
|
|
|
|
|
|
|
DfdElementReader elementReader = new DfdElementReader(fileName);
|
|
|
|
|
string strFileBack = CreateBackupFileName(fileName);
|
|
|
|
|
StreamWriter sw = new StreamWriter(strFileBack, false, GB2312);
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
elementReader.CurElementType = DfdIO.Elements.ElementType.ELEMENT_NONE;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DfLine lineNew = new DfLine();
|
|
|
|
|
Extent2Fault(eleLine, cooFaults, dStep, lineNew);
|
|
|
|
|
sw.WriteLine(lineNew.ToString(false));
|
|
|
|
|
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> dfCurves = curveReader.GetDfdLinesByLayer(curveLayer, 1);
|
|
|
|
|
List<DfLine> dfFaults = new DfdReader(faultFile).GetDfdLinesByLayer(faultLayer);
|
|
|
|
|
List<LineString> cooFaults = BuildFaultGeometries(dfFaults);
|
|
|
|
|
|
|
|
|
|
List<DfLine> dfLinesNew = new List<DfLine>();
|
|
|
|
|
int nCurvesCount = dfCurves.Count;
|
|
|
|
|
int nIndex = 0;
|
|
|
|
|
|
|
|
|
|
foreach (DfLine line in dfCurves)
|
|
|
|
|
{
|
|
|
|
|
int nPtCount = line.Points.Count;
|
|
|
|
|
if (nPtCount < 2) { nIndex++; continue; }
|
|
|
|
|
|
|
|
|
|
DfLine lineNew = line.Copy();
|
|
|
|
|
|
|
|
|
|
double dDistanceStart = dStep, dDistanceEnd = dStep;
|
|
|
|
|
LineString faultStart = null, 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);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < cooFaults.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
double dDist = new DistanceOp(cooFaults[i], new Point(ptStart2)).Distance();
|
|
|
|
|
if (dDist <= dDistanceStart) { dDistanceStart = dDist; faultStart = cooFaults[i]; }
|
|
|
|
|
|
|
|
|
|
dDist = new DistanceOp(cooFaults[i], new Point(ptEnd2)).Distance();
|
|
|
|
|
if (dDist <= dDistanceEnd) { dDistanceEnd = dDist; 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++;
|
|
|
|
|
ProgressChanged?.Invoke("断层搭接", (int)(((double)nIndex / nCurvesCount) * 100));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return dfLinesNew;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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, dDistanceEnd = dStep;
|
|
|
|
|
LineString faultStart = null, 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, bSkipTail = false;
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < cooFaults.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
if (!bSkipHead)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
var crossPt = GetCrossPt(ptStart1, ptStart2, faultStart, dStep);
|
|
|
|
|
lineDes.Points.Insert(0, new DfPoint(crossPt.X, crossPt.Y));
|
|
|
|
|
bSuccess = true;
|
|
|
|
|
}
|
|
|
|
|
if (faultEnd != null && !bSkipTail)
|
|
|
|
|
{
|
|
|
|
|
var crossPt = GetCrossPt(ptEnd1, ptEnd2, faultEnd, dStep);
|
|
|
|
|
lineDes.Points.Add(new DfPoint(crossPt.X, crossPt.Y));
|
|
|
|
|
bSuccess = true;
|
|
|
|
|
}
|
|
|
|
|
return bSuccess;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>将断层线列表转换为 NTS LineString 集合</summary>
|
|
|
|
|
private List<LineString> BuildFaultGeometries(List<DfLine> dfFaults, int minPoints = 2)
|
|
|
|
|
{
|
|
|
|
|
var result = new List<LineString>();
|
|
|
|
|
foreach (DfLine fault in dfFaults)
|
|
|
|
|
{
|
|
|
|
|
int nCount = fault.Points.Count;
|
|
|
|
|
if (nCount < minPoints) 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);
|
|
|
|
|
result.Add(new LineString(coordinates));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 断层内等值线清理
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
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, GB2312);
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
sw.WriteLine(eleLine.ToString(false));
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
LineString cooLine = new LineString(points);
|
|
|
|
|
foreach (Polygon polygon in cooFaults)
|
|
|
|
|
{
|
|
|
|
|
if (RelateOp.Relate(polygon, cooLine).IsCovers())
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 等值线搭接断层(就地修改绘图文件)
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
public void Curve2Fault(string drawFile, string curveLayer, string faultLayer)
|
|
|
|
|
{
|
|
|
|
|
DfdReader faultReader = new DfdReader(drawFile);
|
|
|
|
|
List<DfLine> dfFaults = faultReader.GetDfdLinesByLayer(faultLayer);
|
|
|
|
|
|
|
|
|
|
string strDfgFile = Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(drawFile),
|
|
|
|
|
Path.GetFileNameWithoutExtension(drawFile) + ".cfg");
|
|
|
|
|
if (!File.Exists(strDfgFile))
|
|
|
|
|
{
|
|
|
|
|
strDfgFile = Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(drawFile),
|
|
|
|
|
Path.GetFileNameWithoutExtension(drawFile) + ".dfg");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DfgReader dfg = new DfgReader(strDfgFile);
|
|
|
|
|
dfg.ReadHead();
|
|
|
|
|
double dStep = Math.Max(dfg.DeltX, dfg.DeltY) * 2;
|
|
|
|
|
|
|
|
|
|
List<DfLine> extendCurves = LineOfExtend2Fault(dStep, drawFile, drawFile, curveLayer);
|
|
|
|
|
|
|
|
|
|
DfdWriter dfdWriter = new DfdWriter(drawFile);
|
|
|
|
|
dfdWriter.WriteDfg(strDfgFile, "背景", false);
|
|
|
|
|
dfdWriter.WriteDfdLine(extendCurves, true);
|
|
|
|
|
dfdWriter.WriteDfdLine(dfFaults, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 几何辅助
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
private Coordinate GetCrossPt(Coordinate pt1, Coordinate pt2, Geometry fault, double offset)
|
|
|
|
|
{
|
|
|
|
|
double dR = Math.Sqrt((pt2.Y - pt1.Y) * (pt2.Y - pt1.Y) + (pt2.X - pt1.X) * (pt2.X - pt1.X));
|
|
|
|
|
double dT = dR + offset;
|
|
|
|
|
double dXOffset = pt1.X + (pt2.X - pt1.X) / dR * dT;
|
|
|
|
|
double dYOffset = pt1.Y + (pt2.Y - pt1.Y) / dR * dT;
|
|
|
|
|
|
|
|
|
|
Coordinate[] linePts = { pt2, new Coordinate(dXOffset, dYOffset) };
|
|
|
|
|
LineString linear = new LineString(linePts);
|
|
|
|
|
var crossPts = EnhancedPrecisionOp.Intersection(linear, fault);
|
|
|
|
|
|
|
|
|
|
if (crossPts.Coordinates.Length == 0) return linePts[0];
|
|
|
|
|
if (crossPts.Coordinates.Length == 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 文件辅助
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
public void AppendFile(string fileSource, string fileAppend)
|
|
|
|
|
{
|
|
|
|
|
string strAppendData;
|
|
|
|
|
using (StreamReader sr = new StreamReader(fileAppend, GB2312))
|
|
|
|
|
{
|
|
|
|
|
strAppendData = sr.ReadToEnd();
|
|
|
|
|
}
|
|
|
|
|
using (StreamWriter sw = new StreamWriter(fileSource, true, GB2312))
|
|
|
|
|
{
|
|
|
|
|
sw.WriteLine(strAppendData);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>在指定目录及其子目录中递归查找指定名称的文件</summary>
|
|
|
|
|
public string SearchFolder(string dirName, string layerName)
|
|
|
|
|
{
|
|
|
|
|
DirectoryInfo dir = new DirectoryInfo(dirName);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
foreach (DirectoryInfo d in dir.GetDirectories())
|
|
|
|
|
{
|
|
|
|
|
string 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))
|
|
|
|
|
{
|
|
|
|
|
return f.FullName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception e)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine(e.Message);
|
|
|
|
|
}
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
// 路径辅助
|
|
|
|
|
// ─────────────────────────────────────────────────────────────────────
|
|
|
|
|
|
|
|
|
|
public string Convert2RelativePath(string root, string fullPath)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(fullPath)) return string.Empty;
|
|
|
|
|
if (fullPath.StartsWith(root, StringComparison.CurrentCultureIgnoreCase))
|
|
|
|
|
return fullPath.Remove(0, root.Length + 1);
|
|
|
|
|
return fullPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public string Convert2AbsolutePath(string root, string relativePath)
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrWhiteSpace(relativePath)) return string.Empty;
|
|
|
|
|
if (string.IsNullOrEmpty(root)) return relativePath;
|
|
|
|
|
if (!relativePath.StartsWith(root, StringComparison.CurrentCultureIgnoreCase))
|
|
|
|
|
return Path.Combine(root, relativePath);
|
|
|
|
|
return relativePath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static string CreateBackupFileName(string sourceFile)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (string.IsNullOrEmpty(sourceFile)) return null;
|
|
|
|
|
return Path.Combine(
|
|
|
|
|
Path.GetDirectoryName(sourceFile),
|
|
|
|
|
Path.GetFileNameWithoutExtension(sourceFile) + "_bak" + Path.GetExtension(sourceFile));
|
|
|
|
|
}
|
|
|
|
|
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; }
|
|
|
|
|
}
|
|
|
|
|
}
|