mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 13:06:31 +00:00
update AI initializing
rework AIAvailabilityStatus events to mediatr
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
using System.IO;
|
||||
using Azaion.Common.DTO;
|
||||
using Azaion.Common.DTO.Config;
|
||||
using Azaion.Common.Extensions;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Azaion.Common.Services;
|
||||
|
||||
public interface IGpsMatcherService
|
||||
{
|
||||
Task RunGpsMatching(string userRouteDir, GeoPoint geoPoint, CancellationToken detectToken = default);
|
||||
void StopGpsMatching();
|
||||
Task SetGpsResult(GPSMatcherResultEvent result, CancellationToken detectToken = default);
|
||||
Task FinishGPS(GPSMatcherFinishedEvent notification, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
public class GpsMatcherService(IGpsMatcherClient gpsMatcherClient,
|
||||
ISatelliteDownloader satelliteTileDownloader,
|
||||
IOptions<DirectoriesConfig> dirConfig,
|
||||
IOptions<GpsDeniedConfig> gpsDeniedConfig,
|
||||
IMediator mediator) : IGpsMatcherService
|
||||
{
|
||||
private readonly DirectoriesConfig _dirConfig = dirConfig.Value;
|
||||
private const int ZOOM_LEVEL = 18;
|
||||
private const int POINTS_COUNT = 10;
|
||||
private const int DISTANCE_BETWEEN_POINTS_M = 140;
|
||||
private const double SATELLITE_RADIUS_M = DISTANCE_BETWEEN_POINTS_M * (POINTS_COUNT + 1);
|
||||
private const int MAX_AVG_POINTS = 2;
|
||||
|
||||
private string _routeDir = "";
|
||||
private string _userRouteDir = "";
|
||||
private List<string> _allRouteImages = new();
|
||||
private Dictionary<string, int> _currentRouteImages = new();
|
||||
private GeoPoint _lastGeoPoint = new();
|
||||
private CancellationToken _detectToken;
|
||||
private int _currentIndex;
|
||||
private readonly Queue<Direction> _directions = new();
|
||||
|
||||
|
||||
public async Task RunGpsMatching(string userRouteDir, GeoPoint initGeoPoint, CancellationToken detectToken = default)
|
||||
{
|
||||
_routeDir = Path.Combine(Constants.EXTERNAL_GPS_DENIED_FOLDER, _dirConfig.GpsRouteDirectory);
|
||||
_userRouteDir = userRouteDir;
|
||||
|
||||
_allRouteImages = Directory.GetFiles(userRouteDir)
|
||||
.OrderBy(x => x).ToList();
|
||||
_lastGeoPoint = initGeoPoint;
|
||||
_detectToken = detectToken;
|
||||
await StartMatchingRound(0);
|
||||
}
|
||||
|
||||
private async Task StartMatchingRound(int startIndex)
|
||||
{
|
||||
//empty route dir
|
||||
if (Directory.Exists(_routeDir))
|
||||
Directory.Delete(_routeDir, true);
|
||||
Directory.CreateDirectory(_routeDir);
|
||||
|
||||
_currentRouteImages = _allRouteImages
|
||||
.Skip(startIndex)
|
||||
.Take(POINTS_COUNT)
|
||||
.Select((fullName, index) =>
|
||||
{
|
||||
var filename = Path.GetFileName(fullName);
|
||||
File.Copy(Path.Combine(_userRouteDir, filename), Path.Combine(_routeDir, filename));
|
||||
return new { Filename = Path.GetFileNameWithoutExtension(fullName), Index = startIndex + index };
|
||||
})
|
||||
.ToDictionary(x => x.Filename, x => x.Index);
|
||||
|
||||
await satelliteTileDownloader.GetTiles(_lastGeoPoint, SATELLITE_RADIUS_M, ZOOM_LEVEL, _detectToken);
|
||||
await gpsMatcherClient.StartMatching(new StartMatchingEvent
|
||||
{
|
||||
ImagesCount = POINTS_COUNT,
|
||||
GeoPoint = _lastGeoPoint,
|
||||
SatelliteImagesDir = _dirConfig.GpsSatDirectory,
|
||||
RouteDir = _dirConfig.GpsRouteDirectory
|
||||
});
|
||||
}
|
||||
|
||||
public void StopGpsMatching()
|
||||
{
|
||||
gpsMatcherClient.Stop();
|
||||
}
|
||||
|
||||
public async Task SetGpsResult(GPSMatcherResultEvent result, CancellationToken detectToken = default)
|
||||
{
|
||||
_currentIndex = _currentRouteImages[result.Image];
|
||||
_currentRouteImages.Remove(result.Image);
|
||||
|
||||
if (result.KeyPoints >= gpsDeniedConfig.Value.MinKeyPoints)
|
||||
{
|
||||
var direction = _lastGeoPoint.DirectionTo(result.GeoPoint);
|
||||
_directions.Enqueue(direction);
|
||||
if (_directions.Count > MAX_AVG_POINTS)
|
||||
_directions.Dequeue();
|
||||
_lastGeoPoint = result.GeoPoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
var direction = new Direction(_directions.Average(x => x.Distance), _directions.Average(x => x.Azimuth));
|
||||
_lastGeoPoint = _lastGeoPoint.GoDirection(direction);
|
||||
}
|
||||
await mediator.Publish(new GPSMatcherResultProcessedEvent(result, _lastGeoPoint), detectToken);
|
||||
}
|
||||
|
||||
public async Task FinishGPS(GPSMatcherFinishedEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
if (_currentRouteImages.Count == 0 && _currentIndex < _allRouteImages.Count)
|
||||
await StartMatchingRound(_currentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user