mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-01-01 14:20:33 +01:00
Improved location datasource to better handle multiple gps systems
This commit is contained in:
parent
3c2b9f2851
commit
9a71ca4db6
|
|
@ -39,6 +39,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleApp.NetCore", "Sample
|
|||
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
|
||||
|
|
|
|||
114
src/SampleApp.WinDesktop/NmeaLocationDataSourcer.cs
Normal file
114
src/SampleApp.WinDesktop/NmeaLocationDataSourcer.cs
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
using Esri.ArcGISRuntime.Geometry;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SampleApp.WinDesktop
|
||||
{
|
||||
public class NmeaLocationDataSource : Esri.ArcGISRuntime.Location.LocationDataSource
|
||||
{
|
||||
private NmeaParser.NmeaDevice device;
|
||||
private double m_Accuracy = 0;
|
||||
private double m_altitude = double.NaN;
|
||||
private double m_speed = 0;
|
||||
private double m_course = 0;
|
||||
private bool supportGNMessages; // If device detect GN* messages, ignore all other Talker ID
|
||||
private bool supportGGaMessages; //If device support GGA, ignore RMC for location
|
||||
|
||||
public NmeaLocationDataSource(NmeaParser.NmeaDevice device)
|
||||
{
|
||||
this.device = device;
|
||||
if(device != null)
|
||||
device.MessageReceived += device_MessageReceived;
|
||||
}
|
||||
void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs e)
|
||||
{
|
||||
var message = e.Message;
|
||||
ParseMessage(message);
|
||||
}
|
||||
public void ParseMessage(NmeaParser.Messages.NmeaMessage message)
|
||||
{
|
||||
bool isNewFix = false;
|
||||
bool lostFix = false;
|
||||
double lat = 0;
|
||||
double lon = 0;
|
||||
if (message.TalkerId == NmeaParser.Talker.GlobalNavigationSatelliteSystem)
|
||||
supportGNMessages = true;
|
||||
else if(supportGNMessages && message.TalkerId != NmeaParser.Talker.GlobalNavigationSatelliteSystem)
|
||||
return; // If device supports combined GN* messages, ignore non-GN messages
|
||||
|
||||
if (message is NmeaParser.Messages.Garmin.Pgrme rme)
|
||||
{
|
||||
m_Accuracy = rme.HorizontalError;
|
||||
}
|
||||
else if(message is NmeaParser.Messages.Gst gst)
|
||||
{
|
||||
Gst = gst;
|
||||
m_Accuracy = Math.Sqrt(Gst.SigmaLatitudeError * Gst.SigmaLatitudeError + Gst.SigmaLongitudeError * Gst.SigmaLongitudeError);
|
||||
}
|
||||
else if (message is NmeaParser.Messages.Rmc rmc)
|
||||
{
|
||||
Rmc = rmc;
|
||||
if (Rmc.Active)
|
||||
{
|
||||
m_speed = double.IsNaN(Rmc.Speed) ? Rmc.Speed : 0;
|
||||
if (!double.IsNaN(Rmc.Course))
|
||||
m_course = Rmc.Course;
|
||||
lat = Rmc.Latitude;
|
||||
lon = Rmc.Longitude;
|
||||
}
|
||||
else
|
||||
{
|
||||
lostFix = true;
|
||||
}
|
||||
isNewFix = !supportGGaMessages;
|
||||
}
|
||||
else if (message is NmeaParser.Messages.Gga gga)
|
||||
{
|
||||
supportGGaMessages = true;
|
||||
if (gga.Quality != NmeaParser.Messages.Gga.FixQuality.Invalid)
|
||||
{
|
||||
lat = Rmc.Latitude;
|
||||
lon = Rmc.Longitude;
|
||||
m_altitude = gga.Altitude + gga.GeoidalSeparation; //Convert to ellipsoidal height
|
||||
}
|
||||
if (gga.Quality != NmeaParser.Messages.Gga.FixQuality.Invalid || gga.Quality == NmeaParser.Messages.Gga.FixQuality.Estimated)
|
||||
{
|
||||
lostFix = true;
|
||||
}
|
||||
isNewFix = true;
|
||||
}
|
||||
else if (message is NmeaParser.Messages.Gsa gsa)
|
||||
{
|
||||
Gsa = gsa;
|
||||
}
|
||||
if (isNewFix)
|
||||
{
|
||||
base.UpdateLocation(new Esri.ArcGISRuntime.Location.Location(
|
||||
!double.IsNaN(m_altitude) ? new MapPoint(lon, lat, m_altitude, wgs84_ellipsoidHeight) : new MapPoint(lon, lat, SpatialReferences.Wgs84),
|
||||
m_Accuracy, m_speed, m_course, lostFix));
|
||||
}
|
||||
}
|
||||
private static SpatialReference wgs84_ellipsoidHeight = SpatialReference.Create(4326, 115700);
|
||||
protected override Task OnStartAsync()
|
||||
{
|
||||
if (device != null)
|
||||
return this.device.OpenAsync();
|
||||
else
|
||||
return System.Threading.Tasks.Task<bool>.FromResult(true);
|
||||
}
|
||||
|
||||
protected override Task OnStopAsync()
|
||||
{
|
||||
m_Accuracy = double.NaN;
|
||||
if(this.device != null)
|
||||
return this.device.CloseAsync();
|
||||
else
|
||||
return System.Threading.Tasks.Task<bool>.FromResult(true);
|
||||
}
|
||||
|
||||
public NmeaParser.Messages.Gsa Gsa { get; private set; }
|
||||
public NmeaParser.Messages.Gga Gga { get; private set; }
|
||||
public NmeaParser.Messages.Rmc Rmc { get; private set; }
|
||||
public NmeaParser.Messages.Gst Gst { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
using Esri.ArcGISRuntime.Geometry;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SampleApp.WinDesktop
|
||||
{
|
||||
public class NmeaLocationProvider : Esri.ArcGISRuntime.Location.LocationDataSource
|
||||
{
|
||||
private NmeaParser.NmeaDevice device;
|
||||
double m_Accuracy = 0;
|
||||
double m_altitude = double.NaN;
|
||||
double m_speed = 0;
|
||||
double m_course = 0;
|
||||
|
||||
public NmeaLocationProvider(NmeaParser.NmeaDevice device)
|
||||
{
|
||||
this.device = device;
|
||||
if(device != null)
|
||||
device.MessageReceived += device_MessageReceived;
|
||||
}
|
||||
void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs e)
|
||||
{
|
||||
var message = e.Message;
|
||||
ParseMessage(message);
|
||||
}
|
||||
|
||||
public void ParseMessage(NmeaParser.Messages.NmeaMessage message)
|
||||
{
|
||||
bool isNewFix = false;
|
||||
bool lostFix = false;
|
||||
double lat = 0;
|
||||
double lon = 0;
|
||||
if (message is NmeaParser.Messages.Garmin.Pgrme)
|
||||
{
|
||||
m_Accuracy = ((NmeaParser.Messages.Garmin.Pgrme)message).HorizontalError;
|
||||
}
|
||||
else if(message is NmeaParser.Messages.Gst)
|
||||
{
|
||||
Gst = ((NmeaParser.Messages.Gst)message);
|
||||
m_Accuracy = Math.Sqrt(Gst.SigmaLatitudeError * Gst.SigmaLatitudeError + Gst.SigmaLongitudeError * Gst.SigmaLongitudeError);
|
||||
}
|
||||
else if(message is NmeaParser.Messages.Gga)
|
||||
{
|
||||
Gga = ((NmeaParser.Messages.Gga)message);
|
||||
isNewFix = Gga.Quality != NmeaParser.Messages.Gga.FixQuality.Invalid;
|
||||
lostFix = !isNewFix;
|
||||
m_altitude = Gga.Altitude;
|
||||
lat = Gga.Latitude;
|
||||
lon = Gga.Longitude;
|
||||
}
|
||||
else if (message is NmeaParser.Messages.Rmc)
|
||||
{
|
||||
Rmc = (NmeaParser.Messages.Rmc)message;
|
||||
if (Rmc.Active)
|
||||
{
|
||||
isNewFix = true;
|
||||
m_speed = Rmc.Speed;
|
||||
m_course = Rmc.Course;
|
||||
lat = Rmc.Latitude;
|
||||
lon = Rmc.Longitude;
|
||||
}
|
||||
else lostFix = true;
|
||||
}
|
||||
else if (message is NmeaParser.Messages.Gsa)
|
||||
{
|
||||
Gsa = (NmeaParser.Messages.Gsa)message;
|
||||
}
|
||||
if (isNewFix)
|
||||
{
|
||||
base.UpdateLocation(new Esri.ArcGISRuntime.Location.Location(new MapPoint(lon, lat, m_altitude, SpatialReferences.Wgs84), m_Accuracy, m_speed, m_course, false));
|
||||
}
|
||||
else if (lostFix)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
protected override Task OnStartAsync()
|
||||
{
|
||||
if (device != null)
|
||||
return this.device.OpenAsync();
|
||||
else
|
||||
return System.Threading.Tasks.Task<bool>.FromResult(true);
|
||||
}
|
||||
|
||||
protected override Task OnStopAsync()
|
||||
{
|
||||
m_Accuracy = double.NaN;
|
||||
if(this.device != null)
|
||||
return this.device.CloseAsync();
|
||||
else
|
||||
return System.Threading.Tasks.Task<bool>.FromResult(true);
|
||||
}
|
||||
|
||||
public NmeaParser.Messages.Gsa Gsa { get; private set; }
|
||||
public NmeaParser.Messages.Gga Gga { get; private set; }
|
||||
public NmeaParser.Messages.Rmc Rmc { get; private set; }
|
||||
public NmeaParser.Messages.Gst Gst { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ namespace SampleApp.WinDesktop
|
|||
}
|
||||
|
||||
mapView.LocationDisplay.InitialZoomScale = 5000;
|
||||
mapView.LocationDisplay.AutoPanMode = Esri.ArcGISRuntime.UI.LocationDisplayAutoPanMode.Navigation;
|
||||
mapView.LocationDisplay.AutoPanMode = Esri.ArcGISRuntime.UI.LocationDisplayAutoPanMode.Recenter;
|
||||
}
|
||||
|
||||
public NmeaDevice NmeaDevice
|
||||
|
|
@ -51,7 +51,7 @@ namespace SampleApp.WinDesktop
|
|||
mapView.LocationDisplay.IsEnabled = false;
|
||||
if (newDevice != null)
|
||||
{
|
||||
mapView.LocationDisplay.DataSource = new NmeaLocationProvider(newDevice);
|
||||
mapView.LocationDisplay.DataSource = new NmeaLocationDataSource(newDevice);
|
||||
mapView.LocationDisplay.IsEnabled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue