2023-02-20 15:57:08 +05:00
|
|
|
|
using AsbCloudApp.Data;
|
|
|
|
|
using AsbCloudApp.Repositories;
|
|
|
|
|
using AsbCloudApp.Services;
|
2023-05-04 16:54:09 +05:00
|
|
|
|
using AsbCloudDb.Model;
|
|
|
|
|
using AsbCloudDb.Model.WITS;
|
2023-02-20 15:57:08 +05:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services.Trajectory
|
|
|
|
|
{
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2023-02-20 15:57:08 +05:00
|
|
|
|
public class TrajectoryVisualizationService : ITrajectoryVisualizationService
|
|
|
|
|
{
|
2023-05-04 16:54:09 +05:00
|
|
|
|
private readonly IPlannedTrajectoryRepository plannedRepository;
|
|
|
|
|
private readonly IFactualTrajectoryRepository factualRepository;
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
public TrajectoryVisualizationService(IPlannedTrajectoryRepository plannedRepository, IFactualTrajectoryRepository factualRepository)
|
2023-02-20 15:57:08 +05:00
|
|
|
|
{
|
2023-05-04 16:54:09 +05:00
|
|
|
|
this.plannedRepository = plannedRepository;
|
|
|
|
|
this.factualRepository = factualRepository;
|
2023-02-20 15:57:08 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Получение плановой и фактической траектории по скважине
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="idWell">ключ скважины</param>
|
|
|
|
|
/// <param name="token"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public async Task<PlanFactBase<IEnumerable<TrajectoryVisualizationDto>>> GetTrajectoryAsync(int idWell, CancellationToken token)
|
2023-02-20 15:57:08 +05:00
|
|
|
|
{
|
2023-05-04 16:54:09 +05:00
|
|
|
|
var result = new PlanFactBase<IEnumerable<TrajectoryVisualizationDto>>();
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
var geoPlanCoordinates = (await plannedRepository.GetAsync(idWell, token))
|
|
|
|
|
.Select(coord => new TrajectoryDto(coord.WellboreDepth, coord.ZenithAngle, coord.AzimuthGeo))
|
|
|
|
|
.ToArray();
|
|
|
|
|
var geoFactCoordinates = (await factualRepository.GetAsync(idWell, token))
|
|
|
|
|
.Select(coord => new TrajectoryDto(coord.Deptsvym, coord.Svyinc, coord.Svyazc))
|
|
|
|
|
.ToArray();
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
result.Plan = GetTrajectoryVisualisation(geoPlanCoordinates);
|
|
|
|
|
result.Fact = GetTrajectoryVisualisation(geoFactCoordinates);
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Формирует список координат для визуализации трактории 3D
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="geoCoordinates"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private List<TrajectoryVisualizationDto> GetTrajectoryVisualisation(TrajectoryDto[] geoCoordinates)
|
|
|
|
|
{
|
2023-02-20 15:57:08 +05:00
|
|
|
|
var cartesianCoordinates = new List<TrajectoryVisualizationDto>(geoCoordinates.Length) {
|
|
|
|
|
new (),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (var i = 1; i < geoCoordinates.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
var intervalGeoParams = geoCoordinates[i - 1];
|
|
|
|
|
var deltaWellLength = geoCoordinates[i].WellboreDepth - intervalGeoParams.WellboreDepth;
|
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
if (intervalGeoParams.ZenithAngle != null && intervalGeoParams.AzimuthGeo != null && deltaWellLength != null) {
|
|
|
|
|
|
|
|
|
|
var projectionLengthToXYSurface = deltaWellLength.Value * Math.Sin(intervalGeoParams.ZenithAngle.Value * Math.PI / 180);
|
|
|
|
|
|
|
|
|
|
var dz = deltaWellLength.Value * Math.Cos(intervalGeoParams.ZenithAngle.Value * Math.PI / 180);
|
|
|
|
|
var dx = projectionLengthToXYSurface * Math.Sin(intervalGeoParams.AzimuthGeo.Value * Math.PI / 180);
|
|
|
|
|
var dy = projectionLengthToXYSurface * Math.Cos(intervalGeoParams.AzimuthGeo.Value * Math.PI / 180);
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
var preCoordinates = cartesianCoordinates[i - 1];
|
|
|
|
|
var coordinates = new TrajectoryVisualizationDto
|
|
|
|
|
{
|
|
|
|
|
Z = preCoordinates.Z + dz,
|
|
|
|
|
X = preCoordinates.X + dx,
|
|
|
|
|
Y = preCoordinates.Y + dy,
|
|
|
|
|
};
|
2023-02-20 15:57:08 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
cartesianCoordinates.Add(coordinates);
|
|
|
|
|
}
|
2023-02-20 15:57:08 +05:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cartesianCoordinates;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-04-18 16:22:53 +05:00
|
|
|
|
|
2023-05-04 16:54:09 +05:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Класс для формирования визуализации траектории 3D
|
|
|
|
|
/// </summary>
|
|
|
|
|
internal class TrajectoryDto
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Глубина ствола
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double? WellboreDepth { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Зенитный угол
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double? ZenithAngle { get; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Азимут географиеский
|
|
|
|
|
/// </summary>
|
|
|
|
|
public double? AzimuthGeo { get; }
|
|
|
|
|
|
|
|
|
|
public TrajectoryDto(double? wellboreDepth, double? zenithAngle, double? azimuthGeo)
|
|
|
|
|
{
|
|
|
|
|
WellboreDepth = wellboreDepth;
|
|
|
|
|
ZenithAngle = zenithAngle;
|
|
|
|
|
AzimuthGeo = azimuthGeo;
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-02-20 15:57:08 +05:00
|
|
|
|
}
|