using AsbCloudApp.Data.Trajectory; using AsbCloudApp.Repositories; using AsbCloudApp.Requests; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services.Trajectory; abstract class TrajectoryBaseService where TGeo : TrajectoryGeoDto where TCartesian : TrajectoryCartesianDto, new() { ITrajectoryRepository repository; public TrajectoryBaseService(ITrajectoryRepository repository) { this.repository = repository; } protected class Location { public double North { get; set; } public double East { get; set; } public double Depth { get; set; } public TrajectoryGeoDto Trajectory { get; set; } = null!; } public async Task?> GetAsync(int idWell, CancellationToken token) { var geoCoords = await repository.GetAsync(idWell, token); var locs = GetTrajectoryVisualisation(geoCoords); var dtos = locs.Select(l => Convert(l)); return dtos; } private IEnumerable GetTrajectoryVisualisation(IEnumerable geoCoordinates) { var geoCoordinatesLength = geoCoordinates.Count(); if (geoCoordinatesLength < 2) return new Location[0]; var cartesianCoordinates = new Location[geoCoordinatesLength]; cartesianCoordinates[0] = new(); var geoCoordinatesArray = geoCoordinates.OrderBy(c => c.WellboreDepth).ToArray(); for (var i = 1; i < geoCoordinatesLength; i++) { var coordinates = Calculate(cartesianCoordinates[i - 1], geoCoordinatesArray[i - 1], geoCoordinatesArray[i]); cartesianCoordinates[i] = coordinates; } return cartesianCoordinates; } protected Location Calculate(Location prevlocation, TrajectoryGeoDto prev, TrajectoryGeoDto current) { var intervalGeoParams = prev; var deltaWellLength = current.WellboreDepth - intervalGeoParams.WellboreDepth; var projectionLengthToXYSurface = deltaWellLength * Math.Sin(intervalGeoParams.ZenithAngle * Math.PI / 180); var dDepth = deltaWellLength * Math.Cos(intervalGeoParams.ZenithAngle * Math.PI / 180); var dNorth = projectionLengthToXYSurface * Math.Sin(intervalGeoParams.AzimuthGeo * Math.PI / 180); var dEast = projectionLengthToXYSurface * Math.Cos(intervalGeoParams.AzimuthGeo * Math.PI / 180); return new() { North = prevlocation.North + dNorth, East = prevlocation.East + dEast, Depth = prevlocation.Depth + dDepth, Trajectory = current, }; } protected virtual TCartesian Convert(Location location) { var result = new TCartesian() { X = location.East, Y = -location.Depth, Z = -location.North, }; return result; } } class TrajectoryPlanService: TrajectoryBaseService { public TrajectoryPlanService(ITrajectoryEditableRepository repository) :base(repository) {} protected override TrajectoryCartesianPlanDto Convert(Location location) { var result = base.Convert(location); if (location.Trajectory is TrajectoryGeoPlanDto trajectoryPlan) { result.Radius = trajectoryPlan.Radius; result.Comment = trajectoryPlan.Comment; } return result; } } class TrajectoryFactService : TrajectoryBaseService { public TrajectoryFactService(ITrajectoryEditableRepository repository) : base(repository) { } } class TrajectoryNnbService : TrajectoryBaseService { public TrajectoryNnbService(ITrajectoryNnbRepository repository) : base(repository) { } } public class TrajectoryService { private TrajectoryPlanService trajectoryPlanService; private TrajectoryFactService trajectoryFactService; private TrajectoryNnbService trajectoryNnbService; public TrajectoryService( ITrajectoryEditableRepository plannedRepository, ITrajectoryEditableRepository factRepository, ITrajectoryNnbRepository nnbRepository) { trajectoryPlanService = new TrajectoryPlanService(plannedRepository); trajectoryFactService = new TrajectoryFactService(factRepository); trajectoryNnbService = new TrajectoryNnbService(nnbRepository); } /// /// Получение плановой и фактической траектории по скважине /// /// ключ скважины /// /// public async Task, IEnumerable>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token) { var result = new TrajectoryPlanFactDto, IEnumerable>(); result.Plan = await trajectoryPlanService.GetAsync(idWell, token); result.FactManual = await trajectoryFactService.GetAsync(idWell, token); result.FactNnb = await trajectoryNnbService.GetAsync(idWell, token); return result; } }