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.

1359 lines
53 KiB
C#

1 month ago
// <copyright file="WellDeflectionHelp.cs" company="jindongfang">
// Copyright (c) jindongfang. All rights reserved.
// </copyright>
//using MessagePack;
using SqlSugar;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using WorkData;
using WorkData.Entity;
namespace WellWorkDataUI
{
public static class DataTableExtensions
{
/// <summary>
/// Indexes the specified row.
/// </summary>
/// <param name="row">The row.</param>
/// <returns>System.Int32.</returns>
public static int Index(this DataRow row)
{
if (row.Table != null)
{
return row.Table.Rows.IndexOf(row);
}
return -1;
}
/// <summary>
/// Converts the list to data table.
/// </summary>
/// <param name="list">The list.</param>
/// <returns>A DataTable.</returns>
public static DataTable ConvertListToDataTable<T>(this List<T> list)
{
DataTable table = new DataTable();
if (list.Count > 0)
{
var properties = typeof(T).GetProperties();
foreach (var prop in properties)
{
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
foreach (var item in list)
{
DataRow row = table.NewRow();
foreach (var prop in properties)
{
row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
}
table.Rows.Add(row);
}
}
return table;
}
}
/// <summary>
/// 井斜计算工具
/// </summary>
public class WellDeflectionHelp
{
private SimpleWell[] wells;
private SimpleDeflection[] sysDeflections;
// private List<string> OrderDictKey = new List<string>();
// private Dictionary<string, SimpleDeflection[]> sysDeflectionsDict = new Dictionary<string, SimpleDeflection[]>();
/// <summary>
/// Initializes a new instance of the <see cref="WellDeflectionHelp"/> class.
/// </summary>
public WellDeflectionHelp()
{
}
private static void FunRadius(double i1, double a1, double p, double i2, double a2, double md, out double northSec, out double eastSec, out double tvdSec)
{
northSec = md * (Math.Cos(i1) - Math.Cos(i2)) * (Math.Sin(a2) - Math.Sin(a1))
/ ((i2 - i1) * (a2 - a1)) * (180 / Math.PI) * (180 / Math.PI);
eastSec = md * (Math.Cos(i1) - Math.Cos(a1 * p)) * (Math.Cos(a1) - Math.Cos(a2))
/ ((i2 - i1) * (a2 - a1)) * (180 / Math.PI) * (180 / Math.PI);
tvdSec = md / 2 * (Math.Sin(i2) - Math.Sin(i1)) / (i2 - i1) * (180 / Math.PI);
}
/// <summary>
/// 井斜计算,最小曲率法
/// </summary>
/// <param name="wellName">井号</param>
/// <returns>是否成功</returns>
public static List<WellDeflection> ComputedTrackCurvature(string wellName)
{
// 先从数据库中获取到井斜文件数据
WellDeflection wd = DBHelp.NewDb.Queryable<WellDeflection>().Where(w => w.JH == wellName).First();
if (wd == null || string.IsNullOrWhiteSpace(wd.FileName))
{
return null;
}
string fileName = wd.FileName;
List<WellDeflection> deflections = EntityHelp.GetWellDeflections(fileName);
if (deflections == null || !deflections.Any())
{
return null;
}
//修复计算井斜有问题 bug禅道 421 井斜轨迹计算数据不从0开始计算出的数据是错误的
WellDeflection firstDeflection = deflections.FirstOrDefault();
//if (firstDeflection != null && firstDeflection.JS != 0 && firstDeflection.JXJ != 0 && firstDeflection.FWJ != 0)
if (firstDeflection != null)
{
WellDeflection deflectUppers = new WellDeflection()
{
JH = wellName,
JS = 0,
JXJ = 0,
FWJ = 0,
};
deflections.Insert(0, deflectUppers);
WellDeflection deflectUpper = new WellDeflection()
{
JH = wellName,
JS = 0,// -146.65,
JXJ = 0,
FWJ = 0,
BZB = 0,
DZB = 0,
CS = 0,
};
double md1 = deflectUpper.JS.Value; //deflectUpper.JS.Value; // 测深
double i1 = deflectUpper.JXJ.Value; //deflectUpper.JXJ.Value; // 井斜角
double a1 = deflectUpper.FWJ.Value; //deflectUpper.FWJ.Value; // 方位角
double north = deflectUpper.BZB.Value; // 北坐标
double east = deflectUpper.DZB.Value; // 东坐标
double tvd = deflectUpper.JS.Value; //; deflectUpper.CS.Value; // 垂深
double md2; // = deflections[0].JS.Value;
double i2; // = deflections[0].JXJ.Value;
double a2; // = deflections[0].FWJ.Value;
double northSec0 = 0, eastSec0 = 0, tvdSec0 = 0;
int nCount = deflections.Count;
for (int i = 0; i < nCount; i++)
{
if (!deflections[i].JXJ.HasValue || !deflections[i].FWJ.HasValue || !deflections[i].JS.HasValue)
{
continue;
}
md2 = deflections[i].JS.Value;
i2 = deflections[i].JXJ.Value;
a2 = deflections[i].FWJ.Value;
double northSec, eastSec, tvdSec;
FunCurvature(md1, i1, a1, md2, i2, a2, out northSec, out eastSec, out tvdSec);
if (i == 0)
{
northSec0 = northSec;
eastSec0 = eastSec;
tvdSec0 = tvdSec - md2;
}
north += northSec;
east += eastSec;
tvd += tvdSec;
deflections[i].BZB = north - northSec0;
deflections[i].DZB = east - eastSec0;
deflections[i].CS = tvd - tvdSec0;
md1 = md2;
i1 = i2;
a1 = a2;
}
return deflections;
}
else
{
return null;
}
}
private static double NEWARSET_TO_1 = 0.999995;
/// <summary>
/// Fun the curvature.
/// </summary>
/// <param name="md1">The md1.</param>
/// <param name="i1">The i1.</param>
/// <param name="a1">The a1.</param>
/// <param name="md2">The md2.</param>
/// <param name="i2">The i2.</param>
/// <param name="a2">The a2.</param>
/// <param name="northSec">The north sec.</param>
/// <param name="eastSec">The east sec.</param>
/// <param name="tvdSec">The tvd sec.</param>
private static void FunCurvature(double md1, double i1, double a1, double md2, double i2, double a2, out double northSec, out double eastSec, out double tvdSec)
{
double p = Math.PI / 180;
i1 = i1 * p;
a1 = a1 * p;
i2 = i2 * p;
a2 = a2 * p;
double dL = md2 - md1;
double dCosE = (Math.Cos(i1) * Math.Cos(i2)) + (Math.Sin(i1) * Math.Sin(i2) * Math.Cos(a2 - a1));
double dR = 0;
if (dCosE >= NEWARSET_TO_1 || dCosE <= NEWARSET_TO_1)
{
dR = 0.5;
}
else
{
double dE = Math.Acos(dCosE);
dR = Math.Tan(dE / 2) / dE;
}
northSec = ((Math.Sin(i1) * Math.Cos(a1)) + (Math.Sin(i2) * Math.Cos(a2))) * dL * dR;
eastSec = ((Math.Sin(i1) * Math.Sin(a1)) + (Math.Sin(i2) * Math.Sin(a2))) * dL * dR;
tvdSec = (Math.Cos(i1) + Math.Cos(i2)) * dL * dR;
}
/// <summary>
/// Initializes the.
/// </summary>
/// <param name="wellName">The well name.</param>
/// <param name="simpleWells">The simple well name.</param>
/// <param name="simpleDeflections">SimpleDeflection</param>
/// <returns>A bool.</returns>
public bool Initialize(string wellName, SimpleWell[] simpleWells, SimpleDeflection[] simpleDeflections)
{
try
{
this.wells = simpleWells.ToArray();
this.sysDeflections = simpleDeflections.ToArray();
//DBHelp.Db.Queryable<WellDeflection>().Select(it => new SimpleDeflection
//{
// JH = it.JH,
// BZB = it.BZB ?? 0,
// DZB = it.DZB ?? 0,
// JS = it.JS.Value,
// CS = it.CS ?? 0,
//}).Where(it => it.JH == wellName).ToArray();
return true;
}
catch (Exception ex)
{
Console.WriteLine($"~~~~~~~~~~~~~~执行 Initialize 异常:{ex.Message}~~~~~~~~~~~~~~");
return false;
}
}
/// <summary>
/// 数据准备
/// </summary>
/// <returns>是否成功</returns>
public bool Initialize()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
this.wells = DBHelp.NewDb.Queryable<WellBase>()
.Select(it => new SimpleWell() { JH = it.JH, X = it.X.Value, Y = it.Y.Value })
.Where(it => it.X > 0 && it.Y > 0).ToList()
.OrderBy(it => it.JH)
.ToArray();
Console.WriteLine($"初始化井基础,{stopwatch.Elapsed.TotalMilliseconds}");
ConcurrentBag<SimpleDeflection> sds = new ConcurrentBag<SimpleDeflection>();
// 查询所有井斜
var wds = DBHelp.NewDb.Queryable<WellDeflection>().ToList();
if (wds.Any())
{
Parallel.ForEach(wds, EntityHelp.Options, item =>
{
try
{
List<WellDeflection> itemDatas = EntityHelp.GetWellDeflections(item.FileName);
for (var i = 0; i < itemDatas.Count; i++)
{
var itemData = itemDatas[i];
sds.Add(new SimpleDeflection
{
JH = itemData.JH,
BZB = itemData.BZB ?? 0,
DZB = itemData.DZB ?? 0,
JS = itemData.JS.Value,
CS = itemData.CS ?? 0,
});
}
}
catch (Exception ex)
{
Console.WriteLine($"获取文件[{item.FileName}]数据异常:{ex.Message}");
}
});
}
if (sds.Any())
{
this.sysDeflections = sds.ToArray();
}
Console.WriteLine($"初始化井斜数据,{stopwatch.Elapsed.TotalMilliseconds}");
Console.WriteLine($"初始化井斜,{stopwatch.Elapsed.TotalMilliseconds}");
stopwatch.Stop();
Console.WriteLine($"初始化井斜字典,{stopwatch.Elapsed.TotalMilliseconds}");
return true;
}
/// <summary>
/// 快速查找
/// </summary>
/// <param name="wells">正向排序的井几何</param>
/// <param name="wellName">要查找的井</param>
/// <returns>查找到的索引</returns>
private int FindWellIndex(SimpleWell[] wells, string wellName)
{
//利用二分法快速定位
int num = wells.Length;
if (num == 0)
{
return -1;
}
int start = 0;
int stop = num - 1;
if (wells[start].JH.Equals(wellName))
{
return start;
}
if (wells[stop].JH.Equals(wellName))
{
return stop;
}
//if (z < colset[0].z) return -10;
//if (z > colset[num - 1].z) return num + 10;
int midle;
while (stop - start > 1)
{
midle = (start + stop) / 2;
if (string.CompareOrdinal(wellName, wells[midle].JH) < 0)
{
stop = midle;
}
else
{
start = midle;
}
}
if (wellName == wells[stop].JH)
{
return stop;
}
return start;
}
/// <summary>
/// 查找井斜数据
/// </summary>
/// <param name="deflections">井斜数据</param>
/// <param name="wellName">井号</param>
/// <param name="js">目的井深</param>
/// <param name="opType">查找方式,0-查找上方1查找下方</param>
/// <returns>查找结果</returns>
private SimpleDeflection FindDeflection(SimpleDeflection[] deflections, string wellName, double js, int opType)
{
int num = deflections.Length;
if (num == 0)
{
return null;
}
int start = 0;
int stop = num - 1;
if (deflections[start].JH.Equals(wellName))
{
if (opType == 0)
{
return SearchUpperInWells(deflections, start, wellName, js);
}
else
{
return SearchDownerInWells(deflections, start, wellName, js);
}
}
if (deflections[stop].JH.Equals(wellName))
{
if (opType == 0)
{
return SearchUpperInWells(deflections, stop, wellName, js);
}
else
{
return SearchDownerInWells(deflections, stop, wellName, js);
}
}
int midle;
while (stop - start > 1)
{
midle = (start + stop) / 2;
if (string.CompareOrdinal(wellName, deflections[midle].JH) < 0)
{
stop = midle;
}
else if (wellName.CompareTo(deflections[midle].JH) == 0)
{
stop = midle;
break;
}
else
{
start = midle;
}
}
if (wellName == deflections[stop].JH)
{
if (opType == 0)
{
return SearchUpperInWells(deflections, stop, wellName, js);
}
else
{
return SearchDownerInWells(deflections, stop, wellName, js);
}
}
// TODO可以使用插值二分法
SimpleDeflection SearchUpperInWells(SimpleDeflection[] sourceDeflections, int middleIndex, string wellNameDes, double jsDes)
{
int numSource = sourceDeflections.Length;
double dJSCur = sourceDeflections[middleIndex].JS;
if (dJSCur > jsDes)
{ // 向上查找
for (int i = middleIndex; i >= 0; i--)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].JS <= jsDes)
{
return sourceDeflections[i];
}
}
}
else if (dJSCur < jsDes)
{
for (int i = middleIndex; i < numSource; i++)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].JS > jsDes)
{
return sourceDeflections[i - 1];
}
}
}
else
{
return sourceDeflections[middleIndex];
}
return null;
}
SimpleDeflection SearchDownerInWells(SimpleDeflection[] sourceDeflections, int middleIndex, string wellNameDes, double jsDes)
{
int numSource = sourceDeflections.Length;
double dJSCur = sourceDeflections[middleIndex].JS;
if (dJSCur > jsDes)
{ // 向上查找
for (int i = middleIndex; i >= 0; i--)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].JS < jsDes)
{
return sourceDeflections[i + 1];
}
}
}
else if (dJSCur < jsDes)
{ // 向下查找
for (int i = middleIndex; i < numSource; i++)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].JS >= jsDes)
{
return sourceDeflections[i];
}
}
}
else
{
return sourceDeflections[middleIndex];
}
return null;
}
return null;
}
/// <summary>
/// 根据测深计算井位坐标。TODO:是否与补芯有关
/// </summary>
/// <param name="wellName">井号</param>
/// <param name="detection">测深</param>
/// <param name="x">坐标X</param>
/// <param name="y">坐标Y</param>
/// <param name="vertical">垂深</param>
/// <returns>是否计算成功</returns>
public bool ComputedXY(string wellName, double detection, ref double x, ref double y, ref double vertical)
{
// 井基础数据
int nWellIndex = this.FindWellIndex(this.wells, wellName);
if (nWellIndex < 0)
{
return false;
}
SimpleWell well = this.wells[nWellIndex];
SimpleDeflection deflectionDowner = this.FindDeflection(this.sysDeflections, wellName, detection, 1);
if (deflectionDowner != null && deflectionDowner.JS == detection)
{
// 坐标X
x = well.X + deflectionDowner.DZB;
// 坐标Y
y = well.Y + deflectionDowner.BZB;
return true;
}
SimpleDeflection deflectionUpper = this.FindDeflection(this.sysDeflections, wellName, detection, 0);
if (deflectionUpper != null && deflectionUpper.JS == detection)
{
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
return true;
}
if (deflectionDowner != null || deflectionUpper != null)
{
if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBefore = deflectionUpper.JS;
double dNext = deflectionDowner.JS;
double dFactor = (detection - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = (dFactor * (deflectionDowner.DZB - deflectionUpper.DZB))
+ deflectionUpper.DZB;
// 北坐标
double dOffsetY = (dFactor * (deflectionDowner.BZB - deflectionUpper.BZB))
+ deflectionUpper.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
// 垂深
//double dLastCS = deflectionBefore.CS;
//double dNextCS = deflectionNext.CS;
//vertical = (dFactor * (dNextCS - dLastCS)) + dLastCS;
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
// 垂深
double dLastCS = deflectionUpper.CS;
vertical = dLastCS + (detection - deflectionUpper.JS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.JS;
double dFactor = (detection - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = dFactor * deflectionDowner.DZB;
// 北坐标
double dOffsetY = dFactor * deflectionDowner.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
// 垂深
//double dLastCS = 0;
//double dNextCS = deflectionNext.CS;
//vertical = (dFactor * (dNextCS - dLastCS)) + dLastCS;
return true;
}
}
else
{
if (well != null)
{
x = well.X;
y = well.Y;
//vertical = detection;
return true;
}
}
return false;
}
/// <summary>
/// 查找井斜数据
/// </summary>
/// <param name="deflections">井斜数据</param>
/// <param name="wellName">井号</param>
/// <param name="vertical">垂深</param>
/// <param name="opType">查找方式,0-查找上方1查找下方</param>
/// <returns>查找结果</returns>
private SimpleDeflection FindDeflectionByVertical(SimpleDeflection[] deflections, string wellName, double vertical, int opType)
{
int num = deflections.Length;
if (num == 0)
{
return null;
}
int start = 0;
int stop = num - 1;
if (deflections[start].JH.Equals(wellName))
{
if (opType == 0)
{
return SearchUpperInWells(deflections, start, wellName, vertical);
}
else
{
return SearchDownerInWells(deflections, start, wellName, vertical);
}
}
if (deflections[stop].JH.Equals(wellName))
{
if (opType == 0)
{
return SearchUpperInWells(deflections, stop, wellName, vertical);
}
else
{
return SearchDownerInWells(deflections, stop, wellName, vertical);
}
}
int midle;
while (stop - start > 1)
{
midle = (start + stop) / 2;
if (string.CompareOrdinal(wellName, deflections[midle].JH) < 0)
{
stop = midle;
}
else if (wellName.CompareTo(deflections[midle].JH) == 0)
{
stop = midle;
break;
}
else
{
start = midle;
}
}
if (wellName == deflections[stop].JH)
{
if (opType == 0)
{
return SearchUpperInWells(deflections, stop, wellName, vertical);
}
else
{
return SearchDownerInWells(deflections, stop, wellName, vertical);
}
}
// TODO可以使用插值二分法
SimpleDeflection SearchUpperInWells(SimpleDeflection[] sourceDeflections, int middleIndex, string wellNameDes, double jsDes)
{
int numSource = sourceDeflections.Length;
double dJSCur = sourceDeflections[middleIndex].CS;
if (dJSCur > jsDes)
{ // 向上查找
for (int i = middleIndex; i >= 0; i--)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].CS <= jsDes)
{
return sourceDeflections[i];
}
}
}
else if (dJSCur < jsDes)
{
for (int i = middleIndex; i < numSource; i++)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].CS > jsDes)
{
return sourceDeflections[i - 1];
}
}
}
else
{
return sourceDeflections[middleIndex];
}
return null;
}
SimpleDeflection SearchDownerInWells(SimpleDeflection[] sourceDeflections, int middleIndex, string wellNameDes, double jsDes)
{
int numSource = sourceDeflections.Length;
double dJSCur = sourceDeflections[middleIndex].CS;
if (dJSCur > jsDes)
{ // 向上查找
for (int i = middleIndex; i >= 0; i--)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].CS < jsDes)
{
return sourceDeflections[i + 1];
}
}
}
else if (dJSCur < jsDes)
{ // 向下查找
for (int i = middleIndex; i < numSource; i++)
{
if (sourceDeflections[i].JH != wellNameDes)
{
return null;
}
if (sourceDeflections[i].CS >= jsDes)
{
return sourceDeflections[i];
}
}
}
else
{
return sourceDeflections[middleIndex];
}
return null;
}
return null;
}
/// <summary>
/// 由垂深计算坐标.
/// </summary>
/// <param name="wellName">Name of the well.</param>
/// <param name="vertical">The vertical.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns>是否成功</returns>
public bool ComputedXYByVertical(string wellName, double? vertical, ref double x, ref double y)
{
if (this.wells == null)
{
this.Initialize();
}
// 井基础数据
int nWellIndex = this.FindWellIndex(this.wells, wellName);
if (nWellIndex < 0)
{
return false;
}
SimpleWell well = this.wells[nWellIndex];
if (vertical == null)
{
// 坐标X
x = well.X;
// 坐标Y
y = well.Y;
return true;
}
SimpleDeflection deflectionDowner = this.FindDeflectionByVertical(this.sysDeflections, wellName, vertical.Value, 1);
if (deflectionDowner != null && deflectionDowner.CS == vertical)
{
// 坐标X
x = well.X + deflectionDowner.DZB;
// 坐标Y
y = well.Y + deflectionDowner.BZB;
return true;
}
SimpleDeflection deflectionUpper = this.FindDeflectionByVertical(this.sysDeflections, wellName, vertical.Value, 0);
if (deflectionUpper != null && deflectionUpper.CS == vertical)
{
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
return true;
}
if (deflectionDowner != null || deflectionUpper != null)
{
if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBefore = deflectionUpper.CS;
double dNext = deflectionDowner.CS;
double dFactor = (vertical.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = (dFactor * (deflectionDowner.DZB - deflectionUpper.DZB))
+ deflectionUpper.DZB;
// 北坐标
double dOffsetY = (dFactor * (deflectionDowner.BZB - deflectionUpper.BZB))
+ deflectionUpper.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
// 垂深
double dLastCS = deflectionUpper.CS;
vertical = dLastCS + (vertical - deflectionUpper.CS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.CS;
double dFactor = (vertical.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = dFactor * deflectionDowner.DZB;
// 北坐标
double dOffsetY = dFactor * deflectionDowner.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
}
else
{
if (well != null)
{
x = well.X;
y = well.Y;
//vertical = detection;
return true;
}
}
return false;
}
/// <summary>
/// 由测深计算井斜XY坐标. pnp重写
/// </summary>
/// <param name="wellName">Name of the well.</param>
/// <param name="detection">The vertical.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns>是否成功</returns>
public bool ComputedXYByDetection(string wellName, double? detection, ref double? x, ref double? y)
{
// 井基础数据
SimpleWell well = this.wells.FirstOrDefault(c => c.JH == wellName);
if (well == null)
{
x = null;
y = null;
return true;
}
if (detection == null)
{
// 坐标X
x = well.X;
// 坐标Y
y = well.Y;
return true;
}
var currtDeflections = this.sysDeflections.Where(a => a.JH == wellName).ToArray();
if (currtDeflections == null)
{
x = well.X;
y = well.Y;
return true;
}
//查找是否存在
SimpleDeflection deflectionCurrt = currtDeflections.FirstOrDefault(a => a.JS == detection.Value);
if (deflectionCurrt != null && deflectionCurrt.CS == detection)
{
// 坐标X
x = well.X + deflectionCurrt.DZB;
// 坐标Y
y = well.Y + deflectionCurrt.BZB;
return true;
}
//查找大于深度第一个
SimpleDeflection deflectionDowner = currtDeflections.Where(a => a.JS > detection.Value).OrderBy(a => a.JS).FirstOrDefault();
//查找小于深度第一个
SimpleDeflection deflectionUpper = currtDeflections.Where(a => a.JS < detection.Value).OrderByDescending(a => a.JS).FirstOrDefault();
if (deflectionDowner == null && deflectionUpper == null)
{
if (well != null)
{
x = well.X;
y = well.Y;
return true;
}
}
else if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBefore = deflectionUpper.JS;
double dNext = deflectionDowner.JS;
double dFactor = (detection.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = (dFactor * (deflectionDowner.DZB - deflectionUpper.DZB))
+ deflectionUpper.DZB;
// 北坐标
double dOffsetY = (dFactor * (deflectionDowner.BZB - deflectionUpper.BZB))
+ deflectionUpper.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
// 垂深
double dLastCS = deflectionUpper.JS;
detection = dLastCS + (detection - deflectionUpper.JS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.JS;
double dFactor = (detection.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = dFactor * deflectionDowner.DZB;
// 北坐标
double dOffsetY = dFactor * deflectionDowner.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
return false;
}
/// <summary>
/// 由测深计算井斜XY坐标. pnp重写
/// </summary>
/// <param name="wellName">Name of the well.</param>
/// <param name="vertical">The vertical.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
/// <returns>是否成功</returns>
public bool ComputedXYByVerticalNew(string wellName, double? vertical, ref double? x, ref double? y)
{
if (this.wells == null)
{
this.Initialize();
}
// 井基础数据
SimpleWell well = this.wells.FirstOrDefault(c => c.JH == wellName);
if (well == null)
{
x = null;
y = null;
return true;
}
if (vertical == null)
{
// 坐标X
x = well.X;
// 坐标Y
y = well.Y;
return true;
}
var currtDeflections = this.sysDeflections.Where(it => it.JH == wellName).ToList();
if (currtDeflections == null)
{
x = well.X;
y = well.Y;
return true;
}
//查找是否存在
SimpleDeflection deflectionCurrt = currtDeflections.FirstOrDefault(a => a.CS == vertical.Value);
if (deflectionCurrt != null && deflectionCurrt.JS == vertical)
{
// 坐标X
x = well.X + deflectionCurrt.DZB;
// 坐标Y
y = well.Y + deflectionCurrt.BZB;
return true;
}
//查找大于深度第一个
SimpleDeflection deflectionDowner = currtDeflections.Where(a => a.CS > vertical.Value).OrderBy(a => a.CS).FirstOrDefault();
//查找小于深度第一个
SimpleDeflection deflectionUpper = currtDeflections.Where(a => a.CS < vertical.Value).OrderByDescending(a => a.CS).FirstOrDefault();
if (deflectionDowner != null || deflectionUpper != null)
{
if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBefore = deflectionUpper.CS;
double dNext = deflectionDowner.CS;
double dFactor = (vertical.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = (dFactor * (deflectionDowner.DZB - deflectionUpper.DZB))
+ deflectionUpper.DZB;
// 北坐标
double dOffsetY = (dFactor * (deflectionDowner.BZB - deflectionUpper.BZB))
+ deflectionUpper.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 坐标X
x = well.X + deflectionUpper.DZB;
// 坐标Y
y = well.Y + deflectionUpper.BZB;
// 垂深
double dLastCS = deflectionUpper.CS;
vertical = dLastCS + (vertical - deflectionUpper.CS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.CS;
double dFactor = (vertical.Value - dBefore) / (dNext - dBefore);
// 东坐标
double dOffsetX = dFactor * deflectionDowner.DZB;
// 北坐标
double dOffsetY = dFactor * deflectionDowner.BZB;
// 坐标X
x = well.X + dOffsetX;
// 坐标Y
y = well.Y + dOffsetY;
return true;
}
}
else
{
if (well != null)
{
x = well.X;
y = well.Y;
return true;
}
}
return false;
}
/// <summary>
/// 由测深通过井斜计算垂深. pnp重写
/// </summary>
/// <param name="wellName">井号</param>
/// <param name="detection">测深</param>
/// <param name="vertical">垂深</param>
/// <returns>是否计算成功</returns>
public bool ComputedZByDetection(string wellName, double? detection, ref double? vertical)
{
if (!detection.HasValue)
{
return false;
}
// 井基础数据
if (!this.wells.Any(x => x.JH == wellName))
{
return false;
}
var currtDeflections = this.sysDeflections.Where(it => it.JH == wellName).ToList();
if (currtDeflections == null)
{
vertical = detection;
return true;
}
//查找是否存在
SimpleDeflection deflectionCurrt = currtDeflections.AsParallel().FirstOrDefault(a => a.JS == detection);
if (deflectionCurrt != null)
{
vertical = deflectionCurrt.CS;
return true;
}
//查找大于深度第一个底
SimpleDeflection deflectionDowner = currtDeflections.AsParallel().Where(a => a.JS > detection).OrderBy(a => a.JS).FirstOrDefault();
//查找小于深度第一个
SimpleDeflection deflectionUpper = currtDeflections.AsParallel().Where(a => a.JS < detection).OrderByDescending(a => a.JS).FirstOrDefault();
if (deflectionDowner != null || deflectionUpper != null)
{
if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBeforeJS = deflectionUpper.JS;
double dNextJS = deflectionDowner.JS;
double dBeforeCS = deflectionUpper.CS;
double dNextCS = deflectionDowner.CS;
double dFactor = (dNextCS - dBeforeCS) / (dNextJS - dBeforeJS);
vertical = dBeforeCS + ((detection.Value - dBeforeJS) * dFactor);
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 垂深
double dLastCS = deflectionUpper.CS;
vertical = dLastCS + (detection.Value - deflectionUpper.JS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.JS;
double dFactor = (detection.Value - dBefore) / (dNext - dBefore);
// 垂深
double dLastCS = 0;
double dNextCS = deflectionDowner.CS;
vertical = (dFactor * (dNextCS - dLastCS)) + dLastCS;
return true;
}
}
else
{
vertical = detection;
return true;
}
return false;
}
/// <summary>
/// 由垂深通过井斜计算测深. pnp重写
/// </summary>
/// <param name="wellName">The well name.</param>
/// <param name="vertical">The vertical.</param>
/// <param name="detection">The detection.</param>
/// <returns>是否计算成功</returns>
public bool ComputedZByVertical(string wellName, double? vertical, ref double? detection)
{
if (!vertical.HasValue)
{
return false;
}
// 井基础数据
if (!this.wells.Any(x => x.JH == wellName))
{
return false;
}
//SimpleWell well = this.wells[nWellIndex];
//var currtDeflections = new List<SimpleDeflection>();
//if (this.sysDeflectionsDict.ContainsKey(wellName))
//{
// currtDeflections = this.sysDeflectionsDict[wellName].ToList();
//}
var currtDeflections = this.sysDeflections.Where(it => it.JH == wellName).ToArray();
if (currtDeflections == null)
{
detection = vertical;
return true;
}
//查找是否存在
SimpleDeflection deflectionCurrt = currtDeflections.FirstOrDefault(a => a.CS == vertical);
if (deflectionCurrt != null)
{
detection = deflectionCurrt.JS;
return true;
}
//查找大于深度第一个
SimpleDeflection deflectionDowner = currtDeflections.Where(a => a.CS > vertical).OrderBy(a => a.CS).FirstOrDefault();
//查找小于深度第一个
SimpleDeflection deflectionUpper = currtDeflections.Where(a => a.CS < vertical).OrderByDescending(a => a.CS).FirstOrDefault();
if (deflectionDowner != null || deflectionUpper != null)
{
if (deflectionDowner != null && deflectionUpper != null)
{
// 斜井,计算层位坐标
double dBeforeJS = deflectionUpper.JS;
double dNextJS = deflectionDowner.JS;
double dBeforeCS = deflectionUpper.CS;
double dNextCS = deflectionDowner.CS;
double dFactor = (dNextJS - dBeforeJS) / (dNextCS - dBeforeCS);
detection = dBeforeJS + ((vertical.Value - dBeforeCS) * dFactor);
return true;
}
else if (deflectionDowner == null && deflectionUpper != null)
{ // 仅有上层数据时
// 垂深
double dLastJS = deflectionUpper.JS;
detection = dLastJS + (vertical.Value - deflectionUpper.CS);
return true;
}
else if (deflectionDowner != null && deflectionUpper == null)
{ // 仅有下层数据时
double dBefore = 0;
double dNext = deflectionDowner.CS;
double dFactor = (vertical.Value - dBefore) / (dNext - dBefore);
// 垂深
double dLastJS = 0;
double dNextJS = deflectionDowner.JS;
detection = (dFactor * (dNextJS - dLastJS)) + dLastJS;
return true;
}
}
else
{
detection = vertical;
return true;
}
return false;
}
/// <summary>
/// 重新计算井斜坐标
/// </summary>
/// <param name="wellDeflections">井斜</param>
/// <returns>DataTable</returns>
public DataTable ReCalcDepthByIncrementPoint(List<WellDeflection> wellDeflections)
{
using (SplashHelper splash = SplashHelper.Create())
{
SplashHelper.SetDescription("正在重新计算井斜坐标...");
var jhs = wellDeflections.Select(d => d.JH).Distinct().ToList();
List<WellDeflection> defaultDeflections = new List<WellDeflection>();
foreach (var jh in jhs)
{
List<WellDeflection> defaultDeflection = EntityHelp.GetWellDeflectionsByWellName(jh);
if (defaultDeflection != null && defaultDeflection.Any())
{
defaultDeflections.AddRange(defaultDeflection);
}
}
defaultDeflections = defaultDeflections.OrderBy(it => it.JS).ToList();
var spaceSize = DataHelp.WellDeflectionCollectCount;
var densifyDeflections = new List<WellDeflection>(); // 增加密度的数据
foreach (var g in wellDeflections.GroupBy(w => w.JH))
{
var densifyDeflectionJH = new List<WellDeflection>(); // 增加密度的数据
// 计算方位数据
var defaultDeflectionJH = defaultDeflections.Where(w => w.JH == g.Key).OrderBy(w => w.JS).ToList();
var maxJS = defaultDeflectionJH.Max(w => w.JS);
var firstDeflectionJH = defaultDeflectionJH[0]; // 新井号的第一条数据
firstDeflectionJH.XHID = densifyDeflections.Count + densifyDeflectionJH.Count + 1;
densifyDeflectionJH.Add(firstDeflectionJH);
// 补充方位数据
for (int i = 1; i < defaultDeflectionJH.Count; i++)
{
var preDeflection = defaultDeflectionJH[i - 1]; // 上一个
var deflection = defaultDeflectionJH[i]; // 当前
var meters = Convert.ToInt32(deflection.JS.Value - preDeflection.JS.Value);
// 计算两个记录之间,每一米的深度大小
var depthStep = Math.Abs(deflection.JS.Value - preDeflection.JS.Value) / meters;
var jxjStep = (deflection.JXJ ?? 0 - preDeflection.JXJ ?? 0) / meters;
var fwjStep = (deflection.FWJ ?? 0 - preDeflection.FWJ ?? 0) / meters;
var bzbStep = (deflection.BZB ?? 0 - preDeflection.BZB ?? 0) / meters;
var dzbStep = (deflection.DZB ?? 0 - preDeflection.DZB ?? 0) / meters;
var csStep = Math.Abs(deflection.CS ?? 0 - preDeflection.CS ?? 0) / meters;
int count = 1;
var nextJS = preDeflection.JS + (depthStep * spaceSize * count);
while (nextJS < deflection.JS)
{
nextJS = preDeflection.JS + (depthStep * spaceSize * count);
if (nextJS >= maxJS)
{
var item = defaultDeflectionJH.Last();
item.XHID = densifyDeflections.Count + densifyDeflectionJH.Count + 1;
densifyDeflectionJH.Add(item);
break;
}
else
{
densifyDeflectionJH.Add(new WellDeflection
{
XHID = densifyDeflections.Count + densifyDeflectionJH.Count + 1,
JH = g.Key,
JS = nextJS,
JXJ = preDeflection.JXJ + (jxjStep * spaceSize * count),
FWJ = preDeflection.FWJ + (fwjStep * spaceSize * count),
BZB = preDeflection.BZB + (bzbStep * spaceSize * count),
DZB = preDeflection.DZB + (dzbStep * spaceSize * count),
CS = preDeflection.CS + (csStep * spaceSize * count),
});
count++;
}
}
}
// 临时替换计算源
this.sysDeflections = densifyDeflectionJH.Select(d => new SimpleDeflection { JH = d.JH, JS = d.JS ?? 0, BZB = d.BZB ?? 0, DZB = d.DZB ?? 0, CS = d.CS ?? 0 }).ToArray();
foreach (var well in densifyDeflectionJH)
{
double x = 0, y = 0;
if (this.ComputedXYByVertical(well.JH, well.JS, ref x, ref y))
{
well.X = x;
well.Y = y;
}
}
densifyDeflections.AddRange(densifyDeflectionJH);
}
this.Initialize(); // 还原数据
return densifyDeflections.ConvertListToDataTable();
}
}
}
}