Files
annotations/Azaion.Common/Services/GPSMatcherService.cs
T
Alex Bezdieniezhnykh 1b6c440dcc fix re-send new batch to gps denied
todo: clear folders, consider better center point to fetch next batch from satellite provider
2025-05-30 11:03:00 +03:00

99 lines
3.7 KiB
C#

using System.IO;
using Azaion.CommonSecurity;
using Azaion.CommonSecurity.DTO;
using Microsoft.Extensions.Options;
namespace Azaion.Common.Services;
public interface IGpsMatcherService
{
Task RunGpsMatching(string userRouteDir, double initialLatitude, double initialLongitude, 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) : 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 = 100;
private const double SATELLITE_RADIUS_M = DISTANCE_BETWEEN_POINTS_M * (POINTS_COUNT + 1);
private string _routeDir = "";
private string _userRouteDir = "";
private List<string> _allRouteImages = new();
private Dictionary<string, int> _currentRouteImages = new();
private double _currentLat;
private double _currentLon;
private CancellationToken _detectToken;
private int _currentIndex;
public async Task RunGpsMatching(string userRouteDir, double initialLatitude, double initialLongitude, CancellationToken detectToken = default)
{
_routeDir = Path.Combine(SecurityConstants.EXTERNAL_GPS_DENIED_FOLDER, _dirConfig.GpsRouteDirectory);
_userRouteDir = userRouteDir;
_allRouteImages = Directory.GetFiles(userRouteDir)
.OrderBy(x => x).ToList();
_currentLat = initialLatitude;
_currentLon = initialLongitude;
_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(_currentLat, _currentLon, SATELLITE_RADIUS_M, ZOOM_LEVEL, _detectToken);
await gpsMatcherClient.StartMatching(new StartMatchingEvent
{
ImagesCount = POINTS_COUNT,
Latitude = _currentLat,
Longitude = _currentLon,
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);
_currentLat = result.Latitude;
_currentLon = result.Longitude;
await Task.CompletedTask;
}
public async Task FinishGPS(GPSMatcherFinishedEvent notification, CancellationToken cancellationToken)
{
if (_currentRouteImages.Count == 0 && _currentIndex < _allRouteImages.Count)
await StartMatchingRound(_currentIndex);
}
}