Very large refactoring moving from talker-specific classes to generic message classes, and instead expose talker-type on the base-class.

This commit is contained in:
Morten Nielsen 2019-02-25 23:41:13 -08:00
parent 16da0c7eb4
commit f392416cdd
42 changed files with 757 additions and 1070 deletions

View file

@ -21,21 +21,25 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NmeaParser.Nmea.Gps
namespace NmeaParser.Nmea
{
/// <summary>
/// Bearing Origin to Destination
/// </summary>
/// <remarks>
/// Bearing angle of the line, calculated at the origin waypoint, extending to the destination waypoint from
/// the origin waypoint for the active navigation leg of the journey
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpbod")]
[NmeaMessageType("GPBOD")]
public class Gpbod : NmeaMessage
[NmeaMessageType("--BOD")]
public class Bod : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpbod"/> class.
/// Initializes a new instance of the <see cref="Bod"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpbod(string type, string[] message) : base(type, message)
public Bod(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 3)
throw new ArgumentException("Invalid GPBOD", "message");

View file

@ -1,41 +0,0 @@
//
// 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.Galileo
{
/// <summary>
/// GALILEO Satellites in view
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gagsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("GAGSV")]
public sealed class Gagsv : Gsv
{
/// <summary>
/// Initializes a new instance of the <see cref="Gagsv"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gagsv(string type, string[] message) : base(type, message) { }
}
}

View file

@ -21,7 +21,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NmeaParser.Nmea.Gps.Garmin
namespace NmeaParser.Nmea.Garmin
{
/// <summary>
/// Recommended Minimum

View file

@ -27,21 +27,22 @@ namespace NmeaParser.Nmea
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgga")]
public abstract class Gga : NmeaMessage
[NmeaMessageType("--GGA")]
public class Gga : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gga"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gga(string type, string[] message) : base(type, message)
public Gga(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 14)
throw new ArgumentException("Invalid GPGGA", "message");
FixTime = StringToTimeSpan(message[0]);
Latitude = NmeaMessage.StringToLatitude(message[1], message[2]);
Longitude = NmeaMessage.StringToLongitude(message[3], message[4]);
Quality = (Gps.Gpgga.FixQuality)int.Parse(message[5], CultureInfo.InvariantCulture);
Quality = (Gga.FixQuality)int.Parse(message[5], CultureInfo.InvariantCulture);
NumberOfSatellites = int.Parse(message[6], CultureInfo.InvariantCulture);
Hdop = NmeaMessage.StringToDouble(message[7]);
Altitude = NmeaMessage.StringToDouble(message[8]);
@ -77,7 +78,7 @@ namespace NmeaParser.Nmea
/// <summary>
/// Fix Quality
/// </summary>
public Gps.Gpgga.FixQuality Quality { get; }
public Gga.FixQuality Quality { get; }
/// <summary>
/// Number of satellites being tracked
@ -119,5 +120,34 @@ namespace NmeaParser.Nmea
/// DGPS Station ID Number
/// </summary>
public int DgpsStationId { get; }
}
/// <summary>
/// Fix quality
/// </summary>
public enum FixQuality : int
{
/// <summary>Invalid</summary>
Invalid = 0,
/// <summary>GPS</summary>
GpsFix = 1,
/// <summary>Differential GPS</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dgps")]
DgpsFix = 2,
/// <summary>Precise Positioning Service</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pps")]
PpsFix = 3,
/// <summary>Real Time Kinematic (Fixed)</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rtk")]
Rtk = 4,
/// <summary>Real Time Kinematic (Floating)</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rtk")]
FloatRtk = 5,
/// <summary>Estimated</summary>
Estimated = 6,
/// <summary>Manual input</summary>
ManualInput = 7,
/// <summary>Simulation</summary>
Simulation = 8
}
}
}

View file

@ -27,14 +27,15 @@ namespace NmeaParser.Nmea
/// Geographic position, latitude / longitude
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gll")]
public abstract class Gll : NmeaMessage
[NmeaMessageType("--GLL")]
public class Gll : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gll"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gll(string type, string[] message) : base(type, message)
public Gll(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 4)
throw new ArgumentException("Invalid GPGLL", "message");

View file

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NmeaParser.Nmea.Glonass
{
/// <summary>
/// Fix data for GLONASS satellite navigation systems
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Glgns")]
[NmeaMessageType("GLGNS")]
public class Glgns : Gns
{
/// <summary>
/// Initializes a new instance of the <see cref="Glgns"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Glgns(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,41 +0,0 @@
//
// 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.Glonass
{
/// <summary>
/// GLONASS Satellites in view
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Glgsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("GLGSV")]
public sealed class Glgsv : Gsv
{
/// <summary>
/// Initializes a new instance of the <see cref="Glgsv"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Glgsv(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,17 +0,0 @@
namespace NmeaParser.Nmea.Glonass
{
/// <summary>
/// Date and time of fix
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Glzda")]
[NmeaMessageType("GLZDA")]
public class Glzda : Zda
{
/// <summary>
/// Initializes a new instance of the <see cref="Glzda"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Glzda(string type, string[] message) : base(type, message) { }
}
}

View file

@ -27,7 +27,8 @@ namespace NmeaParser.Nmea
/// Fixes data for single or combined (GPS, GLONASS, possible future satellite systems, and systems combining these) satellite navigation systems
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gns")]
public abstract class Gns : NmeaMessage
[NmeaMessageType("--GNS")]
public class Gns : NmeaMessage
{
/*
* Example of GNS messages:
@ -124,7 +125,7 @@ namespace NmeaParser.Nmea
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gns(string type, string[] message) : base(type, message)
public Gns(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 12)
throw new ArgumentException("Invalid GNS", "message");

View file

@ -1,40 +0,0 @@
//
// 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.Gnss
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gngga")]
[NmeaMessageType("GNGGA")]
public class Gngga : Gga
{
/// <summary>
/// Initializes a new instance of the <see cref="Gngga"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gngga(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,40 +0,0 @@
//
// 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.Gnss
{
/// <summary>
/// Geographic position, latitude / longitude
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gngll")]
[NmeaMessageType("GNGLL")]
public class Gngll : Gll
{
/// <summary>
/// Initializes a new instance of the <see cref="Gngll"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gngll(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NmeaParser.Nmea.Gps
{
/// <summary>
/// Fixes data for single or combined (GPS, GLONASS, possible future satellite systems, and systems combining these) satellite navigation systems
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gngns")]
[NmeaMessageType("GNGNS")]
public class Gngns : Gns
{
/// <summary>
/// Initializes a new instance of the <see cref="Gngns"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gngns(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,40 +0,0 @@
//
// 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.Gnss
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gngsa")]
[NmeaMessageType("GNGSA")]
public class Gngsa : Gsa
{
/// <summary>
/// Initializes a new instance of the <see cref="Gngsa"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gngsa(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,19 +0,0 @@
using System;
namespace NmeaParser.Nmea.Gnss
{
/// <summary>
/// Position error statistics
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gngst")]
[NmeaMessageType("GNGST")]
public class Gngst : Gst
{
/// <summary>
/// Initializes a new instance of the <see cref="Gngst"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gngst(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,40 +0,0 @@
//
// 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.Gnss
{
/// <summary>
/// Recommended Minimum
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gnrmc")]
[NmeaMessageType("GNRMC")]
public class Gnrmc : Rmc
{
/// <summary>
/// Initializes a new instance of the <see cref="Gnrmc"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gnrmc(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,17 +0,0 @@
namespace NmeaParser.Nmea.Gnss
{
/// <summary>
/// Date and time of fix
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gnzda")]
[NmeaMessageType("GNZDA")]
public class Gnzda : Zda
{
/// <summary>
/// Initializes a new instance of the <see cref="Gnzda"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gnzda(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,69 +0,0 @@
//
// 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
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgga")]
[NmeaMessageType("GPGGA")]
public class Gpgga : Gga
{
/// <summary>
/// Fix quality
/// </summary>
public enum FixQuality : int
{
/// <summary>Invalid</summary>
Invalid = 0,
/// <summary>GPS</summary>
GpsFix = 1,
/// <summary>Differential GPS</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Dgps")]
DgpsFix = 2,
/// <summary>Precise Positioning Service</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pps")]
PpsFix = 3,
/// <summary>Real Time Kinematic (Fixed)</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rtk")]
Rtk = 4,
/// <summary>Real Time Kinematic (Floating)</summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rtk")]
FloatRtk = 5,
/// <summary>Estimated</summary>
Estimated = 6,
/// <summary>Manual input</summary>
ManualInput = 7,
/// <summary>Simulation</summary>
Simulation = 8
}
/// <summary>
/// Initializes a new instance of the <see cref="Gpgga"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgga(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,40 +0,0 @@
//
// 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
{
/// <summary>
/// Geographic position, latitude / longitude
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgll")]
[NmeaMessageType("GPGLL")]
public class Gpgll : Gll
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpgll"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgll(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,74 +0,0 @@
//
// 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
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgsa")]
[NmeaMessageType("GPGSA")]
public class Gpgsa : Gsa
{
/// <summary>
/// Mode selection
/// </summary>
public enum ModeSelection
{
/// <summary>
/// Auto
/// </summary>
Auto,
/// <summary>
/// Manual mode
/// </summary>
Manual,
}
/// <summary>
/// Fix Mode
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "Enum values matches NMEA spec")]
public enum Mode : int
{
/// <summary>
/// Not available
/// </summary>
NotAvailable = 1,
/// <summary>
/// 2D Fix
/// </summary>
Fix2D = 2,
/// <summary>
/// 3D Fix
/// </summary>
Fix3D = 3
}
/// <summary>
/// Initializes a new instance of the <see cref="Gpgsa"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgsa(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,40 +0,0 @@
//
// 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
{
/// <summary>
/// Position error statistics
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgst")]
[NmeaMessageType("GPGST")]
public class Gpgst : Gst
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpgst"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgst(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,120 +0,0 @@
//
// 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
{
/// <summary>
/// GLONASS Satellites in view
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("GPGSV")]
public sealed class Gpgsv : Gsv
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpgst"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgsv(string type, string[] message) : base(type, message) { }
}
/// <summary>
/// Satellite vehicle
/// </summary>
public sealed class SatelliteVehicle
{
internal SatelliteVehicle(string[] message, int startIndex)
{
PrnNumber = int.Parse(message[startIndex], CultureInfo.InvariantCulture);
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;
}
/// <summary>
/// SV PRN number
/// </summary>
public int PrnNumber { get; }
/// <summary>
/// Elevation in degrees, 90 maximum
/// </summary>
public double Elevation{ get; }
/// <summary>
/// Azimuth, degrees from true north, 000 to 359
/// </summary>
public double Azimuth{ get; }
/// <summary>
/// Signal-to-Noise ratio, 0-99 dB (-1 when not tracking)
/// </summary>
public int SignalToNoiseRatio{ get; }
/// <summary>
/// Satellite system
/// </summary>
public SatelliteSystem System
{
get
{
if (PrnNumber >= 1 && PrnNumber <= 32)
return SatelliteSystem.Gps;
if (PrnNumber >= 33 && PrnNumber <= 64)
return SatelliteSystem.Waas;
if (PrnNumber >= 65 && PrnNumber <= 96)
return SatelliteSystem.Glonass;
return SatelliteSystem.Unknown;
}
}
}
/// <summary>
/// Satellite system
/// </summary>
public enum SatelliteSystem
{
/// <summary>
/// Unknown
/// </summary>
Unknown,
/// <summary>
/// GPS - Global Positioning System (NAVSTAR)
/// </summary>
Gps,
/// <summary>
/// WAAS - Wide Area Augmentation System
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Waas")]
Waas,
/// <summary>
/// GLONASS - Globalnaya navigatsionnaya sputnikovaya sistema
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Glonass")]
Glonass,
/// <summary>
/// Galileo
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Galileo")]
Galileo
}
}

View file

@ -1,40 +0,0 @@
//
// 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
{
/// <summary>
/// Recommended Minimum
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprmc")]
[NmeaMessageType("GPRMC")]
public class Gprmc : Rmc
{
/// <summary>
/// Initializes a new instance of the <see cref="Gprmc"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gprmc(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,17 +0,0 @@
namespace NmeaParser.Nmea.Gps
{
/// <summary>
/// Date and time of fix
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpzda")]
[NmeaMessageType("GPZDA")]
public class Gpzda : Zda
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpzda"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpzda(string type, string[] message) : base(type, message) { }
}
}

View file

@ -1,21 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NmeaParser.Nmea.Gps
{
/// <summary>
/// Fixes data for GPS satellite navigation systems
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgns")]
[NmeaMessageType("GPGNS")]
public class Gpgns : Gns
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpgns"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpgns(string type, string[] message) : base(type, message) { }
}
}

View file

@ -23,82 +23,117 @@ using System.Threading.Tasks;
namespace NmeaParser.Nmea
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gsa")]
public abstract class Gsa : NmeaMessage
{
/// <summary>
/// Global Positioning System Fix Data
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gsa")]
[NmeaMessageType("--GSA")]
public class Gsa : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gsa"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gsa(string type, string[] message) : base(type, message)
public Gsa(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 17)
throw new ArgumentException("Invalid GPGSA", "message");
GpsMode = message[0] == "A" ? Gps.Gpgsa.ModeSelection.Auto : Gps.Gpgsa.ModeSelection.Manual;
FixMode = (Gps.Gpgsa.Mode)int.Parse(message[1], CultureInfo.InvariantCulture);
throw new ArgumentException("Invalid GPGSA", "message");
List<int> svs = new List<int>();
for (int i = 2; i < 14; i++)
{
int id = -1;
if (message[i].Length > 0 && int.TryParse(message[i], out id))
svs.Add(id);
}
SVs = svs.ToArray();
GpsMode = message[0] == "A" ? Gsa.ModeSelection.Auto : Gsa.ModeSelection.Manual;
FixMode = (Gsa.Mode)int.Parse(message[1], CultureInfo.InvariantCulture);
double tmp;
if (double.TryParse(message[14], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Pdop = tmp;
else
Pdop = double.NaN;
List<int> svs = new List<int>();
for (int i = 2; i < 14; i++)
{
int id = -1;
if (message[i].Length > 0 && int.TryParse(message[i], out id))
svs.Add(id);
}
SVs = svs.ToArray();
if (double.TryParse(message[15], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Hdop = tmp;
else
Hdop = double.NaN;
double tmp;
if (double.TryParse(message[14], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Pdop = tmp;
else
Pdop = double.NaN;
if (double.TryParse(message[16], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Vdop = tmp;
else
Vdop = double.NaN;
}
if (double.TryParse(message[15], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Hdop = tmp;
else
Hdop = double.NaN;
/// <summary>
/// Mode
/// </summary>
public Gps.Gpgsa.ModeSelection GpsMode { get; }
if (double.TryParse(message[16], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
Vdop = tmp;
else
Vdop = double.NaN;
}
/// <summary>
/// Mode
/// </summary>
public Gps.Gpgsa.Mode FixMode { get; }
/// <summary>
/// Mode
/// </summary>
public ModeSelection GpsMode { get; }
/// <summary>
/// IDs of SVs used in position fix
/// </summary>
public IReadOnlyList<int> SVs { get; }
/// <summary>
/// Mode
/// </summary>
public Mode FixMode { get; }
/// <summary>
/// Dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pdop")]
public double Pdop { get; }
/// <summary>
/// IDs of SVs used in position fix
/// </summary>
public IReadOnlyList<int> SVs { get; }
/// <summary>
/// Horizontal dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hdop")]
public double Hdop { get; }
/// <summary>
/// Dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Pdop")]
public double Pdop { get; }
/// <summary>
/// Vertical dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Vdop")]
public double Vdop { get; }
}
}
/// <summary>
/// Horizontal dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hdop")]
public double Hdop { get; }
/// <summary>
/// Vertical dilution of precision
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Vdop")]
public double Vdop { get; }
/// <summary>
/// Mode selection
/// </summary>
public enum ModeSelection
{
/// <summary>
/// Auto
/// </summary>
Auto,
/// <summary>
/// Manual mode
/// </summary>
Manual,
}
/// <summary>
/// Fix Mode
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue", Justification = "Enum values matches NMEA spec")]
public enum Mode : int
{
/// <summary>
/// Not available
/// </summary>
NotAvailable = 1,
/// <summary>
/// 2D Fix
/// </summary>
Fix2D = 2,
/// <summary>
/// 3D Fix
/// </summary>
Fix3D = 3
}
}
}

View file

@ -27,14 +27,15 @@ namespace NmeaParser.Nmea
/// Position error statistics
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gpgst")]
public abstract class Gst : NmeaMessage
[NmeaMessageType("--GST")]
public class Gst : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gst"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gst(string type, string[] message) : base(type, message)
public Gst(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 8)
throw new ArgumentException("Invalid GPGST", "message");

View file

@ -23,76 +23,155 @@ using System.Text;
using System.Threading.Tasks;
namespace NmeaParser.Nmea
{
/// <summary>
/// GPS Satellites in view
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
public abstract class Gsv : NmeaMessage, IMultiPartMessage<SatelliteVehicle>
{
{
/// <summary>
/// GPS Satellites in view
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gsv")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("--GSV")]
public class Gsv : NmeaMessage, IMultiPartMessage<SatelliteVehicle>
{
/// <summary>
/// Initializes a new instance of the <see cref="Gsv"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Gsv(string type, string[] message) : base(type, message)
public Gsv(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 3)
throw new ArgumentException("Invalid GSV", "message");
TotalMessages = int.Parse(message[0], CultureInfo.InvariantCulture);
MessageNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
SVsInView = int.Parse(message[2], CultureInfo.InvariantCulture);
List<SatelliteVehicle> svs = new List<SatelliteVehicle>();
for (int i = 3; i < message.Length - 3; i += 4)
{
if (message[i].Length == 0)
continue;
else
svs.Add(new SatelliteVehicle(message, i));
}
this.SVs = svs.ToArray();
}
/// <summary>
/// Total number of messages of this type in this cycle
/// </summary>
public int TotalMessages { get; }
/// <summary>
/// Message number
/// </summary>
public int MessageNumber { get; }
/// <summary>
/// Total number of SVs in view
/// </summary>
public int SVsInView { get; }
/// <summary>
/// Satellite vehicles in this message part.
/// </summary>
public IReadOnlyList<SatelliteVehicle> SVs { get; }
if (message == null || message.Length < 3)
throw new ArgumentException("Invalid GSV", "message");
TotalMessages = int.Parse(message[0], CultureInfo.InvariantCulture);
MessageNumber = int.Parse(message[1], CultureInfo.InvariantCulture);
SVsInView = int.Parse(message[2], CultureInfo.InvariantCulture);
List<SatelliteVehicle> svs = new List<SatelliteVehicle>();
for (int i = 3; i < message.Length - 3; i += 4)
{
if (message[i].Length == 0)
continue;
else
svs.Add(new SatelliteVehicle(message, i));
}
this.SVs = svs.ToArray();
}
/// <summary>
/// Total number of messages of this type in this cycle
/// </summary>
public int TotalMessages { get; }
/// <summary>
/// Message number
/// </summary>
public int MessageNumber { get; }
/// <summary>
/// Total number of SVs in view
/// </summary>
public int SVsInView { get; }
/// <summary>
/// Satellite vehicles in this message part.
/// </summary>
public IReadOnlyList<SatelliteVehicle> SVs { get; }
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns> A System.Collections.Generic.IEnumerator{SatelliteVehicle} that can be used to iterate through the collection.</returns>
public IEnumerator<SatelliteVehicle> GetEnumerator()
{
foreach(var sv in SVs)
yield return sv;
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns> An System.Collections.IEnumerator object that can be used to iterate through the collection.</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
public IEnumerator<SatelliteVehicle> GetEnumerator()
{
foreach (var sv in SVs)
yield return sv;
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns> An System.Collections.IEnumerator object that can be used to iterate through the collection.</returns>
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
/// <summary>
/// Satellite vehicle
/// </summary>
public sealed class SatelliteVehicle
{
internal SatelliteVehicle(string[] message, int startIndex)
{
PrnNumber = int.Parse(message[startIndex], CultureInfo.InvariantCulture);
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;
}
/// <summary>
/// SV PRN number
/// </summary>
public int PrnNumber { get; }
/// <summary>
/// Elevation in degrees, 90 maximum
/// </summary>
public double Elevation { get; }
/// <summary>
/// Azimuth, degrees from true north, 000 to 359
/// </summary>
public double Azimuth { get; }
/// <summary>
/// Signal-to-Noise ratio, 0-99 dB (-1 when not tracking)
/// </summary>
public int SignalToNoiseRatio { get; }
/// <summary>
/// Satellite system
/// </summary>
public SatelliteSystem System
{
get
{
if (PrnNumber >= 1 && PrnNumber <= 32)
return SatelliteSystem.Gps;
if (PrnNumber >= 33 && PrnNumber <= 64)
return SatelliteSystem.Waas;
if (PrnNumber >= 65 && PrnNumber <= 96)
return SatelliteSystem.Glonass;
return SatelliteSystem.Unknown;
}
}
}
/// <summary>
/// Satellite system
/// </summary>
public enum SatelliteSystem
{
/// <summary>
/// Unknown
/// </summary>
Unknown,
/// <summary>
/// GPS - Global Positioning System (NAVSTAR)
/// </summary>
Gps,
/// <summary>
/// WAAS - Wide Area Augmentation System
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Waas")]
Waas,
/// <summary>
/// GLONASS - Globalnaya navigatsionnaya sputnikovaya sistema
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Glonass")]
Glonass,
/// <summary>
/// Galileo
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Galileo")]
Galileo
}
}

View file

@ -44,11 +44,11 @@ namespace NmeaParser.Nmea
public string NmeaType { get; private set; }
}
/// <summary>
/// NMEA Message base class.
/// </summary>
public abstract class NmeaMessage
{
/// <summary>
/// NMEA Message base class.
/// </summary>
public abstract class NmeaMessage
{
private readonly static Dictionary<string, ConstructorInfo> messageTypes;
/// <summary>
@ -87,70 +87,84 @@ namespace NmeaParser.Nmea
}
}
/// <summary>
/// Parses the specified NMEA message.
/// </summary>
/// <param name="message">The NMEA message string.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentException">
/// Invalid nmea message: Missing starting character '$'
/// or checksum failure
/// </exception>
public static NmeaMessage Parse(string message)
{
if (string.IsNullOrEmpty(message))
throw new ArgumentNullException("message");
int checksum = -1;
if (message[0] != '$')
throw new ArgumentException("Invalid nmea message: Missing starting character '$'");
var idx = message.IndexOf('*');
if (idx >= 0)
{
checksum = Convert.ToInt32(message.Substring(idx + 1), 16);
message = message.Substring(0, message.IndexOf('*'));
}
if (checksum > -1)
{
int checksumTest = 0;
for (int i = 1; i < message.Length; i++)
{
checksumTest ^= Convert.ToByte(message[i]);
}
if (checksum != checksumTest)
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid nmea message: Checksum failure. Got {0:X2}, Expected {1:X2}", checksum, checksumTest));
}
/// <summary>
/// Parses the specified NMEA message.
/// </summary>
/// <param name="message">The NMEA message string.</param>
/// <returns></returns>
/// <exception cref="System.ArgumentException">
/// Invalid nmea message: Missing starting character '$'
/// or checksum failure
/// </exception>
public static NmeaMessage Parse(string message)
{
if (string.IsNullOrEmpty(message))
throw new ArgumentNullException("message");
string[] parts = message.Split(new char[] { ',' });
string MessageType = parts[0].Substring(1);
string[] MessageParts = parts.Skip(1).ToArray();
if (messageTypes.ContainsKey(MessageType))
{
return (NmeaMessage)messageTypes[MessageType].Invoke(new object[] { MessageType, MessageParts });
}
else
{
int checksum = -1;
if (message[0] != '$')
throw new ArgumentException("Invalid nmea message: Missing starting character '$'");
var idx = message.IndexOf('*');
if (idx >= 0)
{
checksum = Convert.ToInt32(message.Substring(idx + 1), 16);
message = message.Substring(0, message.IndexOf('*'));
}
if (checksum > -1)
{
int checksumTest = 0;
for (int i = 1; i < message.Length; i++)
{
checksumTest ^= Convert.ToByte(message[i]);
}
if (checksum != checksumTest)
throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "Invalid nmea message: Checksum failure. Got {0:X2}, Expected {1:X2}", checksum, checksumTest));
}
string[] parts = message.Split(new char[] { ',' });
string MessageType = parts[0].Substring(1);
string[] MessageParts = parts.Skip(1).ToArray();
if (messageTypes.ContainsKey(MessageType))
{
return (NmeaMessage)messageTypes[MessageType].Invoke(new object[] { MessageType, MessageParts });
}
else if (messageTypes.ContainsKey("--" + MessageType.Substring(2)))
{
return (NmeaMessage)messageTypes["--" + MessageType.Substring(2)].Invoke(new object[] { MessageType, MessageParts });
}
else
{
return new UnknownMessage(MessageType, MessageParts);
}
}
}
}
/// <summary>
/// Gets the NMEA message parts.
/// </summary>
protected IReadOnlyList<string> MessageParts { get; }
/// <summary>
/// Gets the NMEA message parts.
/// </summary>
protected IReadOnlyList<string> MessageParts { get; }
/// <summary>
/// Gets the NMEA type id for the message.
/// </summary>
public string MessageType { get; }
/// <summary>
/// Gets the NMEA type id for the message.
/// </summary>
public string MessageType { get; }
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
/// <summary>
/// Gets the talker ID for this message (
/// </summary>
public Talker TalkerId => TalkerHelper.GetTalker(MessageType);
/// <summary>
/// Gets a value indicating whether this message type is proprietary
/// </summary>
public bool IsProprietary => MessageType[0] == 'P'; //Appendix B
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "${0},{1}*{2:X2}", MessageType, string.Join(",", MessageParts), Checksum);
}

View file

@ -27,8 +27,8 @@ namespace NmeaParser.Nmea.Gps
/// Recommended minimum navigation information
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprmb")]
[NmeaMessageType("GPRMB")]
public class Gprmb : NmeaMessage
[NmeaMessageType("--RMB")]
public class Rmb : NmeaMessage
{
/// <summary>
/// Data status
@ -46,16 +46,16 @@ namespace NmeaParser.Nmea.Gps
}
/// <summary>
/// Initializes a new instance of the <see cref="Gprmb"/> class.
/// Initializes a new instance of the <see cref="Rmb"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gprmb(string type, string[] message) : base(type, message)
public Rmb(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 13)
throw new ArgumentException("Invalid GPRMB", "message");
Status = message[0] == "A" ? DataStatus.Ok : Gprmb.DataStatus.Warning;
Status = message[0] == "A" ? DataStatus.Ok : Rmb.DataStatus.Warning;
double tmp;
if (double.TryParse(message[1], NumberStyles.Float, CultureInfo.InvariantCulture, out tmp))
{

View file

@ -27,14 +27,15 @@ namespace NmeaParser.Nmea
/// Recommended Minimum
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprmc")]
public abstract class Rmc : NmeaMessage
[NmeaMessageType("--RMC")]
public class Rmc : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Rmc"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Rmc(string type, string[] message) : base(type, message)
public Rmc(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 11)
throw new ArgumentException("Invalid GPRMC", "message");

View file

@ -24,12 +24,19 @@ using System.Threading.Tasks;
namespace NmeaParser.Nmea.Gps
{
/// <summary>
/// Routes
/// Routes
/// </summary>
/// <remarks>
/// Waypoint identifiers, listed in order with starting waypoint first, for the identified route. Two modes of
/// transmission are provided: 'c' indicates that the complete list of waypoints in the route are being
/// transmitted; 'w' indicates a working route where the first listed waypoint is always the last waypoint
/// that had been reached (FROM), while the second listed waypoint is always the waypoint that the vessel is
/// currently heading for (TO), the remaining list of waypoints represents the remainder of the route.
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Gprte")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
[NmeaMessageType("GPRTE")]
public sealed class Gprte : NmeaMessage, IMultiPartMessage<string>
[NmeaMessageType("--RTE")]
public sealed class Rte : NmeaMessage, IMultiPartMessage<string>
{
/// <summary>
/// Waypoint tpe
@ -51,7 +58,7 @@ namespace NmeaParser.Nmea.Gps
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gprte(string type, string[] message) : base(type, message)
public Rte(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 4)
throw new ArgumentException("Invalid GPRTE", "message");

View file

@ -0,0 +1,257 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace NmeaParser.Nmea
{
internal static class TalkerHelper
{
internal static Talker GetTalker(string messageType)
{
if (messageType[0] == 'P')
return Talker.ProprietaryCode;
if (TalkerLookupTable.ContainsKey(messageType.Substring(0, 2)))
{
return TalkerLookupTable[messageType.Substring(0, 2)];
}
return Talker.Unknown;
}
private static readonly Dictionary<string, Talker> TalkerLookupTable = new Dictionary<string, Talker>()
{
{"AB", Talker.IndependentAISBaseStation },
{"AD", Talker.DependentAISBaseStation },
{"AG", Talker.HeadingTrackControllerGeneral },
{"AP", Talker.HeadingTrackControllerMagnetic },
{"AI", Talker.MobileClassAorBAISStation },
{"AN", Talker.AISAidstoNavigationStation },
{"AR", Talker.AISReceivingStation },
{"AS", Talker.AISStation },
{"AT", Talker.AISTransmittingStation },
{"AX", Talker.AISSimplexRepeaterStation },
{"BI", Talker.BilgeSystems },
{"CD", Talker.DigitalSelectiveCalling },
{"CR", Talker.DataReceiver },
{"CS", Talker.Satellite },
{"CT", Talker.RadioTelephoneMFHF },
{"CV", Talker.RadioTelephoneVHF },
{"CX", Talker.ScanningReceiver },
{"DE", Talker.DECCANavigator },
{"DF", Talker.DirectionFinder },
{"DU", Talker.DuplexRepeaterStation },
{"EC", Talker.ElectronicChartSystem },
{"EI", Talker.ElectronicChartDisplayInformationSystem },
{"EP", Talker.EmergencyPositionIndicatingBeacon },
{"ER", Talker.EngineRoomMonitoringSystems },
{"FD", Talker.FireDoorControllerMonitoringPoint },
{"FE", Talker.FireExtinguisherSystem },
{"FR", Talker.FireDetectionPoint },
{"FS", Talker.FireSprinklerSystem },
{"GA", Talker.GalileoPositioningSystem },
{"GL", Talker.GlonassReceiver },
{"GN", Talker.GlobalNavigationSatelliteSystem },
{"GP", Talker.GlobalPositioningSystem },
{"HC", Talker.CompassMagnetic },
{"HE", Talker.GyroNorthSeeking },
{"HF", Talker.Fluxgate },
{"HN", Talker.GyroNonNorthSeeking },
{"HD", Talker.HullDoorControllerMonitoringPanel },
{"HS", Talker.HullStressMonitoring },
{"II", Talker.IntegratedInstrumentation },
{"IN", Talker.IntegratedNavigation },
{"LC", Talker.LoranC },
{"P ", Talker.ProprietaryCode },
{"RA", Talker.RadarAndOrRadarPlotting },
{"RC", Talker.PropulsionMachineryIncludingRemoteControl },
{"SA", Talker.PhysicalShoreAISStation },
{"SD", Talker.SounderDepth },
{"SG", Talker.SteeringGearSteeringEngine },
{"SN", Talker.ElectronicPositioningSystem },
{"SS", Talker.SounderScanning },
{"TI", Talker.TurnRateIndicator },
{"UP", Talker.MicroprocessorController },
{"U0", Talker.UserID0 },
{"U1", Talker.UserID1 },
{"U2", Talker.UserID2 },
{"U3", Talker.UserID3 },
{"U4", Talker.UserID4 },
{"U5", Talker.UserID5 },
{"U6", Talker.UserID6 },
{"U7", Talker.UserID7 },
{"U8", Talker.UserID8 },
{"U9", Talker.UserID9 },
{"VD", Talker.Doppler },
{"VM", Talker.SpeedLogWaterMagnetic },
{"VW", Talker.SpeedLogWaterMechanical },
{"VR", Talker.VoyageDataRecorder },
{"WD", Talker.WatertightDoorControllerMonitoringPanel },
{"WI", Talker.WeatherInstruments },
{"WL", Talker.WaterLevelDetectionSystems },
{"YX", Talker.Transducer },
{"ZA", Talker.AtomicsClock },
{"ZC", Talker.Chronometer },
{"ZQ", Talker.Quartz },
{"ZV", Talker.RadioUpdate },
};
}
/// <summary>
/// Talker Identifier
/// </summary>
public enum Talker
{
/// <summary>
/// Unrecognized Talker ID
/// </summary>
Unknown,
/// <summary>Independent AIS Base Station</summary>
IndependentAISBaseStation, // = AB
/// <summary>Dependent AIS Base Station</summary>
DependentAISBaseStation, // = AD
/// <summary>Heading Track Controller (Autopilot) - General</summary>
HeadingTrackControllerGeneral, // = AG
/// <summary>Heading Track Controller (Autopilot) - Magnetic</summary>
HeadingTrackControllerMagnetic, // = AP
/// <summary>Mobile Class A or B AIS Station</summary>
MobileClassAorBAISStation, // = AI
/// <summary>AIS Aids to Navigation Station </summary>
AISAidstoNavigationStation, // = AN
/// <summary>AIS Receiving Station</summary>
AISReceivingStation, // = AR
/// <summary>AIS Station (ITU_R M1371, (“Limited Base Station)</summary>
AISStation, // = AS
/// <summary>AIS Transmitting Station</summary>
AISTransmittingStation, // = AT
/// <summary>AIS Simplex Repeater Station</summary>
AISSimplexRepeaterStation, // = AX
/// <summary>Bilge Systems</summary>
BilgeSystems, // = BI
/// <summary></summary>
DigitalSelectiveCalling, // = CD
/// <summary></summary>
DataReceiver, // = CR
/// <summary></summary>
Satellite, // = CS
/// <summary></summary>
RadioTelephoneMFHF, // = CT
/// <summary></summary>
RadioTelephoneVHF, // = CV
/// <summary></summary>
ScanningReceiver, // = CX
/// <summary></summary>
DECCANavigator, // = DE
/// <summary></summary>
DirectionFinder, // = DF
/// <summary></summary>
DuplexRepeaterStation, // = DU
/// <summary></summary>
ElectronicChartSystem, // = EC
/// <summary></summary>
ElectronicChartDisplayInformationSystem, // = EI
/// <summary></summary>
EmergencyPositionIndicatingBeacon, // = EP
/// <summary></summary>
EngineRoomMonitoringSystems, // = ER
/// <summary></summary>
FireDoorControllerMonitoringPoint, // = FD
/// <summary></summary>
FireExtinguisherSystem, // = FE
/// <summary></summary>
FireDetectionPoint, // = FR
/// <summary></summary>
FireSprinklerSystem, // = FS
/// <summary>Galileo Positioning System</summary>
GalileoPositioningSystem, // = GA
/// <summary>GLONASS Receiver</summary>
GlonassReceiver, // = GL
/// <summary>Global Navigation Satellite System (GNSS</summary>
GlobalNavigationSatelliteSystem, // = GN
/// <summary>Global Positioning System (GPS)</summary>
GlobalPositioningSystem, // = GPS
/// <summary>Heading Sensor - Compass, Magnetic</summary>
CompassMagnetic, // = HC
/// <summary>Heading Sensor - Gyro, North Seeking</summary>
GyroNorthSeeking, // = HE
/// <summary>Heading Sensor - Fluxgate</summary>
Fluxgate, // = HF
/// <summary>Heading Sensor - Gyro, Non-North Seeking</summary>
GyroNonNorthSeeking, // = HN
/// <summary>Hull Door Controller/Monitoring Panel</summary>
HullDoorControllerMonitoringPanel, // = HD
/// <summary>Hull Stress Monitoring</summary>
HullStressMonitoring, // = HS
/// <summary>Integrated Instrumentation</summary>
IntegratedInstrumentation, // = II
/// <summary>Integrated Navigation</summary>
IntegratedNavigation, // = IN
/// <summary>Loran C</summary>
LoranC, // = LC
/// <summary></summary>
ProprietaryCode, // = P
/// <summary></summary>
RadarAndOrRadarPlotting, // = RA
/// <summary></summary>
PropulsionMachineryIncludingRemoteControl, // = RC
/// <summary></summary>
PhysicalShoreAISStation, // = SA
/// <summary></summary>
SounderDepth, // = SD
/// <summary></summary>
SteeringGearSteeringEngine, // = SG
/// <summary></summary>
ElectronicPositioningSystem, // = SN
/// <summary></summary>
SounderScanning, // = SS
/// <summary></summary>
TurnRateIndicator, // = TI
/// <summary></summary>
MicroprocessorController, // = UP
/// <summary>User configured talker identifier</summary>
UserID0, // = U0
/// <summary>User configured talker identifier</summary>
UserID1, // = U1
/// <summary>User configured talker identifier</summary>
UserID2, // = U2
/// <summary>User configured talker identifier</summary>
UserID3, // = U3
/// <summary>User configured talker identifier</summary>
UserID4, // = U4
/// <summary>User configured talker identifier</summary>
UserID5, // = U5
/// <summary>User configured talker identifier</summary>
UserID6, // = U6
/// <summary>User configured talker identifier</summary>
UserID7, // = U7
/// <summary>User configured talker identifier</summary>
UserID8, // = U8
/// <summary>User configured talker identifier</summary>
UserID9, // = U9
/// <summary>Velocity sensor - Doppler</summary>
Doppler, // = VD
/// <summary>Velocity sensor - Speed Log, Water, Magnetic</summary>
SpeedLogWaterMagnetic, // = VM
/// <summary>Velocity sensor - Speed Log, Water Mechanical</summary>
SpeedLogWaterMechanical, // = VW
/// <summary>Voyage Data Recorder</summary>
VoyageDataRecorder, // = VR
/// <summary>Watertight Door Controller/Monitoring Panel</summary>
WatertightDoorControllerMonitoringPanel, // = WD
/// <summary>Weather Instruments</summary>
WeatherInstruments, // = WI
/// <summary>Water Level Detection Systems </summary>
WaterLevelDetectionSystems, // = WL
/// <summary>Transducer</summary>
Transducer, // = YX
/// <summary>Time keeper - Atomics Clock</summary>
AtomicsClock, // = ZA
/// <summary>Time keeper - Chronometer</summary>
Chronometer, // = ZC
/// <summary>Time keeper - Quartz</summary>
Quartz, // = ZQ
/// <summary>Time keeper - Radio Update</summary>
RadioUpdate, // = ZV
}
}

View file

@ -23,16 +23,19 @@ namespace NmeaParser.Nmea.Gps
/// <summary>
/// Course over ground and ground speed
/// </summary>
/// <remarks>
/// The actual course and speed relative to the ground.
/// </remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "GPVTG")]
[NmeaMessageType("GPVTG")]
public class Gpvtg : NmeaMessage
[NmeaMessageType("--VTG")]
public class Vtg : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Gpvtg"/> class.
/// Initializes a new instance of the <see cref="Vtg"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
public Gpvtg(string type, string[] message) : base(type, message)
public Vtg(string type, string[] message) : base(type, message)
{
if (message == null || message.Length < 7)
throw new ArgumentException("Invalid Gpvtg", "message");

View file

@ -7,14 +7,15 @@ namespace NmeaParser.Nmea
/// Date and time of fix
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Zda")]
public abstract class Zda : NmeaMessage
[NmeaMessageType("--ZDA")]
public class Zda : NmeaMessage
{
/// <summary>
/// Initializes a new instance of the <see cref="Zda"/> class.
/// </summary>
/// <param name="type">The message type</param>
/// <param name="message">The NMEA message values.</param>
protected Zda(string type, string[] message) : base(type, message)
public Zda(string type, string[] message) : base(type, message)
{
if (message?.Length != 6)
{

View file

@ -11,7 +11,7 @@
<Description>An NMEA stream parser for serial port, bluetooth and file-based nmea simulation.</Description>
<PackageTags>nmea winrt wpf uwp xamarin gps serialport bluetooth</PackageTags>
<PackageId>SharpGIS.NmeaParser</PackageId>
<Version>1.11</Version>
<Version>2.0-beta1</Version>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/dotMorten/NmeaParser</PackageProjectUrl>
<RepositoryUrl>https://github.com/dotMorten/NmeaParser</RepositoryUrl>
@ -19,7 +19,10 @@
<Copyright>Copyright © Morten Nielsen 2015-2019</Copyright>
<OutputPath>$(MSBuildThisFileDirectory)..\Bin\$(Configuration)</OutputPath>
<PackageOutputPath>$(OutDir)</PackageOutputPath>
<PackageReleaseNotes>Lots of API cleanup to avoid null-references. Simplify object model for creation (semi-breaking). Updated license to Apache 2.0</PackageReleaseNotes>
<PackageReleaseNotes>Lots of API cleanup to avoid null-references.
Revamped talker-specific message to use same class, instead of having talker-specific types (breaking).
Simplify object model for creation (semi-breaking).
Updated license to Apache 2.0</PackageReleaseNotes>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<AllowedOutputExtensionsInPackageBuildOutputFolder>$(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb</AllowedOutputExtensionsInPackageBuildOutputFolder>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="SampleApp.Droid.SampleApp.Droid" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="21" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH" />

View file

@ -16,7 +16,6 @@
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
<MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>

View file

@ -110,8 +110,8 @@ namespace SampleApp.WinDesktop
gpgsaView.Message = args.Message as NmeaParser.Nmea.Gsa;
else if (args.Message is NmeaParser.Nmea.Gll)
gpgllView.Message = args.Message as NmeaParser.Nmea.Gll;
else if (args.Message is NmeaParser.Nmea.Gps.Garmin.Pgrme)
pgrmeView.Message = args.Message as NmeaParser.Nmea.Gps.Garmin.Pgrme;
else if (args.Message is NmeaParser.Nmea.Garmin.Pgrme)
pgrmeView.Message = args.Message as NmeaParser.Nmea.Garmin.Pgrme;
else
{
var ctrl = MessagePanel.Children.OfType<UnknownMessageControl>().Where(c => c.Message.MessageType == args.Message.MessageType).FirstOrDefault();

View file

@ -1,5 +1,4 @@
using NmeaParser.Nmea.Gps;
using NmeaParser.Nmea.Gps.Garmin;
using NmeaParser.Nmea.Garmin;
using System;
using System.Collections.Generic;
using System.Linq;

View file

@ -1,4 +1,5 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;
using NmeaParser.Nmea;
using System;
using System.Collections.Generic;
using System.Linq;
@ -24,8 +25,8 @@ namespace NmeaParser.Tests
try
{
Assert.IsTrue(e.IsMultipart, "IsMultiPart");
Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gps.Gpgsv));
var msg = e.Message as NmeaParser.Nmea.Gps.Gpgsv;
Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
var msg = e.Message as NmeaParser.Nmea.Gsv;
if (msg.TotalMessages == msg.MessageNumber)
{
Assert.IsNotNull(e.MessageParts);
@ -71,10 +72,15 @@ $GAGSV,4,4,14,19,82,349,40,1,44,220,40,4,24,314,38*5F";
{
Assert.IsNotNull(e.MessageParts);
Assert.AreEqual(e.MessageParts.Count, 4, "MessageParts.Length");
Assert.IsInstanceOfType(e.MessageParts[0], typeof(NmeaParser.Nmea.Gps.Gpgsv));
Assert.IsInstanceOfType(e.MessageParts[1], typeof(NmeaParser.Nmea.Gps.Gpgsv));
Assert.IsInstanceOfType(e.MessageParts[2], typeof(NmeaParser.Nmea.Glonass.Glgsv));
Assert.IsInstanceOfType(e.MessageParts[3], typeof(NmeaParser.Nmea.Galileo.Gagsv));
Assert.IsInstanceOfType(e.MessageParts[0], typeof(NmeaParser.Nmea.Gsv));
Assert.IsInstanceOfType(e.MessageParts[1], typeof(NmeaParser.Nmea.Gsv));
Assert.IsInstanceOfType(e.MessageParts[2], typeof(NmeaParser.Nmea.Gsv));
Assert.IsInstanceOfType(e.MessageParts[3], typeof(NmeaParser.Nmea.Gsv));
Assert.AreEqual(Talker.GlobalPositioningSystem, e.MessageParts[0].TalkerId);
Assert.AreEqual(Talker.GlobalPositioningSystem, e.MessageParts[1].TalkerId);
Assert.AreEqual(Talker.GlonassReceiver, e.MessageParts[2].TalkerId);
Assert.AreEqual(Talker.GalileoPositioningSystem, e.MessageParts[3].TalkerId);
tcs.SetResult(true);
}
else
@ -106,8 +112,8 @@ $GAGSV,4,4,14,19,82,349,40,1,44,220,40,4,24,314,38*5F";
try
{
Assert.IsTrue(e.IsMultipart, "IsMultiPart");
Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gps.Gpgsv));
var msg = e.Message as NmeaParser.Nmea.Gps.Gpgsv;
Assert.IsInstanceOfType(e.Message, typeof(NmeaParser.Nmea.Gsv));
var msg = e.Message as NmeaParser.Nmea.Gsv;
Assert.IsNull(e.MessageParts);
if (count > 6)
tcs.SetResult(true);

View file

@ -22,8 +22,6 @@ using NmeaParser.Nmea;
using NmeaParser.Nmea.Gps;
using System.Threading.Tasks;
using System.IO;
using NmeaParser.Nmea.Gnss;
using NmeaParser.Nmea.Glonass;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace NmeaParser.Tests
@ -91,8 +89,8 @@ namespace NmeaParser.Tests
{
string input = "$GPRMB,A,,,,,,,,,,,,A,A*0B";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gprmb));
Gprmb rmb = (Gprmb)msg;
Assert.IsInstanceOfType(msg, typeof(Rmb));
Rmb rmb = (Rmb)msg;
Assert.AreEqual(true, rmb.Arrived);
Assert.AreEqual(double.NaN, rmb.CrossTrackError);
Assert.AreEqual(double.NaN, rmb.DestinationLatitude);
@ -100,7 +98,7 @@ namespace NmeaParser.Tests
Assert.AreEqual(0, rmb.DestinationWaypointId);
Assert.AreEqual(0, rmb.OriginWaypointId);
Assert.AreEqual(double.NaN, rmb.RangeToDestination);
Assert.AreEqual(Gprmb.DataStatus.Ok, rmb.Status);
Assert.AreEqual(Rmb.DataStatus.Ok, rmb.Status);
Assert.AreEqual(double.NaN, rmb.TrueBearing);
Assert.AreEqual(double.NaN, rmb.Velocity);
}
@ -110,9 +108,9 @@ namespace NmeaParser.Tests
{
string input = "$GPRMB,A,0.66,L,003,004,4917.24,S,12309.57,W,001.3,052.5,000.5,V*3D";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gprmb));
Gprmb rmb = (Gprmb)msg;
Assert.AreEqual(Gprmb.DataStatus.Ok, rmb.Status);
Assert.IsInstanceOfType(msg, typeof(Rmb));
Rmb rmb = (Rmb)msg;
Assert.AreEqual(Rmb.DataStatus.Ok, rmb.Status);
Assert.AreEqual(-.66, rmb.CrossTrackError);
Assert.AreEqual(3, rmb.OriginWaypointId);
Assert.AreEqual(4, rmb.DestinationWaypointId);
@ -129,8 +127,8 @@ namespace NmeaParser.Tests
{
string input = "$GPRMC,123519,A,4807.038,S,01131.000,W,022.4,084.4,230313,003.1,W*6A";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gprmc));
Gprmc rmc = (Gprmc)msg;
Assert.IsInstanceOfType(msg, typeof(Rmc));
Rmc rmc = (Rmc)msg;
Assert.AreEqual(new DateTime(2013, 03, 23, 12, 35, 19, DateTimeKind.Utc), rmc.FixTime);
Assert.AreEqual(-48.1173, rmc.Latitude);
Assert.AreEqual(-11.516666666666667, rmc.Longitude, 0.0000000001);
@ -141,8 +139,8 @@ namespace NmeaParser.Tests
{
string input = "$GNRMC,231011.00,A,3403.47163804,N,11711.80926595,W,0.019,11.218,201217,12.0187,E,D*01";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gnrmc));
Gnrmc rmc = (Gnrmc)msg;
Assert.IsInstanceOfType(msg, typeof(Rmc));
Rmc rmc = (Rmc)msg;
Assert.AreEqual("GNRMC", rmc.MessageType);
Assert.AreEqual(new DateTime(2017, 12, 20, 23, 10, 11, DateTimeKind.Utc), rmc.FixTime);
Assert.AreEqual(34.057860634, rmc.Latitude, 0.0000000001);
@ -158,12 +156,12 @@ namespace NmeaParser.Tests
{
string input = "$GPGGA,235236,3925.9479,N,11945.9211,W,1,10,0.8,1378.0,M,-22.1,M,,*46";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgga));
Gpgga gga = (Gpgga)msg;
Assert.IsInstanceOfType(msg, typeof(Gga));
Gga gga = (Gga)msg;
Assert.AreEqual(new TimeSpan(23, 52, 36), gga.FixTime);
Assert.AreEqual(39.432465, gga.Latitude);
Assert.AreEqual(-119.7653516666666667, gga.Longitude, 0.0000000001);
Assert.AreEqual(NmeaParser.Nmea.Gps.Gpgga.FixQuality.GpsFix, gga.Quality);
Assert.AreEqual(NmeaParser.Nmea.Gga.FixQuality.GpsFix, gga.Quality);
Assert.AreEqual(10, gga.NumberOfSatellites);
Assert.AreEqual(.8, gga.Hdop);
Assert.AreEqual(1378, gga.Altitude);
@ -179,12 +177,12 @@ namespace NmeaParser.Tests
{
string input = "$GNGGA,231011.00,3403.47163804,N,11711.80926595,W,5,13,0.9,403.641,M,-32.133,M,1.0,0000*6D";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gngga));
Gngga gga = (Gngga)msg;
Assert.IsInstanceOfType(msg, typeof(Gga));
Gga gga = (Gga)msg;
Assert.AreEqual(new TimeSpan(23, 10, 11), gga.FixTime);
Assert.AreEqual(34.057860634, gga.Latitude);
Assert.AreEqual(-117.19682109916667, gga.Longitude, 0.0000000001);
Assert.AreEqual(NmeaParser.Nmea.Gps.Gpgga.FixQuality.FloatRtk, gga.Quality);
Assert.AreEqual(NmeaParser.Nmea.Gga.FixQuality.FloatRtk, gga.Quality);
Assert.AreEqual(13, gga.NumberOfSatellites);
Assert.AreEqual(.9, gga.Hdop);
Assert.AreEqual(403.641, gga.Altitude);
@ -201,6 +199,7 @@ namespace NmeaParser.Tests
string input = "$PTNLA,HV,002.94,M,288.1,D,008.6,D,002.98,M*74";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(NmeaParser.Nmea.LaserRange.Trimble.Ptnla));
Assert.AreEqual(Talker.ProprietaryCode, msg.TalkerId);
NmeaParser.Nmea.LaserRange.Trimble.Ptnla ptlna = (NmeaParser.Nmea.LaserRange.Trimble.Ptnla)msg;
Assert.AreEqual(2.94, ptlna.HorizontalDistance);
Assert.AreEqual('M', ptlna.HorizontalDistanceUnits);
@ -217,8 +216,9 @@ namespace NmeaParser.Tests
{
string input = "$PGRME,2.3,M,3.3,M,4.0,M*2B";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(NmeaParser.Nmea.Gps.Garmin.Pgrme));
NmeaParser.Nmea.Gps.Garmin.Pgrme rme = (NmeaParser.Nmea.Gps.Garmin.Pgrme)msg;
Assert.IsInstanceOfType(msg, typeof(NmeaParser.Nmea.Garmin.Pgrme));
Assert.AreEqual(Talker.ProprietaryCode, msg.TalkerId);
NmeaParser.Nmea.Garmin.Pgrme rme = (NmeaParser.Nmea.Garmin.Pgrme)msg;
Assert.AreEqual(2.3, rme.HorizontalError);
Assert.AreEqual("M", rme.HorizontalErrorUnits);
Assert.AreEqual(3.3, rme.VerticalError);
@ -232,10 +232,10 @@ namespace NmeaParser.Tests
{
string input = "$GPGSA,A,3,,,,,,16,18,,22,24,,,,,*14";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgsa));
Gpgsa gsa = (Gpgsa)msg;
Assert.AreEqual(Gpgsa.ModeSelection.Auto, gsa.GpsMode);
Assert.AreEqual(Gpgsa.Mode.Fix3D, gsa.FixMode);
Assert.IsInstanceOfType(msg, typeof(Gsa));
Gsa gsa = (Gsa)msg;
Assert.AreEqual(Gsa.ModeSelection.Auto, gsa.GpsMode);
Assert.AreEqual(Gsa.Mode.Fix3D, gsa.FixMode);
Assert.AreEqual(4, gsa.SVs.Count);
Assert.AreEqual(16, gsa.SVs[0]);
Assert.AreEqual(18, gsa.SVs[1]);
@ -251,10 +251,10 @@ namespace NmeaParser.Tests
{
string input = "$GPGSA,M,2,19,28,14,18,27,22,31,39,40,42,43,44,1.7,1.0,1.3*3C";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgsa));
Gpgsa gsa = (Gpgsa)msg;
Assert.AreEqual(Gpgsa.ModeSelection.Manual, gsa.GpsMode);
Assert.AreEqual(Gpgsa.Mode.Fix2D, gsa.FixMode);
Assert.IsInstanceOfType(msg, typeof(Gsa));
Gsa gsa = (Gsa)msg;
Assert.AreEqual(Gsa.ModeSelection.Manual, gsa.GpsMode);
Assert.AreEqual(Gsa.Mode.Fix2D, gsa.FixMode);
Assert.AreEqual(12, gsa.SVs.Count);
Assert.AreEqual(19, gsa.SVs[0]);
Assert.AreEqual(28, gsa.SVs[1]);
@ -278,10 +278,11 @@ namespace NmeaParser.Tests
{
string input = "$GNGSA,A,3,3,7,16,23,9,26,,,,,,,3.5,1.4,3.2*11";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gngsa));
Gngsa gsa = (Gngsa)msg;
Assert.AreEqual(Gpgsa.ModeSelection.Auto, gsa.GpsMode);
Assert.AreEqual(Gpgsa.Mode.Fix3D, gsa.FixMode);
Assert.IsInstanceOfType(msg, typeof(Gsa));
Assert.AreEqual("GNGSA", msg.MessageType);
Gsa gsa = (Gsa)msg;
Assert.AreEqual(Gsa.ModeSelection.Auto, gsa.GpsMode);
Assert.AreEqual(Gsa.Mode.Fix3D, gsa.FixMode);
Assert.AreEqual(6, gsa.SVs.Count);
Assert.AreEqual(3, gsa.SVs[0]);
Assert.AreEqual(7, gsa.SVs[1]);
@ -299,8 +300,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGSV,3,3,11,22,42,067,42,75,14,311,43,50,05,244,00,,,,*49";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgsv));
Gpgsv gsv = (Gpgsv)msg;
Assert.IsInstanceOfType(msg, typeof(Gsv));
Gsv gsv = (Gsv)msg;
Assert.AreEqual(3, gsv.TotalMessages);
Assert.AreEqual(3, gsv.MessageNumber);
Assert.AreEqual(11, gsv.SVsInView);
@ -333,8 +334,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGSV,1,1,0,,,,,,,,,,,,,,,,*49";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgsv));
Gpgsv gsv = (Gpgsv)msg;
Assert.IsInstanceOfType(msg, typeof(Gsv));
Gsv gsv = (Gsv)msg;
Assert.AreEqual(1, gsv.TotalMessages);
Assert.AreEqual(1, gsv.MessageNumber);
Assert.AreEqual(0, gsv.SVsInView);
@ -347,8 +348,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGLL,4916.45,N,12311.12,W,225444.12,A,*30";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgll));
Gpgll gll = (Gpgll)msg;
Assert.IsInstanceOfType(msg, typeof(Gll));
Gll gll = (Gll)msg;
Assert.IsTrue(gll.DataActive);
Assert.AreEqual(49.2741666666666666667, gll.Latitude);
Assert.AreEqual(-123.18533333333333333, gll.Longitude);
@ -360,8 +361,8 @@ namespace NmeaParser.Tests
{
string input = "$GNGLL,3403.47121040,N,11711.80878910,W,235715.00,A,D*66";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gngll));
Gngll gll = (Gngll)msg;
Assert.IsInstanceOfType(msg, typeof(Gll));
Gll gll = (Gll)msg;
Assert.IsTrue(gll.DataActive);
Assert.AreEqual(34.0578535066667, gll.Latitude, .000000000001);
Assert.AreEqual(-117.196813151667, gll.Longitude, .000000000001);
@ -375,8 +376,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGNS,224749.00,3333.4268304,N,11153.3538273,W,D,19,0.6,406.110,-26.294,6.0,0138,S*6A";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgns));
Gpgns gns = (Gpgns)msg;
Assert.IsInstanceOfType(msg, typeof(Gns));
Gns gns = (Gns)msg;
Assert.AreEqual(new TimeSpan(0, 22, 47, 49, 0), gns.FixTime);
Assert.AreEqual(33.55711384, gns.Latitude, .000000000001);
Assert.AreEqual(-111.889230455, gns.Longitude, .000000000001);
@ -397,8 +398,9 @@ namespace NmeaParser.Tests
{
string input = "$GPGNS,235720.00,,,,,,6,,,,2.0,0*48";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgns));
Gpgns gns = (Gpgns)msg;
Assert.IsInstanceOfType(msg, typeof(Gns));
Gns gns = (Gns)msg;
Assert.AreEqual(Talker.GlobalPositioningSystem, gns.TalkerId);
Assert.AreEqual(new TimeSpan(0, 23, 57, 20, 0), gns.FixTime);
Assert.AreEqual(double.NaN, gns.Latitude);
Assert.AreEqual(double.NaN, gns.Longitude);
@ -418,8 +420,9 @@ namespace NmeaParser.Tests
{
string input = "$GNGNS,235719.00,3403.47068778,N,11711.80950154,W,DDNNN,10,1.4,402.411,-32.133,,*26";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gngns));
Gngns gns = (Gngns)msg;
Assert.IsInstanceOfType(msg, typeof(Gns));
Gns gns = (Gns)msg;
Assert.AreEqual(Talker.GlobalNavigationSatelliteSystem, gns.TalkerId);
Assert.AreEqual(new TimeSpan(0, 23, 57, 19, 0), gns.FixTime);
Assert.AreEqual(34.0578447963333, gns.Latitude, .000000000001);
Assert.AreEqual(-117.196825025667, gns.Longitude, .00000000001);
@ -443,9 +446,10 @@ namespace NmeaParser.Tests
{
string input = "$GLGNS,235720.00,,,,,,4,,,,2.0,0*56";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Glgns));
Glgns gns = (Glgns)msg;
Assert.IsInstanceOfType(msg, typeof(Gns));
Gns gns = (Gns)msg;
Assert.AreEqual(new TimeSpan(0, 23, 57, 20, 0), gns.FixTime);
Assert.AreEqual(Talker.GlonassReceiver, gns.TalkerId);
Assert.AreEqual(double.NaN, gns.Latitude);
Assert.AreEqual(double.NaN, gns.Longitude);
Assert.AreEqual(Gns.Mode.NoFix, gns.GpsModeIndicator);
@ -463,8 +467,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGLL,3751.65,S,14507.36,E*77";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgll));
Gpgll gll = (Gpgll)msg;
Assert.IsInstanceOfType(msg, typeof(Gll));
Gll gll = (Gll)msg;
Assert.IsTrue(gll.DataActive);
Assert.AreEqual(-37.860833333333333333, gll.Latitude);
Assert.AreEqual(145.1226666666666666667, gll.Longitude);
@ -477,8 +481,8 @@ namespace NmeaParser.Tests
{
string input = "$GPBOD,,T,,M,,*47";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpbod));
Gpbod bod = (Gpbod)msg;
Assert.IsInstanceOfType(msg, typeof(Bod));
Bod bod = (Bod)msg;
Assert.AreEqual(double.NaN, bod.TrueBearing, "TrueBearing");
Assert.AreEqual(double.NaN, bod.MagneticBearing, "MagneticBearing");
Assert.IsNull(bod.OriginId, "OriginID");
@ -490,8 +494,8 @@ namespace NmeaParser.Tests
{
string input = "$GPBOD,099.3,T,105.6,M,POINTB,*48";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpbod));
Gpbod bod = (Gpbod)msg;
Assert.IsInstanceOfType(msg, typeof(Bod));
Bod bod = (Bod)msg;
Assert.AreEqual(99.3, bod.TrueBearing, "TrueBearing");
Assert.AreEqual(105.6, bod.MagneticBearing, "MagneticBearing");
Assert.AreEqual("POINTB", bod.DestinationId, "DestinationID");
@ -504,8 +508,8 @@ namespace NmeaParser.Tests
{
string input = "$GPBOD,097.0,T,103.2,M,POINTB,POINTA*4A";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpbod));
Gpbod bod = (Gpbod)msg;
Assert.IsInstanceOfType(msg, typeof(Bod));
Bod bod = (Bod)msg;
Assert.AreEqual(97d, bod.TrueBearing, "TrueBearing");
Assert.AreEqual(103.2, bod.MagneticBearing, "MagneticBearing");
Assert.AreEqual("POINTB", bod.DestinationId, "DestinationID");
@ -542,11 +546,11 @@ namespace NmeaParser.Tests
{
string input = "$GPRTE,2,1,c,0,W3IWI,DRIVWY,32CEDR,32-29,32BKLD,32-I95,32-US1,BW-32,BW-198*69";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gprte));
Gprte gsv = (Gprte)msg;
Assert.IsInstanceOfType(msg, typeof(Rte));
Rte gsv = (Rte)msg;
Assert.AreEqual(2, gsv.TotalMessages);
Assert.AreEqual(1, gsv.MessageNumber);
Assert.AreEqual(NmeaParser.Nmea.Gps.Gprte.WaypointListType.CompleteWaypointsList, gsv.ListType);
Assert.AreEqual(Rte.WaypointListType.CompleteWaypointsList, gsv.ListType);
Assert.AreEqual("0", gsv.RouteId);
Assert.AreEqual("0", gsv.RouteId);
Assert.AreEqual(9, gsv.Waypoints.Count);
@ -560,8 +564,8 @@ namespace NmeaParser.Tests
{
string input = "$GPGST,172814.0,0.006,0.023,0.020,273.6,0.023,0.020,0.031*6A";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpgst));
Gpgst gst = (Gpgst)msg;
Assert.IsInstanceOfType(msg, typeof(Gst));
Gst gst = (Gst)msg;
Assert.AreEqual(new TimeSpan(17, 28, 14), gst.FixTime);
Assert.AreEqual(0.006, gst.Rms);
Assert.AreEqual(0.023, gst.SemiMajorError);
@ -577,8 +581,8 @@ namespace NmeaParser.Tests
{
string input = "$GNGST,172814.0,0.006,0.023,0.020,273.6,0.023,0.020,0.031*74";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gngst));
Gngst gst = (Gngst)msg;
Assert.IsInstanceOfType(msg, typeof(Gst));
Gst gst = (Gst)msg;
Assert.AreEqual(new TimeSpan(17, 28, 14), gst.FixTime);
Assert.AreEqual(0.006, gst.Rms);
Assert.AreEqual(0.023, gst.SemiMajorError);
@ -594,8 +598,8 @@ namespace NmeaParser.Tests
{
string input = "$GPVTG,103.85,T,92.79,M,0.14,N,0.25,K,D*1E";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpvtg));
Gpvtg vtg = (Gpvtg)msg;
Assert.IsInstanceOfType(msg, typeof(Vtg));
Vtg vtg = (Vtg)msg;
Assert.AreEqual(103.85, vtg.TrueCourseOverGround);
Assert.AreEqual(92.79, vtg.MagneticCourseOverGround);
Assert.AreEqual(0.14, vtg.SpeedInKnots);
@ -607,8 +611,8 @@ namespace NmeaParser.Tests
{
string input = "$GPVTG,,T,,M,0.00,N,0.00,K*4E";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpvtg));
Gpvtg vtg = (Gpvtg)msg;
Assert.IsInstanceOfType(msg, typeof(Vtg));
Vtg vtg = (Vtg)msg;
Assert.IsTrue(double.IsNaN(vtg.TrueCourseOverGround));
Assert.IsTrue(double.IsNaN(vtg.MagneticCourseOverGround));
Assert.AreEqual(0.0, vtg.SpeedInKnots);
@ -620,8 +624,8 @@ namespace NmeaParser.Tests
{
var input = "$GNZDA,075451.00,02,10,2018,00,00*72";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gnzda));
var zda = (Gnzda)msg;
Assert.IsInstanceOfType(msg, typeof(Zda));
var zda = (Zda)msg;
Assert.AreEqual(new DateTime(2018, 10, 02, 07, 54, 51, 00, DateTimeKind.Utc), zda.FixDateTime);
}
@ -630,8 +634,8 @@ namespace NmeaParser.Tests
{
var input = "$GPZDA,143042.00,25,08,2005,,*6E";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Gpzda));
var zda = (Gpzda)msg;
Assert.IsInstanceOfType(msg, typeof(Zda));
var zda = (Zda)msg;
Assert.AreEqual(new DateTime(2005, 08, 25, 14, 30, 42, 00, DateTimeKind.Utc), zda.FixDateTime);
}
@ -640,8 +644,8 @@ namespace NmeaParser.Tests
{
var input = "$GLZDA,225627.00,21,09,2015,00,00*70";
var msg = NmeaMessage.Parse(input);
Assert.IsInstanceOfType(msg, typeof(Glzda));
var zda = (Glzda)msg;
Assert.IsInstanceOfType(msg, typeof(Zda));
var zda = (Zda)msg;
Assert.AreEqual(new DateTime(2015, 09, 21, 22, 56, 27, 00, DateTimeKind.Utc), zda.FixDateTime);
}
}