DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/Trajectory/TrajectoryVisualizationService.cs

117 lines
4.6 KiB
C#

using AsbCloudApp.Data;
using AsbCloudApp.Repositories;
using AsbCloudApp.Services;
using AsbCloudDb.Model;
using AsbCloudDb.Model.WITS;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Trajectory
{
public class TrajectoryVisualizationService : ITrajectoryVisualizationService
{
private readonly IPlannedTrajectoryRepository plannedRepository;
private readonly IFactualTrajectoryRepository factualRepository;
public TrajectoryVisualizationService(IPlannedTrajectoryRepository plannedRepository, IFactualTrajectoryRepository factualRepository)
{
this.plannedRepository = plannedRepository;
this.factualRepository = factualRepository;
}
/// <summary>
/// Получение плановой и фактической траектории по скважине
/// </summary>
/// <param name="idWell">ключ скважины</param>
/// <param name="token"></param>
/// <returns></returns>
public async Task<PlanFactBase<IEnumerable<TrajectoryVisualizationDto>>> GetTrajectoryAsync(int idWell, CancellationToken token)
{
var result = new PlanFactBase<IEnumerable<TrajectoryVisualizationDto>>();
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();
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)
{
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;
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);
var preCoordinates = cartesianCoordinates[i - 1];
var coordinates = new TrajectoryVisualizationDto
{
Z = preCoordinates.Z + dz,
X = preCoordinates.X + dx,
Y = preCoordinates.Y + dy,
};
cartesianCoordinates.Add(coordinates);
}
}
return cartesianCoordinates;
}
}
/// <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;
}
}
}