mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2025-12-06 07:12:04 +01:00
Initial stab at an aggregator
This commit is contained in:
parent
252193dd86
commit
bde9a0aee2
108
src/NmeaParser/GnssMessageProcessor.cs
Normal file
108
src/NmeaParser/GnssMessageProcessor.cs
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
using NmeaParser.Nmea;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NmeaParser
|
||||
{
|
||||
public class GnssMessageProcessor : MessageAggregator
|
||||
{
|
||||
|
||||
public GnssMessageProcessor(NmeaDevice device) : base(device)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnMessagesReceived(NmeaMessage[] messages)
|
||||
{
|
||||
base.OnMessagesReceived(messages);
|
||||
// We prefer GNSS messages, so put thos first
|
||||
var info = new PositionInformation();
|
||||
messages = messages.OrderBy(rmc => rmc.TalkerId == Talker.GlobalNavigationSatelliteSystem ? -100 : (int)rmc.TalkerId).ToArray();
|
||||
info.Longitude = double.NaN;
|
||||
info.Latitude = double.NaN;
|
||||
var RmcMessages = messages.OfType<Rmc>().Where(rmc => rmc.Active);
|
||||
if (RmcMessages.Any())
|
||||
{
|
||||
var rmc = RmcMessages.First();
|
||||
info.Latitude = rmc.Latitude;
|
||||
info.Longitude = rmc.Longitude;
|
||||
info.Speed = rmc.Speed;
|
||||
info.TimeOfFix = rmc.FixTime;
|
||||
}
|
||||
var GsaMessages = messages.OfType<Gsa>().Where(gsa => gsa.Fix == Gsa.FixType.Fix3D);
|
||||
if (!GsaMessages.Any())
|
||||
GsaMessages = messages.OfType<Gsa>().Where(gsa => gsa.Fix == Gsa.FixType.Fix2D);
|
||||
if (GsaMessages.Any())
|
||||
{
|
||||
var gsa = GsaMessages.First();
|
||||
info.Hdop = gsa.Hdop;
|
||||
info.Pdop = gsa.Pdop;
|
||||
info.Vdop = gsa.Vdop;
|
||||
info.SatelliteIds = gsa.SatelliteIDs;
|
||||
}
|
||||
var GsvMessages = messages.OfType<Gsv>();
|
||||
if (GsvMessages.Any())
|
||||
{
|
||||
Gsv gsv = GsvMessages.First();
|
||||
info.Satellites = gsv.SVs.ToArray();
|
||||
}
|
||||
var GstMessages = messages.OfType<Gst>();
|
||||
if (GstMessages.Any())
|
||||
{
|
||||
Gst gst = GstMessages.First();
|
||||
info.HorizontalAccuracy = (gst.SemiMajorError + gst.SemiMinorError) / 2;
|
||||
info.VerticalAccuracy = gst.SigmaHeightError;
|
||||
if (!info.TimeOfFix.HasValue)
|
||||
{
|
||||
info.TimeOfFix = DateTime.UtcNow.Date.Add(gst.FixTime);
|
||||
}
|
||||
}
|
||||
var GgaMessages = messages.OfType<Gga>().Where(g=>g.Quality != Gga.FixQuality.Invalid);
|
||||
if (GgaMessages.Any())
|
||||
{
|
||||
Gga gga = GgaMessages.First();
|
||||
info.Latitude = gga.Latitude;
|
||||
info.Longitude = gga.Longitude;
|
||||
info.Altitude = gga.Altitude;
|
||||
info.GeoidalSeparation = gga.GeoidalSeparation;
|
||||
if (!info.TimeOfFix.HasValue)
|
||||
{
|
||||
info.TimeOfFix = DateTime.UtcNow.Date.Add(gga.FixTime);
|
||||
}
|
||||
}
|
||||
var GnsMessages = messages.OfType<Gns>();
|
||||
if (GnsMessages.Any())
|
||||
{
|
||||
Gns gns = GnsMessages.First();
|
||||
if (!info.TimeOfFix.HasValue)
|
||||
{
|
||||
info.TimeOfFix = DateTime.UtcNow.Date.Add(gns.FixTime);
|
||||
}
|
||||
info.GeoidalSeparation = gns.GeoidalSeparation;
|
||||
info.Latitude = gns.Latitude;
|
||||
info.Longitude = gns.Longitude;
|
||||
}
|
||||
LocationUpdated?.Invoke(this, info);
|
||||
}
|
||||
|
||||
public event EventHandler<PositionInformation> LocationUpdated;
|
||||
}
|
||||
|
||||
public struct PositionInformation
|
||||
{
|
||||
public double? Longitude { get; internal set; }
|
||||
public double? Latitude { get; internal set; }
|
||||
public double? Altitude { get; internal set; }
|
||||
public double? GeoidalSeparation { get; internal set; }
|
||||
public double? Speed { get; internal set; }
|
||||
public double? Pdop { get; internal set; }
|
||||
public double? Hdop { get; internal set; }
|
||||
public double? Vdop { get; internal set; }
|
||||
public double? HorizontalAccuracy { get; internal set; }
|
||||
public double? VerticalAccuracy { get; internal set; }
|
||||
public DateTimeOffset? TimeOfFix { get; internal set; }
|
||||
public int[] SatelliteIds { get; internal set; }
|
||||
public SatelliteVehicle[] Satellites { get; internal set; }
|
||||
}
|
||||
}
|
||||
57
src/NmeaParser/MessageAggregator.cs
Normal file
57
src/NmeaParser/MessageAggregator.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using NmeaParser.Nmea;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NmeaParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Aggregates a group of messages, and raises an event once all messages has completed transmission
|
||||
/// </summary>
|
||||
public class MessageAggregator
|
||||
{
|
||||
private readonly Dictionary<string, Nmea.NmeaMessage> _messages = new Dictionary<string, Nmea.NmeaMessage>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MessageAggregator"/> class.
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
public MessageAggregator(NmeaDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException(nameof(device));
|
||||
Device = device;
|
||||
Device.MessageReceived += Device_MessageReceived;
|
||||
}
|
||||
|
||||
private void Device_MessageReceived(object sender, NmeaMessageReceivedEventArgs e)
|
||||
{
|
||||
if(_messages.ContainsKey(e.Message.MessageType))
|
||||
{
|
||||
var messages = _messages.Values.ToArray();
|
||||
_messages.Clear();
|
||||
OnMessagesReceived(messages);
|
||||
MessagesReceived?.Invoke(this, messages);
|
||||
}
|
||||
_messages.Add(e.Message.MessageType, e.Message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Called when a group of messages have been received.
|
||||
/// </summary>
|
||||
protected virtual void OnMessagesReceived(NmeaMessage[] messages)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raised when a group of messages have been received.
|
||||
/// </summary>
|
||||
public event EventHandler<Nmea.NmeaMessage[]> MessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The device that's being listened to.
|
||||
/// </summary>
|
||||
public NmeaDevice Device { get; }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue