add gps matcher service

This commit is contained in:
Alex Bezdieniezhnykh
2025-04-14 09:50:34 +03:00
parent 36b3bf1712
commit ca1682a86e
26 changed files with 759 additions and 119 deletions
+5 -2
View File
@@ -52,6 +52,7 @@ public partial class Annotator
private readonly TimeSpan _thresholdBefore = TimeSpan.FromMilliseconds(50);
private readonly TimeSpan _thresholdAfter = TimeSpan.FromMilliseconds(150);
private readonly IGpsMatcherService _gpsMatcherService;
private static readonly Guid SaveConfigTaskId = Guid.NewGuid();
public ObservableCollection<MediaFileInfo> AllMediaFiles { get; set; } = new();
@@ -70,7 +71,8 @@ public partial class Annotator
ILogger<Annotator> logger,
AnnotationService annotationService,
IDbFactory dbFactory,
IInferenceService inferenceService)
IInferenceService inferenceService,
IGpsMatcherService gpsMatcherService)
{
InitializeComponent();
@@ -85,6 +87,7 @@ public partial class Annotator
_annotationService = annotationService;
_dbFactory = dbFactory;
_inferenceService = inferenceService;
_gpsMatcherService = gpsMatcherService;
Loaded += OnLoaded;
Closed += OnFormClosed;
@@ -106,7 +109,7 @@ public partial class Annotator
};
Editor.GetTimeFunc = () => TimeSpan.FromMilliseconds(_mediaPlayer.Time);
MapMatcherComponent.Init(_appConfig);
MapMatcherComponent.Init(_appConfig, _gpsMatcherService);
}
private void OnLoaded(object sender, RoutedEventArgs e)
+1 -1
View File
@@ -13,7 +13,7 @@
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
<PackageReference Include="MediatR" Version="12.4.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="9.0.3" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.0" />
+64 -19
View File
@@ -24,30 +24,75 @@
HorizontalAlignment="Stretch"
Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="28"></RowDefinition>
<RowDefinition Height="28"></RowDefinition>
<RowDefinition Height="28"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBox
Grid.Column="0"
<Grid
Grid.Row="0"
HorizontalAlignment="Stretch"
Margin="1"
x:Name="TbGpsMapFolder"></TextBox>
<Button
Grid.Row="0"
Grid.Column="1"
Margin="1"
Click="OpenGpsTilesFolderClick">
. . .
</Button>
<ListView Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="32"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox
Grid.Column="0"
Grid.Row="0"
HorizontalAlignment="Stretch"
Margin="1"
x:Name="TbGpsMapFolder"></TextBox>
<Button
Grid.Row="0"
Grid.Column="1"
Margin="1"
Click="OpenGpsTilesFolderClick">
. . .
</Button>
</Grid>
<Grid
Grid.Row="1"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- <TextBlock -->
<!-- Grid.Column="0" -->
<!-- Text="Lat" -->
<!-- Background="Gray"/> -->
<Button
Grid.Column="0"
Margin="1"
Click="TestGps">
Test
</Button>
<TextBox
Grid.Column="1"
HorizontalAlignment="Stretch"
x:Name="TbLat"
Text="48.2748909"></TextBox>
</Grid>
<Grid
Grid.Row="2"
HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text="Lon"
Background="Gray"/>
<TextBox
Grid.Column="1"
HorizontalAlignment="Stretch"
x:Name="TbLon"
Text="37.3834877"></TextBox>
</Grid>
<ListView Grid.Row="3"
Name="GpsFiles"
Background="Black"
SelectedItem="{Binding Path=SelectedVideo}"
+44 -48
View File
@@ -11,6 +11,7 @@ using Azaion.Common.Database;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using Azaion.Common.Extensions;
using Azaion.Common.Services;
using GMap.NET;
using GMap.NET.MapProviders;
using GMap.NET.WindowsPresentation;
@@ -22,17 +23,19 @@ public partial class MapMatcher : UserControl
{
private AppConfig _appConfig;
List<MediaFileInfo> _allMediaFiles;
private Dictionary<string, Annotation> _annotations;
private Dictionary<int, Annotation> _annotations;
private string _currentDir;
private IGpsMatcherService _gpsMatcherService;
public MapMatcher()
{
InitializeComponent();
}
public void Init(AppConfig appConfig)
public void Init(AppConfig appConfig, IGpsMatcherService gpsMatcherService)
{
_appConfig = appConfig;
_gpsMatcherService = gpsMatcherService;
GoogleMapProvider.Instance.ApiKey = appConfig.MapConfig.ApiKey;
SatelliteMap.MapProvider = GMapProviders.GoogleSatelliteMap;
SatelliteMap.Position = new PointLatLng(48.295985271707664, 37.14477539062501);
@@ -44,7 +47,7 @@ public partial class MapMatcher : UserControl
private async Task OpenGpsLocation(int gpsFilesIndex)
{
var media = GpsFiles.Items[gpsFilesIndex] as MediaFileInfo;
var ann = _annotations.GetValueOrDefault(Path.GetFileNameWithoutExtension(media.Name));
var ann = _annotations.GetValueOrDefault(gpsFilesIndex);
GpsImageEditor.Background = new ImageBrush
{
ImageSource = await Path.Combine(_currentDir, ann.Name).OpenImage()
@@ -91,70 +94,63 @@ public partial class MapMatcher : UserControl
Path = x.FullName,
MediaType = MediaTypes.Image
}).ToList();
// var allFiles = videoFiles.Concat(imageFiles).ToList();
//
// var labelsDict = await _dbFactory.Run(async db => await db.Annotations
// .GroupBy(x => x.Name.Substring(0, x.Name.Length - 7))
// .Where(x => allFileNames.Contains(x.Key))
// .ToDictionaryAsync(x => x.Key, x => x.Key));
//
// foreach (var mediaFile in allFiles)
// mediaFile.HasAnnotations = labelsDict.ContainsKey(mediaFile.FName);
//
// AllMediaFiles = new ObservableCollection<MediaFileInfo>(allFiles);
_allMediaFiles = mediaFiles;
GpsFiles.ItemsSource = new ObservableCollection<MediaFileInfo>(_allMediaFiles);
var annotations = SetFromCsv(mediaFiles);
Cursor = Cursors.Wait;
await Task.Delay(TimeSpan.FromSeconds(10));
SetMarkers(annotations);
Cursor = Cursors.Arrow;
await OpenGpsLocation(0);
}
private Dictionary<string, Annotation> SetFromCsv(List<MediaFileInfo> mediaFiles)
{
_annotations = mediaFiles.Select(x => new Annotation
_annotations = mediaFiles.Select((x, i) => (i, new Annotation
{
Name = x.Name,
OriginalMediaName = x.Name
}).ToDictionary(x => Path.GetFileNameWithoutExtension(x.OriginalMediaName));
})).ToDictionary(x => x.i, x => x.Item2);
var csvResults = GpsCsvResult.ReadFromCsv(Constants.CSV_PATH);
var initialLat = double.Parse(TbLat.Text);
var initialLon = double.Parse(TbLon.Text);
await _gpsMatcherService.RunGpsMatching(dir.FullName, initialLat, initialLon, async res => await SetMarker(res));
}
private async Task SetMarker(GpsMatchResult result)
{
await Dispatcher.Invoke(async () =>
{
var marker = new GMapMarker(new PointLatLng(result.Latitude, result.Longitude));
var ann = _annotations[result.Index];
marker.Shape = new CircleVisual(marker, System.Windows.Media.Brushes.Blue)
{
Text = ann.Name
};
SatelliteMap.Markers.Add(marker);
ann.Lat = result.Latitude;
ann.Lon = result.Longitude;
SatelliteMap.Position = new PointLatLng(result.Latitude, result.Longitude);
SatelliteMap.ZoomAndCenterMarkers(null);
});
}
private async Task SetFromCsv(List<MediaFileInfo> mediaFiles)
{
var csvResults = GpsMatchResult.ReadFromCsv(Constants.CSV_PATH);
var csvDict = csvResults
.Where(x => x.MatchType == "stitched")
.ToDictionary(x => x.Image);
.ToDictionary(x => x.Index);
foreach (var ann in _annotations)
{
var csvRes = csvDict.GetValueOrDefault(ann.Key);
if (csvRes == null)
continue;
ann.Value.Lat = csvRes.Latitude;
ann.Value.Lon = csvRes.Longitude;
await SetMarker(csvRes);
}
return _annotations;
}
private void SetMarkers(Dictionary<string, Annotation> annotations)
private async void TestGps(object sender, RoutedEventArgs e)
{
if (!annotations.Any())
if (string.IsNullOrEmpty(TbGpsMapFolder.Text))
return;
var firstAnnotation = annotations.FirstOrDefault();
SatelliteMap.Position = new PointLatLng(firstAnnotation.Value.Lat, firstAnnotation.Value.Lon);
foreach (var ann in annotations.Where(x => x.Value.Lat != 0 && x.Value.Lon != 0))
{
var marker = new GMapMarker(new PointLatLng(ann.Value.Lat, ann.Value.Lon));
var circle = new CircleVisual(marker, System.Windows.Media.Brushes.Blue)
{
Text = " "
};
marker.Shape = circle;
SatelliteMap.Markers.Add(marker);
}
SatelliteMap.ZoomAndCenterMarkers(null);
var initialLat = double.Parse(TbLat.Text);
var initialLon = double.Parse(TbLon.Text);
await _gpsMatcherService.RunGpsMatching(TbGpsMapFolder.Text, initialLat, initialLon, async res => await SetMarker(res));
}
}
}