using System.Diagnostics; using Azaion.Common.DTO; using Azaion.CommonSecurity; using Azaion.CommonSecurity.DTO; using Microsoft.Extensions.Options; using NetMQ; using NetMQ.Sockets; namespace Azaion.Common.Services; public interface IGpsMatcherClient { void StartMatching(StartMatchingEvent startEvent); GpsMatchResult? GetResult(int retries = 2, int tryTimeoutSeconds = 5, CancellationToken ct = default); 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 string ProcessingType { get; set; } = "cuda"; 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},{ProcessingType},{Altitude},{CameraSensorWidth},{CameraFocalLength}"; } public class GpsMatcherClient : IGpsMatcherClient { private readonly GpsDeniedClientConfig _gpsDeniedClientConfig; private readonly RequestSocket _requestSocket = new(); private readonly SubscriberSocket _subscriberSocket = new(); public GpsMatcherClient(IOptions gpsDeniedClientConfig) { _gpsDeniedClientConfig = gpsDeniedClientConfig.Value; Start(); } private void Start() { 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; } _requestSocket.Connect($"tcp://{_gpsDeniedClientConfig.ZeroMqHost}:{_gpsDeniedClientConfig.ZeroMqPort}"); _subscriberSocket.Connect($"tcp://{_gpsDeniedClientConfig.ZeroMqHost}:{_gpsDeniedClientConfig.ZeroMqSubscriberPort}"); _subscriberSocket.Subscribe(""); } public void StartMatching(StartMatchingEvent e) { _requestSocket.SendFrame(e.ToString()); var response = _requestSocket.ReceiveFrameString(); if (response != "OK") throw new Exception("Start Matching Failed"); } public GpsMatchResult? GetResult(int retries = 15, int tryTimeoutSeconds = 5, CancellationToken ct = default) { var tryNum = 0; while (!ct.IsCancellationRequested && tryNum++ < retries) { if (!_subscriberSocket.TryReceiveFrameString(TimeSpan.FromSeconds(tryTimeoutSeconds), out var update)) continue; if (update == "FINISHED") return null; var parts = update.Split(','); if (parts.Length != 5) throw new Exception("Matching Result Failed"); return new GpsMatchResult { Index = int.Parse(parts[0]), Image = parts[1], Latitude = double.Parse(parts[2]), Longitude = double.Parse(parts[3]), MatchType = parts[4] }; } if (!ct.IsCancellationRequested) throw new Exception($"Unable to get bytes after {tryNum} retries, {tryTimeoutSeconds} seconds each"); return null; } public void Stop() { _requestSocket.SendFrame("STOP"); } }