mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-02-06 07:44:13 +01:00
early gnss lib work
This commit is contained in:
parent
b52d2d2d2b
commit
36a5235982
120
src/NmeaParser.Gnss/GnssMessageAggregator.cs
Normal file
120
src/NmeaParser.Gnss/GnssMessageAggregator.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
using NmeaParser.Messages;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace NmeaParser.Gnss
|
||||
{
|
||||
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; }
|
||||
}
|
||||
}
|
||||
52
src/NmeaParser.Gnss/NmeaParser.Gnss.csproj
Normal file
52
src/NmeaParser.Gnss/NmeaParser.Gnss.csproj
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
<Project Sdk="MSBuild.Sdk.Extras/2.0.54">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>netstandard1.4</TargetFrameworks>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<!--<GenerateDocumentationFile>true</GenerateDocumentationFile>-->
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
<Platforms>AnyCPU</Platforms>
|
||||
<Authors>Morten Nielsen</Authors>
|
||||
<Company>Morten Nielsen</Company>
|
||||
<Description>Global Navigation System library based on a NMEA input stream.</Description>
|
||||
<PackageTags>nmea winrt wpf uwp xamarin gps serialport bluetooth gnss galileo GLONASS</PackageTags>
|
||||
<PackageId>SharpGIS.NmeaParser.Gnss</PackageId>
|
||||
<Version>2.1</Version>
|
||||
<Product>NMEA Parser - GNSS</Product>
|
||||
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
|
||||
<PackageProjectUrl>https://dotmorten.github.io/NmeaParser/</PackageProjectUrl>
|
||||
<RepositoryUrl>https://github.com/dotMorten/NmeaParser</RepositoryUrl>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Copyright>Copyright © Morten Nielsen 2015-2020</Copyright>
|
||||
<OutputPath>$(MSBuildThisFileDirectory)..\..\artifacts\NmeaParser\$(Configuration)</OutputPath>
|
||||
<PackageOutputPath>..\..\artifacts\NuGet\$(Configuration)\</PackageOutputPath>
|
||||
<PackageReleaseNotes></PackageReleaseNotes>
|
||||
<PublishRepositoryUrl>true</PublishRepositoryUrl>
|
||||
<EmbedUntrackedSources>true</EmbedUntrackedSources>
|
||||
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<TreatWarningsAsErrors Condition="'$(Configuration)'=='Release'">true</TreatWarningsAsErrors>
|
||||
<CodeAnalysisTreatWarningsAsErrors Condition="'$(Configuration)'=='Release'">true</CodeAnalysisTreatWarningsAsErrors>
|
||||
<Nullable>enable</Nullable>
|
||||
<PackageIcon>logo.png</PackageIcon>
|
||||
<PackageIconUrl />
|
||||
<AssemblyVersion>2.1.0.0</AssemblyVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(TargetFramework)' == 'netstandard1.4'">
|
||||
<DefineConstants>$(DefineConstants);NETSTANDARD</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0" PrivateAssets="All" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="../NmeaParser/logo.png" Link="logo.png" Pack="true" PackagePath="" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\NmeaParser\NmeaParser.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
23
src/NmeaParser.Gnss/Ntrip/Carrier.cs
Normal file
23
src/NmeaParser.Gnss/Ntrip/Carrier.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
namespace NmeaParser.Gnss.Ntrip
|
||||
{
|
||||
public enum Carrier : int
|
||||
{
|
||||
No = 0,
|
||||
L1 = 1,
|
||||
L1L2 = 2
|
||||
}
|
||||
}
|
||||
59
src/NmeaParser.Gnss/Ntrip/Caster.cs
Normal file
59
src/NmeaParser.Gnss/Ntrip/Caster.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
using System.Globalization;
|
||||
using System.Net;
|
||||
|
||||
namespace NmeaParser.Gnss.Ntrip
|
||||
{
|
||||
public class Caster : NtripSource
|
||||
{
|
||||
internal Caster (string[] d)
|
||||
{
|
||||
var a = d[1].Split(':');
|
||||
Address = IPAddress.Parse(a[0]);
|
||||
Port = int.Parse(a[1]);
|
||||
Identifier = d[3];
|
||||
Operator = d[4];
|
||||
SupportsNmea = d[5] == "1";
|
||||
CountryCode = d[6];
|
||||
Latitude = double.Parse(d[7], CultureInfo.InvariantCulture);
|
||||
Longitude = double.Parse(d[8], CultureInfo.InvariantCulture);
|
||||
FallbackAddress = IPAddress.Parse(d[9]);
|
||||
}
|
||||
|
||||
public Caster(IPAddress address, int port, string identifier, string _operator, bool supportsNmea, string countryCode, double latitude, double longitude, IPAddress fallbackkAddress)
|
||||
{
|
||||
Address = address;
|
||||
Port = port;
|
||||
Identifier = identifier;
|
||||
Operator = _operator;
|
||||
SupportsNmea = supportsNmea;
|
||||
CountryCode = countryCode;
|
||||
Latitude = latitude;
|
||||
Longitude = longitude;
|
||||
FallbackAddress = fallbackkAddress;
|
||||
}
|
||||
|
||||
public IPAddress Address { get; }
|
||||
public int Port { get; }
|
||||
public string Identifier { get; }
|
||||
public string Operator { get; }
|
||||
public bool SupportsNmea { get; }
|
||||
public string CountryCode { get; }
|
||||
public double Latitude { get; }
|
||||
public double Longitude { get; }
|
||||
public IPAddress FallbackAddress { get; }
|
||||
}
|
||||
}
|
||||
140
src/NmeaParser.Gnss/Ntrip/Client.cs
Normal file
140
src/NmeaParser.Gnss/Ntrip/Client.cs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace NmeaParser.Gnss.Ntrip
|
||||
{
|
||||
public class Client : IDisposable
|
||||
{
|
||||
private readonly string _host;
|
||||
private readonly int _port;
|
||||
private string? _auth;
|
||||
private Socket? sckt;
|
||||
private bool connected;
|
||||
private Task? runningTask;
|
||||
|
||||
public Client(string host, int port)
|
||||
{
|
||||
_host = host;
|
||||
_port = port;
|
||||
}
|
||||
|
||||
public Client(string host, int port, string username, string password) : this(host, port)
|
||||
{
|
||||
_auth = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(username + ":" + password));
|
||||
}
|
||||
|
||||
public IEnumerable<NtripSource> GetSourceTable()
|
||||
{
|
||||
string data = "";
|
||||
byte[] buffer = new byte[1024];
|
||||
using (var sck = Request(""))
|
||||
{
|
||||
int count;
|
||||
while ((count = sck.Receive(buffer)) > 0)
|
||||
{
|
||||
data += System.Text.Encoding.UTF8.GetString(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
var lines = data.Split('\n');
|
||||
List<NtripSource> sources = new List<NtripSource>();
|
||||
foreach (var item in lines)
|
||||
{
|
||||
var d = item.Split(';');
|
||||
if (d.Length == 0) continue;
|
||||
if (d[0] == "ENDSOURCETABLE")
|
||||
break;
|
||||
if (d[0] == "CAS")
|
||||
{
|
||||
sources.Add(new Caster(d));
|
||||
}
|
||||
else if (d[0] == "STR")
|
||||
{
|
||||
sources.Add(new NtripStream(d));
|
||||
}
|
||||
}
|
||||
return sources;
|
||||
}
|
||||
|
||||
private Socket Request(string path)
|
||||
{
|
||||
var sckt = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||
sckt.Blocking = true;
|
||||
sckt.Connect(_host, _port);
|
||||
|
||||
string msg = $"GET /{path} HTTP/1.1\r\n";
|
||||
msg += "User-Agent: NTRIP ntripclient\r\n";
|
||||
if (_auth != null)
|
||||
{
|
||||
msg += "Authorization: Basic " + _auth + "\r\n";
|
||||
}
|
||||
msg += "Accept: */*\r\nConnection: close\r\n";
|
||||
msg += "\r\n";
|
||||
|
||||
byte[] data = System.Text.Encoding.ASCII.GetBytes(msg);
|
||||
sckt.Send(data);
|
||||
return sckt;
|
||||
}
|
||||
|
||||
public void Connect(string strName)
|
||||
{
|
||||
if (sckt != null) throw new Exception("Connection already open");
|
||||
sckt = Request(strName);
|
||||
connected = true;
|
||||
runningTask = Task.Run(ReceiveThread);
|
||||
}
|
||||
|
||||
private async Task ReceiveThread()
|
||||
{
|
||||
byte[] buffer = new byte[65536];
|
||||
|
||||
while (connected && sckt != null)
|
||||
{
|
||||
int count = sckt.Receive(buffer);
|
||||
if (count > 0)
|
||||
{
|
||||
DataReceived?.Invoke(this, buffer.Take(count).ToArray());
|
||||
}
|
||||
await Task.Delay(10);
|
||||
}
|
||||
sckt.Shutdown(SocketShutdown.Both);
|
||||
sckt.Dispose();
|
||||
sckt = null;
|
||||
}
|
||||
|
||||
public Task CloseAsync()
|
||||
{
|
||||
if (runningTask != null)
|
||||
{
|
||||
connected = false;
|
||||
var t = runningTask;
|
||||
runningTask = null;
|
||||
return t;
|
||||
}
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_ = CloseAsync();
|
||||
}
|
||||
|
||||
public event EventHandler<byte[]>? DataReceived;
|
||||
}
|
||||
}
|
||||
23
src/NmeaParser.Gnss/Ntrip/NtripSource.cs
Normal file
23
src/NmeaParser.Gnss/Ntrip/NtripSource.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
namespace NmeaParser.Gnss.Ntrip
|
||||
{
|
||||
public class NtripSource
|
||||
{
|
||||
protected NtripSource()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
46
src/NmeaParser.Gnss/Ntrip/NtripStream.cs
Normal file
46
src/NmeaParser.Gnss/Ntrip/NtripStream.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
using System.Globalization;
|
||||
|
||||
namespace NmeaParser.Gnss.Ntrip
|
||||
{
|
||||
public class NtripStream : NtripSource
|
||||
{
|
||||
internal NtripStream(string[] d)
|
||||
{
|
||||
Mountpoint = d[1];
|
||||
Identifier = d[2];
|
||||
Format = d[3];
|
||||
FormatDetails = d[4];
|
||||
Carrier = (Carrier)int.Parse(d[5]);
|
||||
Network = d[7];
|
||||
CountryCode = d[8];
|
||||
Latitude = double.Parse(d[9], CultureInfo.InvariantCulture);
|
||||
Longitude = double.Parse(d[10], CultureInfo.InvariantCulture);
|
||||
SupportsNmea = d[11] == "1";
|
||||
}
|
||||
|
||||
public string Mountpoint { get; }
|
||||
public string Identifier { get; }
|
||||
public string Format { get; }
|
||||
public string FormatDetails { get; }
|
||||
public Carrier Carrier { get; }
|
||||
public string Network { get; }
|
||||
public string CountryCode { get; }
|
||||
public double Latitude { get; }
|
||||
public double Longitude { get; }
|
||||
public bool SupportsNmea { get; }
|
||||
}
|
||||
}
|
||||
|
|
@ -37,8 +37,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NmeaParser.Tests.Net", "Uni
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.NetCore", "SampleApp.WinDesktop\SampleApp.NetCore.csproj", "{6F97C607-42A0-458B-B9E9-CF5AF53CBB1E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NmeaParser.Gnss", "NmeaParser.Gnss\NmeaParser.Gnss.csproj", "{3ABEC519-B792-41D0-8462-1512B05276D6}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SharedMSBuildProjectFiles) = preSolution
|
||||
UnitTests\NmeaParser.Tests\NmeaParser.Tests.projitems*{73efb2ef-de40-46c4-9685-745a9815c0d2}*SharedItemsImports = 5
|
||||
UnitTests\NmeaParser.Tests\NmeaParser.Tests.projitems*{92cad93b-6c3b-45a0-a723-be046de50fec}*SharedItemsImports = 4
|
||||
UnitTests\NmeaParser.Tests\NmeaParser.Tests.projitems*{979ae182-eb59-4181-9d45-3fd6e4817f11}*SharedItemsImports = 13
|
||||
EndGlobalSection
|
||||
|
|
@ -171,6 +174,22 @@ Global
|
|||
{6F97C607-42A0-458B-B9E9-CF5AF53CBB1E}.Release|x64.Build.0 = Release|Any CPU
|
||||
{6F97C607-42A0-458B-B9E9-CF5AF53CBB1E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{6F97C607-42A0-458B-B9E9-CF5AF53CBB1E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|ARM.ActiveCfg = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|ARM.Build.0 = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|ARM.ActiveCfg = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|ARM.Build.0 = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|x64.Build.0 = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -187,6 +206,7 @@ Global
|
|||
{48540D33-4349-42D2-9D49-144A7049565A} = {456E7573-3324-43CB-8BA0-8D9C300EEB50}
|
||||
{73EFB2EF-DE40-46C4-9685-745A9815C0D2} = {28B8E327-C504-4E08-B2CE-09D1CBB8B904}
|
||||
{6F97C607-42A0-458B-B9E9-CF5AF53CBB1E} = {7ABA337E-6748-484E-A0F4-E1715E1C95F1}
|
||||
{3ABEC519-B792-41D0-8462-1512B05276D6} = {1701F3BA-A09C-4706-A612-24FD9340FC18}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {03788B53-C0BF-485B-AA19-A9EAB0E9AF7B}
|
||||
|
|
|
|||
57
src/NmeaParser/MessageAggregator.cs
Normal file
57
src/NmeaParser/MessageAggregator.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using NmeaParser.Messages;
|
||||
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, NmeaMessage> _messages = new Dictionary<string, 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<NmeaMessage[]> MessagesReceived;
|
||||
|
||||
/// <summary>
|
||||
/// The device that's being listened to.
|
||||
/// </summary>
|
||||
public NmeaDevice Device { get; }
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue