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#

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.

// <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();
}
}
}
}