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; } /// /// Получение плановой и фактической траектории по скважине /// /// ключ скважины /// /// public async Task>> GetTrajectoryAsync(int idWell, CancellationToken token) { var result = new PlanFactBase>(); 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; } /// /// Формирует список координат для визуализации трактории 3D /// /// /// private List GetTrajectoryVisualisation(TrajectoryDto[] geoCoordinates) { var cartesianCoordinates = new List(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; } } /// /// Класс для формирования визуализации траектории 3D /// internal class TrajectoryDto { /// /// Глубина ствола /// public double? WellboreDepth { get; } /// /// Зенитный угол /// public double? ZenithAngle { get; } /// /// Азимут географиеский /// public double? AzimuthGeo { get; } public TrajectoryDto(double? wellboreDepth, double? zenithAngle, double? azimuthGeo) { WellboreDepth = wellboreDepth; ZenithAngle = zenithAngle; AzimuthGeo = azimuthGeo; } } }