mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:06:30 +00:00
a5c72c49f1
lower expectations from gmaps, enlarge size of download map
114 lines
4.3 KiB
C#
114 lines
4.3 KiB
C#
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 = 120;
|
|
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(SecurityConstants.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);
|
|
}
|
|
}
|
|
|