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

160 lines
5.7 KiB
C#
Raw Normal View History

2023-11-28 15:54:47 +05:00
using AsbCloudApp.Data.Trajectory;
2023-05-30 11:21:07 +05:00
using AsbCloudApp.Repositories;
using AsbCloudApp.Requests;
2023-05-30 11:21:07 +05:00
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace AsbCloudInfrastructure.Services.Trajectory;
abstract class TrajectoryBaseService<TGeo, TCartesian>
where TGeo : TrajectoryGeoDto
where TCartesian : TrajectoryCartesianDto, new()
{
private readonly ITrajectoryRepository<TGeo> repository;
2023-05-30 11:21:07 +05:00
public TrajectoryBaseService(ITrajectoryRepository<TGeo> 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<IEnumerable<TCartesian>?> GetAsync(int idWell, CancellationToken token)
{
2023-11-30 09:40:51 +05:00
var geoCoords = await repository.GetAsync(idWell, token);
var locs = TrajectoryBaseService<TGeo, TCartesian>.GetTrajectoryVisualisation(geoCoords);
2023-05-30 11:21:07 +05:00
var dtos = locs.Select(l => Convert(l));
return dtos;
}
private static IEnumerable<Location> GetTrajectoryVisualisation(IEnumerable<TrajectoryGeoDto> geoCoordinates)
2023-05-30 11:21:07 +05:00
{
var geoCoordinatesLength = geoCoordinates.Count();
if (geoCoordinatesLength < 2)
return Enumerable.Empty<Location>();
2023-05-30 11:21:07 +05:00
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 = TrajectoryBaseService<TGeo, TCartesian>.Calculate(cartesianCoordinates[i - 1],
2023-05-30 11:21:07 +05:00
geoCoordinatesArray[i - 1],
geoCoordinatesArray[i]);
cartesianCoordinates[i] = coordinates;
}
return cartesianCoordinates;
}
protected static Location Calculate(Location prevLocation, TrajectoryGeoDto prev, TrajectoryGeoDto current)
2023-05-30 11:21:07 +05:00
{
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,
2023-05-30 11:21:07 +05:00
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<TrajectoryGeoPlanDto, TrajectoryCartesianPlanDto>
{
public TrajectoryPlanService(ITrajectoryEditableRepository<TrajectoryGeoPlanDto> repository)
2023-05-30 11:21:07 +05:00
: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<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
{
public TrajectoryFactService(ITrajectoryEditableRepository<TrajectoryGeoFactDto> repository)
: base(repository)
{ }
}
class TrajectoryNnbService : TrajectoryBaseService<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
{
public TrajectoryNnbService(ITrajectoryNnbRepository repository)
2023-05-30 11:21:07 +05:00
: base(repository)
{ }
}
public class TrajectoryService
{
private readonly TrajectoryPlanService trajectoryPlanService;
private readonly TrajectoryFactService trajectoryFactService;
private readonly TrajectoryNnbService trajectoryNnbService;
2023-05-30 11:21:07 +05:00
public TrajectoryService(
2023-11-30 15:20:22 +05:00
ITrajectoryEditableRepository<TrajectoryGeoPlanDto> planRepository,
ITrajectoryEditableRepository<TrajectoryGeoFactDto> factRepository,
ITrajectoryNnbRepository nnbRepository)
2023-05-30 11:21:07 +05:00
{
2023-11-30 15:20:22 +05:00
trajectoryPlanService = new TrajectoryPlanService(planRepository);
2023-05-30 11:21:07 +05:00
trajectoryFactService = new TrajectoryFactService(factRepository);
trajectoryNnbService = new TrajectoryNnbService(nnbRepository);
2023-05-30 11:21:07 +05:00
}
/// <summary>
/// Получение плановой и фактической траектории по скважине
/// </summary>
/// <param name="idWell">ключ скважины</param>
/// <param name="token"></param>
/// <returns></returns>
2023-11-28 15:54:47 +05:00
public async Task<TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token)
2023-05-30 11:21:07 +05:00
{
var result = new TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>
{
Plan = await trajectoryPlanService.GetAsync(idWell, token),
FactManual = await trajectoryFactService.GetAsync(idWell, token),
FactNnb = await trajectoryNnbService.GetAsync(idWell, token)
};
2023-05-30 11:21:07 +05:00
return result;
}
}