diff --git a/src/NmeaParser/Nmea/Ggk.cs b/src/NmeaParser/Nmea/Ggk.cs new file mode 100644 index 0000000..589e7b3 --- /dev/null +++ b/src/NmeaParser/Nmea/Ggk.cs @@ -0,0 +1,165 @@ +// ******************************************************************************* +// * 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.Globalization; +using System.Linq; + +namespace NmeaParser.Messages +{ + /// + /// PTNL,GGK: Time, position, position type, DOP + /// + /// + /// + /// 1.: UTC time of position fix, in hhmmss.ss format. Hours must be two numbers, so may be padded. For example, 7 is shown as 07. + /// 2.: UTC date of position fix, in mmddyy format. Day must be two numbers, so may be padded. For example, 8 is shown as 08. + /// 3.: Latitude, in degrees and decimal minutes (dddmm.mmmmmmm) + /// 4.: Direction of latitude: N: North S: South + /// 5.: Longitude, in degrees and decimal minutes (dddmm.mmmmmmm). Should contain three digits of ddd. + /// 6.: Direction of longitude: E: East W: West + /// 7.: GPS Quality indicator: + /// 0: Fix not available or invalid + /// 1: Autonomous GPS fix + /// 2: RTK float solution + /// 3: RTK fix solution + /// 4: Differential, code phase only solution(DGPS) + /// 5: SBAS solution – WAAS/EGNOS/MSAS + /// 6: RTK float or RTK location 3D Network solution + /// 7: RTK fixed 3D Network solution + /// 8: RTK float or RTK location 2D in a Network solution + /// 9: RTK fixed 2D Network solution + /// 10: OmniSTAR HP / XP solution + /// 11: OmniSTAR VBS solution + /// 12: Location RTK solution + /// 13: Beacon DGPS + /// 14: CenterPoint RTX + /// 15: xFill + /// 8.: Number of satellites in fix + /// 9.: Dilution of Precision of fix (DOP) + /// 10.: Ellipsoidal height of fix (antenna height above ellipsoid). + /// 11.: M: ellipsoidal height is measured in meters + /// + /// + /// NOTE – The PTNL,GGK message is longer than the NMEA-0183 standard of 80 characters + /// NOTE – Even if a user-defined geoid model, or an inclined plane is loaded into the receiver, then the height output in the NMEA GGK string is always an ellipsoid height, for example, EHT24.123. + /// + /// + [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ggk")] + [NmeaMessageType("GGK")] + public class Ggk : NmeaMessage + { + /// + /// Initializes a new instance of the class. + /// + /// The message type + /// The NMEA message values. + public Ggk(string type, string[] message) : base(type, message) + { + if (message == null || message.Length < 11) + throw new ArgumentException("Invalid Ggk", "message"); + + UtcTime = StringsToUtcDateTime(message[1], message[0]); + Latitude = StringToLatitude(message[2], message[3]); + Longitude = StringToLongitude(message[4], message[5]); + if (!string.IsNullOrEmpty(message[6])) + Quality = (Ggk.QualityIndicator)int.Parse(message[6], CultureInfo.InvariantCulture); + if (!string.IsNullOrEmpty(message[7])) + NumberOfSatellites = int.Parse(message[7], CultureInfo.InvariantCulture); + DilutionOfPrecision = StringToDouble(message[8]); + EllipsoidalHeightOfFix = StringToDouble(message[9]); + EllipsoidalHeightIsMeasuredInMeters = message[10] == "M"; + } + + /// + /// UTC time of position fix, in DateTime format. + /// DateTime(fullYear, month, day, hours, minutes, seconds, milliseconds, DateTimeKind.Utc) + /// + public DateTime? UtcTime { get; } + + /// + /// Latitude, in degrees and decimal minutes (dddmm.mmmmmmm) + /// + public double Latitude { get; } + + /// + /// Longitude, in degrees and decimal minutes (dddmm.mmmmmmm) + /// + public double Longitude { get; } + + /// + /// GPS Quality indicator + /// + public Ggk.QualityIndicator Quality { get; } + + /// + /// Number of satellites in fix + /// + public int NumberOfSatellites { get; } + + /// + /// Dilution of Precision of fix (DOP) + /// + public double DilutionOfPrecision { get; } + + /// + /// Ellipsoidal height of fix (antenna height above ellipsoid). Must start with EHT. + /// + public double EllipsoidalHeightOfFix { get; } + + /// + /// M: ellipsoidal height is measured in meters + /// + public bool EllipsoidalHeightIsMeasuredInMeters { get; } + + /// + /// GPS Quality indicator + /// + public enum QualityIndicator : int + { + /// Fix not available or invalid + Invalid = 0, + /// Autonomous GPS fix + GpsFix = 1, + /// RTK float solution + RtkFloat = 2, + /// RTK fix solution + RtkFix = 3, + /// Differential, code phase only solution(DGPS) + Ggps = 4, + /// SBAS solution – WAAS/EGNOS/MSAS + Sbas = 5, + /// RTK float or RTK location 3D Network solution + RtkFloatOrLocation3DNetworkSolution = 6, + /// RTK fixed 3D Network solution + RtkFixed3DNetworkSolution = 7, + /// RTK float or RTK location 2D in a Network solution + RtkFloatOrLocation2DNetworkSolution = 8, + /// RTK fixed 2D Network solution + RtkFixed2DNetworkSolution = 9, + /// OmniSTAR HP / XP solution + OmistarHpXp = 10, + /// OmniSTAR VBS solution + OmniStarVbs = 11, + /// Location RTK solution + LocationRtk = 12, + /// Beacon DGPS + BeaconDgps = 13, + /// CenterPoint RTX + CenterPointRtx = 14, + /// xFill + XFill = 15, + } + } +} \ No newline at end of file diff --git a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs index 3d58f9e..a4d5d7b 100644 --- a/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs +++ b/src/UnitTests/NmeaParser.Tests/NmeaMessages.cs @@ -337,6 +337,23 @@ namespace NmeaParser.Tests Assert.AreEqual('M', ptlna.SlopeDistanceUnits); } + [TestMethod] + public void TestPtnlGgk() + { + string input = "$PTNL,GGK,133703.14,012925,6104.64373420,N,01027.91199999,E,2,08,1.0,0.0,M,*0B"; + var msg = NmeaMessage.Parse(input); + Assert.IsInstanceOfType(msg, typeof(Ggk)); + Ggk ggk = (Ggk)msg; + Assert.AreEqual(new DateTime(2025, 1, 29, 13, 37, 3, 140, DateTimeKind.Utc), ggk.UtcTime); + Assert.AreEqual(61.07739557, ggk.Latitude); + Assert.AreEqual(10.465199999833333, ggk.Longitude); + Assert.AreEqual(Ggk.QualityIndicator.RtkFloat, ggk.Quality); + Assert.AreEqual(8, ggk.NumberOfSatellites); + Assert.AreEqual(1, ggk.DilutionOfPrecision); + Assert.AreEqual(0, ggk.EllipsoidalHeightOfFix); + Assert.IsTrue(ggk.EllipsoidalHeightIsMeasuredInMeters); + } + [TestMethod] public void TestPgrme() {