Files
annotations/Azaion.Common/Services/GpsMatcherClient.cs
T
2025-05-27 13:26:37 +03:00

132 lines
4.5 KiB
C#

using System.Diagnostics;
using Azaion.CommonSecurity;
using Azaion.CommonSecurity.DTO;
using MediatR;
using Microsoft.Extensions.Options;
using NetMQ;
using NetMQ.Sockets;
namespace Azaion.Common.Services;
public interface IGpsMatcherClient : IDisposable
{
void StartMatching(StartMatchingEvent startEvent);
void Stop();
}
public class StartMatchingEvent
{
public string RouteDir { get; set; } = null!;
public string SatelliteImagesDir { get; set; } = null!;
public int ImagesCount { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public int Altitude { get; set; } = 400;
public double CameraSensorWidth { get; set; } = 23.5;
public double CameraFocalLength { get; set; } = 24;
public override string ToString() =>
$"{RouteDir},{SatelliteImagesDir},{ImagesCount},{Latitude},{Longitude},{Altitude},{CameraSensorWidth},{CameraFocalLength}";
}
public class GpsMatcherClient : IGpsMatcherClient
{
private readonly IMediator _mediator;
private readonly GpsDeniedClientConfig _gpsDeniedClientConfig;
private string _requestAddress;
private readonly RequestSocket _requestSocket = new();
private string _subscriberAddress;
private readonly SubscriberSocket _subscriberSocket = new();
public GpsMatcherClient(IMediator mediator, IOptions<GpsDeniedClientConfig> gpsDeniedClientConfig)
{
_mediator = mediator;
_gpsDeniedClientConfig = gpsDeniedClientConfig.Value;
Start();
}
private void Start(CancellationToken ct = default)
{
try
{
using var process = new Process();
process.StartInfo = new ProcessStartInfo
{
FileName = SecurityConstants.ExternalGpsDeniedPath,
WorkingDirectory = SecurityConstants.EXTERNAL_GPS_DENIED_FOLDER
//Arguments = $"-e {credentials.Email} -p {credentials.Password} -f {apiConfig.ResourcesFolder}",
//RedirectStandardOutput = true,
//RedirectStandardError = true,
//CreateNoWindow = true
};
process.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
process.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
process.Start();
}
catch (Exception e)
{
Console.WriteLine(e);
//throw;
}
_requestAddress = $"tcp://{_gpsDeniedClientConfig.ZeroMqHost}:{_gpsDeniedClientConfig.ZeroMqPort}";
_requestSocket.Connect(_requestAddress);
_subscriberAddress = $"tcp://{_gpsDeniedClientConfig.ZeroMqHost}:{_gpsDeniedClientConfig.ZeroMqSubscriberPort}";
_subscriberSocket.Connect(_subscriberAddress);
_subscriberSocket.Subscribe("");
_subscriberSocket.ReceiveReady += async (_, e) => await ProcessClientCommand(e.Socket, ct);
}
private async Task ProcessClientCommand(NetMQSocket socket, CancellationToken ct)
{
while (socket.TryReceiveFrameString(TimeSpan.Zero, out var str))
{
if (string.IsNullOrEmpty(str))
continue;
switch (str)
{
case "FINISHED":
await _mediator.Publish(new GPSMatcherFinishedEvent(), ct);
break;
case "OK":
await _mediator.Publish(new GPSMatcherJobAcceptedEvent(), ct);
break;
default:
var parts = str.Split(',');
if (parts.Length != 5)
throw new Exception("Matching Result Failed");
await _mediator.Publish(new GPSMatcherResultEvent
{
Index = int.Parse(parts[0]),
Image = parts[1],
Latitude = double.Parse(parts[2]),
Longitude = double.Parse(parts[3]),
MatchType = parts[4]
}, ct);
break;
}
}
}
public void StartMatching(StartMatchingEvent e)
{
_requestSocket.SendFrame(e.ToString());
}
public void Stop() => _requestSocket.SendFrame("STOP");
public void Dispose()
{
_requestSocket.SendFrame("EXIT");
_requestSocket.Disconnect(_requestAddress);
_requestSocket.Dispose();
_subscriberSocket.Disconnect(_subscriberAddress);
_subscriberSocket.Dispose();
}
}