mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:16:30 +00:00
1b6c440dcc
todo: clear folders, consider better center point to fetch next batch from satellite provider
99 lines
3.7 KiB
C#
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);
|
|
}
|
|
}
|
|
|