diff --git a/src/NmeaParser.Shared/Nmea/Gps/GPGSV.cs b/src/NmeaParser.Shared/Nmea/Gps/GPGSV.cs new file mode 100644 index 0000000..4ecc046 --- /dev/null +++ b/src/NmeaParser.Shared/Nmea/Gps/GPGSV.cs @@ -0,0 +1,98 @@ +// +// Copyright (c) 2014 Morten Nielsen +// +// Licensed under the Microsoft Public License (Ms-PL) (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://opensource.org/licenses/Ms-PL.html +// +// 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.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace NmeaParser.Nmea.Gps +{ + /// + /// GPS Satellites in view + /// + [NmeaMessageType(Type = "GPGSV")] + public sealed class Gpgsv : NmeaMessage + { + protected override void LoadMessage(string[] message) + { + TotalMessages = int.Parse(message[0]); + MessageNumber = int.Parse(message[1]); + SVsInView = int.Parse(message[2]); + + List svs = new List(); + for (int i = 3; i < 18; i+=4) + { + if (message[i].Length == 0) + continue; + else + svs.Add(new SatelitteVehicle(message, i)); + } + this.SVs = svs.ToArray(); + } + + /// + /// Total number of messages of this type in this cycle + /// + public int TotalMessages { get; private set; } + + /// + /// Message number + /// + public int MessageNumber { get; private set; } + + /// + /// Total number of SVs in view + /// + public int SVsInView { get; private set; } + + /// + /// Dilution of precision + /// + public SatelitteVehicle[] SVs { get; private set; } + } + + public sealed class SatelitteVehicle + { + internal SatelitteVehicle(string[] message, int startIndex) + { + PrnNumber = int.Parse(message[startIndex]); + Elevation = double.Parse(message[startIndex+1], CultureInfo.InvariantCulture); + Azimuth = double.Parse(message[startIndex + 2], CultureInfo.InvariantCulture); + int snr = -1; + if (int.TryParse(message[startIndex + 3], out snr)) + SignalToNoiseRatio = snr; + } + /// + /// SV PRN number + /// + public int PrnNumber { get; set; } + /// + /// Elevation in degrees, 90 maximum + /// + public double Elevation { get; private set; } + /// + /// Azimuth, degrees from true north, 000 to 359 + /// + public double Azimuth { get; private set; } + /// + /// Signal-to-Noise ratio, 0-99 dB (-1 when not tracking) + /// + public int SignalToNoiseRatio { get; private set; } + } +} diff --git a/src/NmeaParser.Shared/NmeaParser.Shared.projitems b/src/NmeaParser.Shared/NmeaParser.Shared.projitems index 6aae2c1..d6ab5da 100644 --- a/src/NmeaParser.Shared/NmeaParser.Shared.projitems +++ b/src/NmeaParser.Shared/NmeaParser.Shared.projitems @@ -12,6 +12,7 @@ + diff --git a/src/NmeaParser.Tests/NmeaMessages.cs b/src/NmeaParser.Tests/NmeaMessages.cs index 2f1e09a..429a69a 100644 --- a/src/NmeaParser.Tests/NmeaMessages.cs +++ b/src/NmeaParser.Tests/NmeaMessages.cs @@ -192,5 +192,50 @@ namespace NmeaParser.Tests Assert.AreEqual(1.0, gsa.HDop); Assert.AreEqual(1.3, gsa.VDop); } + + [TestMethod] + public void TestGpgsv() + { + string input = "$GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gpgsv)); + Gpgsv gsv = (Gpgsv)msg; + Assert.AreEqual(3, gsv.TotalMessages); + Assert.AreEqual(3, gsv.MessageNumber); + Assert.AreEqual(11, gsv.SVsInView); + Assert.IsNotNull(gsv.SVs); + Assert.AreEqual(3, gsv.SVs.Length); + var sv = gsv.SVs[0]; + Assert.AreEqual(22, sv.PrnNumber); + Assert.AreEqual(42, sv.Elevation); + Assert.AreEqual(67, sv.Azimuth); + Assert.AreEqual(42, sv.SignalToNoiseRatio); + + sv = gsv.SVs[1]; + Assert.AreEqual(24, sv.PrnNumber); + Assert.AreEqual(14, sv.Elevation); + Assert.AreEqual(311, sv.Azimuth); + Assert.AreEqual(43, sv.SignalToNoiseRatio); + + sv = gsv.SVs[2]; + Assert.AreEqual(27, sv.PrnNumber); + Assert.AreEqual(5, sv.Elevation); + Assert.AreEqual(244, sv.Azimuth); + Assert.AreEqual(00, sv.SignalToNoiseRatio); + } + + [TestMethod] + public void TestGpgsv_Empty() + { + string input = "$GPGSV,1,1,0,,,,,,,,,,,,,,,,*49"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Gpgsv)); + Gpgsv gsv = (Gpgsv)msg; + Assert.AreEqual(1, gsv.TotalMessages); + Assert.AreEqual(1, gsv.MessageNumber); + Assert.AreEqual(0, gsv.SVsInView); + Assert.IsNotNull(gsv.SVs); + Assert.AreEqual(0, gsv.SVs.Length); + } } }