// // Copyright (c) jindongfang. All rights reserved. // //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 { /// /// Indexes the specified row. /// /// The row. /// System.Int32. public static int Index(this DataRow row) { if (row.Table != null) { return row.Table.Rows.IndexOf(row); } return -1; } /// /// Converts the list to data table. /// /// The list. /// A DataTable. public static DataTable ConvertListToDataTable(this List 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; } } /// /// 井斜计算工具 /// public class WellDeflectionHelp { private SimpleWell[] wells; private SimpleDeflection[] sysDeflections; // private List OrderDictKey = new List(); // private Dictionary sysDeflectionsDict = new Dictionary(); /// /// Initializes a new instance of the class. /// 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); } /// /// 井斜计算,最小曲率法 /// /// 井号 /// 是否成功 public static List ComputedTrackCurvature(string wellName) { // 先从数据库中获取到井斜文件数据 WellDeflection wd = DBHelp.NewDb.Queryable().Where(w => w.JH == wellName).First(); if (wd == null || string.IsNullOrWhiteSpace(wd.FileName)) { return null; } string fileName = wd.FileName; List 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; /// /// Fun the curvature. /// /// The md1. /// The i1. /// The a1. /// The md2. /// The i2. /// The a2. /// The north sec. /// The east sec. /// The tvd sec. 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; } /// /// Initializes the. /// /// The well name. /// The simple well name. /// SimpleDeflection /// A bool. public bool Initialize(string wellName, SimpleWell[] simpleWells, SimpleDeflection[] simpleDeflections) { try { this.wells = simpleWells.ToArray(); this.sysDeflections = simpleDeflections.ToArray(); //DBHelp.Db.Queryable().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; } } /// /// 数据准备 /// /// 是否成功 public bool Initialize() { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); this.wells = DBHelp.NewDb.Queryable() .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 sds = new ConcurrentBag(); // 查询所有井斜 var wds = DBHelp.NewDb.Queryable().ToList(); if (wds.Any()) { Parallel.ForEach(wds, EntityHelp.Options, item => { try { List 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; } /// /// 快速查找 /// /// 正向排序的井几何 /// 要查找的井 /// 查找到的索引 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; } /// /// 查找井斜数据 /// /// 井斜数据 /// 井号 /// 目的井深 /// 查找方式,0-查找上方,1查找下方 /// 查找结果 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; } /// /// 根据测深计算井位坐标。TODO:是否与补芯有关 /// /// 井号 /// 测深 /// 坐标X /// 坐标Y /// 垂深 /// 是否计算成功 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; } /// /// 查找井斜数据 /// /// 井斜数据 /// 井号 /// 垂深 /// 查找方式,0-查找上方,1查找下方 /// 查找结果 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; } /// /// 由垂深计算坐标. /// /// Name of the well. /// The vertical. /// The x. /// The y. /// 是否成功 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; } /// /// 由测深计算井斜XY坐标. (pnp重写) /// /// Name of the well. /// The vertical. /// The x. /// The y. /// 是否成功 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; } /// /// 由测深计算井斜XY坐标. (pnp重写) /// /// Name of the well. /// The vertical. /// The x. /// The y. /// 是否成功 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; } /// /// 由测深通过井斜计算垂深. (pnp重写) /// /// 井号 /// 测深 /// 垂深 /// 是否计算成功 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; } /// /// 由垂深通过井斜计算测深. (pnp重写) /// /// The well name. /// The vertical. /// The detection. /// 是否计算成功 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(); //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; } /// /// 重新计算井斜坐标 /// /// 井斜 /// DataTable public DataTable ReCalcDepthByIncrementPoint(List wellDeflections) { using (SplashHelper splash = SplashHelper.Create()) { SplashHelper.SetDescription("正在重新计算井斜坐标..."); var jhs = wellDeflections.Select(d => d.JH).Distinct().ToList(); List defaultDeflections = new List(); foreach (var jh in jhs) { List 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(); // 增加密度的数据 foreach (var g in wellDeflections.GroupBy(w => w.JH)) { var densifyDeflectionJH = new List(); // 增加密度的数据 // 计算方位数据 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(); } } } }