forked from ddrilling/AsbCloudServer
160 lines
5.6 KiB
C#
160 lines
5.6 KiB
C#
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<TGeo, TCartesian>
|
|
where TGeo : TrajectoryGeoDto
|
|
where TCartesian : TrajectoryCartesianDto, new()
|
|
{
|
|
private readonly ITrajectoryRepository<TGeo> repository;
|
|
|
|
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)
|
|
{
|
|
var geoCoords = await repository.GetAsync(idWell, token);
|
|
var locs = TrajectoryBaseService<TGeo, TCartesian>.GetTrajectoryVisualisation(geoCoords);
|
|
var dtos = locs.Select(l => Convert(l));
|
|
return dtos;
|
|
}
|
|
|
|
private static IEnumerable<Location> GetTrajectoryVisualisation(IEnumerable<TrajectoryGeoDto> geoCoordinates)
|
|
{
|
|
var geoCoordinatesLength = geoCoordinates.Count();
|
|
if (geoCoordinatesLength < 2)
|
|
return Enumerable.Empty<Location>();
|
|
|
|
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],
|
|
geoCoordinatesArray[i - 1],
|
|
geoCoordinatesArray[i]);
|
|
|
|
cartesianCoordinates[i] = coordinates;
|
|
}
|
|
|
|
return cartesianCoordinates;
|
|
}
|
|
|
|
protected static 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<TrajectoryGeoPlanDto, TrajectoryCartesianPlanDto>
|
|
{
|
|
public TrajectoryPlanService(ITrajectoryEditableRepository<TrajectoryGeoPlanDto> 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<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
|
|
{
|
|
public TrajectoryFactService(ITrajectoryEditableRepository<TrajectoryGeoFactDto> repository)
|
|
: base(repository)
|
|
{ }
|
|
}
|
|
|
|
class TrajectoryNnbService : TrajectoryBaseService<TrajectoryGeoFactDto, TrajectoryCartesianFactDto>
|
|
{
|
|
public TrajectoryNnbService(ITrajectoryNnbRepository repository)
|
|
: base(repository)
|
|
{ }
|
|
}
|
|
|
|
|
|
public class TrajectoryService
|
|
{
|
|
private readonly TrajectoryPlanService trajectoryPlanService;
|
|
private readonly TrajectoryFactService trajectoryFactService;
|
|
private readonly TrajectoryNnbService trajectoryNnbService;
|
|
|
|
public TrajectoryService(
|
|
ITrajectoryEditableRepository<TrajectoryGeoPlanDto> planRepository,
|
|
ITrajectoryEditableRepository<TrajectoryGeoFactDto> factRepository,
|
|
ITrajectoryNnbRepository nnbRepository)
|
|
{
|
|
trajectoryPlanService = new TrajectoryPlanService(planRepository);
|
|
trajectoryFactService = new TrajectoryFactService(factRepository);
|
|
trajectoryNnbService = new TrajectoryNnbService(nnbRepository);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Получение плановой и фактической траектории по скважине
|
|
/// </summary>
|
|
/// <param name="idWell">ключ скважины</param>
|
|
/// <param name="token"></param>
|
|
/// <returns></returns>
|
|
public async Task<TrajectoryPlanFactDto<IEnumerable<TrajectoryCartesianPlanDto>, IEnumerable<TrajectoryCartesianFactDto>>> GetTrajectoryCartesianAsync(int idWell, CancellationToken token)
|
|
{
|
|
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)
|
|
};
|
|
|
|
return result;
|
|
}
|
|
}
|