示例#1
0
文件: RoutePart.cs 项目: dotnet/iot
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public RoutePart(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            RouteName = string.Empty;
            int?numberOfSequences = ReadInt(field);
            int?numberOfSequence  = ReadInt(field);

            string sentenceMode = ReadString(field);
            string routeName    = ReadString(field);

            // SentenceMode "w" not yet supported
            if (numberOfSequences.HasValue && numberOfSequence.HasValue && sentenceMode == "c")
            {
                Valid          = true;
                RouteName      = routeName;
                TotalSequences = numberOfSequences.Value;
                Sequence       = numberOfSequence.Value;
                WaypointNames  = new List <string>();
                while (field.MoveNext())
                {
                    WaypointNames.Add(field.Current);
                }
            }
            else
            {
                // Empty list
                WaypointNames  = new List <string>();
                TotalSequences = 1;
                Sequence       = 1;
            }
        }
示例#2
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public CrossTrackError(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            string status1   = ReadString(field);
            string status2   = ReadString(field);
            double?distance  = ReadValue(field);
            string direction = ReadString(field);
            string unit      = ReadString(field);

            if (status1 == "A" && status2 == "A" && distance.HasValue && (direction == "L" || direction == "R") && unit == "N")
            {
                Distance = Length.FromNauticalMiles(distance.Value);
                if (direction == "R")
                {
                    Distance = Distance * -1;
                }

                Valid = true;
            }
            else
            {
                Distance = Length.Zero;
                Valid    = false;
            }
        }
示例#3
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public Waypoint(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            Position = new GeographicPosition();
            Name     = string.Empty;
            double?           wayPointLatitude   = ReadValue(field);
            CardinalDirection?wayPointHemisphere = (CardinalDirection?)ReadChar(field);
            double?           wayPointLongitude  = ReadValue(field);
            CardinalDirection?wayPointDirection  = (CardinalDirection?)ReadChar(field);

            string waypointName = ReadString(field);

            if (wayPointLatitude.HasValue && wayPointLongitude.HasValue)
            {
                double?latitude  = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(wayPointLatitude, wayPointHemisphere);
                double?longitude = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(wayPointLongitude, wayPointDirection);
                if (latitude.HasValue && longitude.HasValue)
                {
                    Position = new GeographicPosition(latitude.Value, longitude.Value, 0);
                    Valid    = true;
                }

                Name = waypointName;
            }
        }
示例#4
0
        /// <summary>
        /// Creates a VTG sentence from decoded fields
        /// </summary>
        /// <param name="talkerId">Talker Id</param>
        /// <param name="fields">List of fields</param>
        /// <param name="time">Time this message was valid</param>
        public TrackMadeGood(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?courseOverGroundTrue = ReadValue(field);
            string reference            = ReadString(field) ?? string.Empty;

            double?courseOverGroundMagnetic = ReadValue(field);
            string reference2 = ReadString(field) ?? string.Empty;

            double?speedKnots = ReadValue(field);
            string reference3 = ReadString(field) ?? string.Empty;

            // The HDT sentence must have a "T" (True) reference, otherwise something is fishy
            if (reference == "T" && courseOverGroundTrue.HasValue)
            {
                CourseOverGroundTrue = Angle.FromDegrees(courseOverGroundTrue.Value);
            }

            if (reference2 == "M" && courseOverGroundMagnetic.HasValue)
            {
                CourseOverGroundMagnetic = Angle.FromDegrees(courseOverGroundMagnetic.Value);
            }

            if (reference3 == "N" && speedKnots.HasValue)
            {
                Speed = Speed.FromKnots(speedKnots.Value);
            }

            // At least these should be set
            Valid = courseOverGroundTrue.HasValue && speedKnots.HasValue;
        }
示例#5
0
    internal Talker(TalkerId talkerId)
    {
        switch (talkerId)
        {
        case TalkerId.AB: Value = Talkers.BaseAIS; break;

        case TalkerId.AD: Value = Talkers.DependentAISBase; break;

        case TalkerId.AI: Value = Talkers.MobileAIS; break;

        case TalkerId.AN: Value = Talkers.AidToNavigation; break;

        case TalkerId.AR: Value = Talkers.Receiving; break;

        case TalkerId.AS: Value = Talkers.LimitedBase; break;

        case TalkerId.AT: Value = Talkers.Transmitting; break;

        case TalkerId.AX: Value = Talkers.Repeater; break;

        case TalkerId.BS: Value = Talkers.Deprecated; break;

        case TalkerId.SA: Value = Talkers.PhysicalStore; break;

        default: Value = Talkers.Undefined; break;
        }
    }
示例#6
0
        /// <summary>
        /// Decode a message
        /// </summary>
        public WindDirectionWithRespectToNorth(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?windDirectionTrue        = ReadValue(field);
            string referenceT               = ReadString(field) ?? string.Empty;
            double?windDirectionMagnetic    = ReadValue(field);
            string referenceM               = ReadString(field) ?? string.Empty;
            double?windSpeedKnots           = ReadValue(field);
            string referenceN               = ReadString(field) ?? string.Empty;
            double?windSpeedMetersPerSecond = ReadValue(field);
            string referenceMeters          = ReadString(field) ?? string.Empty;

            if (windDirectionTrue.HasValue && referenceT == "T")
            {
                TrueWindDirection = Angle.FromDegrees(windDirectionTrue.Value);
            }

            if (windDirectionMagnetic.HasValue && referenceM == "M")
            {
                MagneticWindDirection = Angle.FromDegrees(windDirectionMagnetic.Value);
            }

            if (windSpeedKnots.HasValue && referenceN == "N")
            {
                WindSpeed = Speed.FromKnots(windSpeedKnots.Value);
            }
            else if (windSpeedMetersPerSecond.HasValue && referenceMeters == "M")
            {
                WindSpeed = Speed.FromMetersPerSecond(windSpeedMetersPerSecond.Value);
            }

            Valid = true;
        }
示例#7
0
        /// <summary>
        /// Internal constructor from NMEA string
        /// </summary>
        public EngineRevolutions(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            string source   = ReadString(field);
            int?   engineNo = ReadInt(field);
            double?rpm      = ReadValue(field);
            double?pitch    = ReadValue(field);
            string status   = ReadString(field);

            if (source == "S")
            {
                RotationSource = RotationSource.Shaft;
            }
            else if (source == "E")
            {
                RotationSource = RotationSource.Engine;
            }
            else
            {
                RotationSource = RotationSource.Unknown;
            }

            if (engineNo.HasValue)
            {
                EngineNumber = engineNo.Value;
            }
            else
            {
                EngineNumber = 1;
            }

            if (rpm.HasValue)
            {
                RotationalSpeed = RotationalSpeed.FromRevolutionsPerMinute(rpm.Value);
            }
            else
            {
                RotationalSpeed = RotationalSpeed.Zero;
            }

            if (pitch.HasValue)
            {
                PropellerPitch = Ratio.FromPercent(pitch.Value);
            }

            if (rpm.HasValue && status == "A")
            {
                Valid = true;
            }
            else
            {
                Valid = false;
            }
        }
示例#8
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public WindSpeedAndAngle(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?angle     = ReadValue(field);
            string reference = ReadString(field) ?? string.Empty;
            double?speed     = ReadValue(field);

            string unit   = ReadString(field) ?? string.Empty;
            string status = ReadString(field) ?? string.Empty;

            if (status == "A" && angle.HasValue && speed.HasValue)
            {
                Angle = Angle.FromDegrees(angle.Value);
                if (unit == "N")
                {
                    Speed     = Speed.FromKnots(speed.Value);
                    SpeedUnit = unit;
                }
                else if (unit == "M")
                {
                    Speed     = Speed.FromMetersPerSecond(speed.Value);
                    SpeedUnit = unit;
                }
                else
                {
                    Speed     = Speed.FromMetersPerSecond(0);
                    SpeedUnit = "M";
                }

                if (reference == "T")
                {
                    Relative = false;
                    Angle    = Angle.Normalize(true);
                }
                else
                {
                    // Default, since that's what the actual wind instrument delivers
                    Relative = true;
                    // Relative angles are +/- 180
                    Angle = Angle.Normalize(false);
                }

                Valid = true;
            }
            else
            {
                Angle     = Angle.Zero;
                Speed     = Speed.Zero;
                SpeedUnit = string.Empty;
                Valid     = false;
            }
        }
示例#9
0
        /// <summary>
        /// Internal ctor
        /// </summary>
        public BearingAndDistanceToWayPoint(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            string         timeString = ReadString(field);
            DateTimeOffset now        = ParseDateTime(time, timeString);

            DateTime = now;

            NextWayPointName = string.Empty;
            NextWayPoint     = new GeographicPosition();

            double?           nextWayPointLatitude      = ReadValue(field);
            CardinalDirection?nextWayPointHemisphere    = (CardinalDirection?)ReadChar(field);
            double?           nextWayPointLongitude     = ReadValue(field);
            CardinalDirection?nextWayPointDirection     = (CardinalDirection?)ReadChar(field);
            double?           bearingTrue               = ReadValue(field);
            string            bearingTrueIdentifier     = ReadString(field);
            double?           bearingMagnetic           = ReadValue(field);
            string            bearingMagneticIdentifier = ReadString(field);
            double?           distance     = ReadValue(field);
            string            nm           = ReadString(field);
            string            wayPointName = ReadString(field);

            if (nextWayPointLongitude.HasValue && nextWayPointLatitude.HasValue)
            {
                Valid = true;
                double?latitude  = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(nextWayPointLatitude, nextWayPointHemisphere);
                double?longitude = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(nextWayPointLongitude, nextWayPointDirection);

                if (latitude.HasValue && longitude.HasValue)
                {
                    NextWayPoint = new GeographicPosition(latitude.Value, longitude.Value, 0);
                }

                NextWayPointName = wayPointName;

                if (bearingTrue.HasValue && bearingTrueIdentifier == "T")
                {
                    BearingTrueToWayPoint = Angle.FromDegrees(bearingTrue.Value);
                }

                if (bearingMagnetic.HasValue && bearingMagneticIdentifier == "M")
                {
                    BearingMagneticToWayPoint = Angle.FromDegrees(bearingMagnetic.Value);
                }

                if (distance.HasValue && nm == "N")
                {
                    DistanceToWayPoint = Length.FromNauticalMiles(distance.Value);
                }
            }
        }
示例#10
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public TimeDate(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            string   timeString     = ReadString(field);
            TimeSpan?localTimeOfDay = null;

            if (!string.IsNullOrWhiteSpace(timeString))
            {
                // Can't use the base class methods here, because we just shouldn't rely on the input variable "today" here, as this message defines the date
                int    hour    = int.Parse(timeString.Substring(0, 2), CultureInfo.InvariantCulture);
                int    minute  = int.Parse(timeString.Substring(2, 2), CultureInfo.InvariantCulture);
                int    seconds = int.Parse(timeString.Substring(4, 2), CultureInfo.InvariantCulture);
                double millis  = double.Parse("0" + timeString.Substring(6), CultureInfo.InvariantCulture) * 1000;
                localTimeOfDay = new TimeSpan(0, hour, minute, seconds, (int)millis);
            }

            double year  = ReadValue(field) ?? time.Year;
            double month = ReadValue(field) ?? time.Month;
            double day   = ReadValue(field) ?? time.Day;
            // Offset hours and minutes (last two fields, optional and usually 0). Some sources say these fields are first, but that's apparently wrong
            double offset = ReadValue(field) ?? 0.0;

            offset += (ReadValue(field) ?? 0.0) / 60;

            // Some sources say the parameter order is day-month-year, some say it shall be year-month-day. Luckily, the cases are easy to distinguish,
            // since the year is always given as 4-digit number
            if (day > 2000)
            {
                double ytemp = day;
                day  = year;
                year = ytemp;
                ReverseDateFormat = true; // If the input format is exchanged, we by default send the message out the same way
            }

            // These may be undefined or zero if the GPS receiver is not receiving valid satellite data (i.e. the receiver works, but there's no antenna connected)
            if (localTimeOfDay.HasValue)
            {
                DateTimeOffset t = new DateTimeOffset((int)year, (int)month, (int)day, localTimeOfDay.Value.Hours, localTimeOfDay.Value.Minutes, localTimeOfDay.Value.Seconds,
                                                      localTimeOfDay.Value.Milliseconds, gregorianCalendar, TimeSpan.Zero);
                LocalTimeOffset = TimeSpan.FromHours(offset);
                DateTime        = t;
                Valid           = true;
            }
            else
            {
                // Set the reception time anyway, but tell clients that this was not a complete ZDA message
                Valid           = false;
                LocalTimeOffset = TimeSpan.Zero;
                DateTime        = time;
            }
        }
示例#11
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public MeteorologicalComposite(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?baroInchesMercury = ReadValue(field);
            string referenceI        = ReadString(field) ?? string.Empty;
            double?baroBars          = ReadValue(field);
            string referenceB        = ReadString(field) ?? string.Empty;
            double?airTemp           = ReadValue(field);
            string referenceAir      = ReadString(field) ?? string.Empty;
            double?waterTemp         = ReadValue(field);
            string referenceWater    = ReadString(field) ?? string.Empty;
            double?relHumidity       = ReadValue(field);

            ReadValue(field); // Absolute humidity (ignored, since meaning unclear)
            double?dewPoint          = ReadValue(field);
            string referenceDewPoint = ReadString(field) ?? string.Empty;

            if (baroBars.HasValue && referenceB == "B")
            {
                BarometricPressure = Pressure.FromHectopascals(baroBars.Value * 1000);
            }
            else if (baroInchesMercury.HasValue && referenceI == "I")
            {
                BarometricPressure = Pressure.FromInchesOfMercury(baroInchesMercury.Value);
            }

            if (airTemp.HasValue && referenceAir == "C")
            {
                AirTemperature = Temperature.FromDegreesCelsius(airTemp.Value);
            }

            if (waterTemp.HasValue && referenceWater == "C")
            {
                WaterTemperature = Temperature.FromDegreesCelsius(waterTemp.Value);
            }

            if (relHumidity.HasValue)
            {
                RelativeHumidity = UnitsNet.RelativeHumidity.FromPercent(relHumidity.Value);
            }

            if (dewPoint.HasValue && referenceDewPoint == "C")
            {
                DewPoint = Temperature.FromDegreesCelsius(dewPoint.Value);
            }

            // Note: The remaining fields are about wind speed/direction. These are not parsed here, use MWV sentence instead
            Valid = true;
        }
示例#12
0
        /// <summary>
        /// Magnetic heading message
        /// </summary>
        public HeadingAndDeclination(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?heading            = ReadValue(field);
            double?deviation          = ReadValue(field);
            string deviationDirection = ReadString(field);
            double?magVar             = ReadValue(field);
            string magVarDirection    = ReadString(field);
            string reference          = ReadString(field) ?? string.Empty;

            Valid = false;
            if (heading.HasValue)
            {
                HeadingTrue = Angle.FromDegrees(heading.Value);
                // This one needs to be there, the others are optional
                Valid = true;
            }

            if (deviation.HasValue)
            {
                if (deviationDirection == "E")
                {
                    Deviation = Angle.FromDegrees(deviation.Value);
                }
                else
                {
                    Deviation = Angle.FromDegrees(deviation.Value * -1);
                }
            }

            if (magVar.HasValue)
            {
                if (magVarDirection == "E")
                {
                    Declination = Angle.FromDegrees(magVar.Value);
                }
                else
                {
                    Declination = Angle.FromDegrees(magVar.Value * -1);
                }
            }
        }
示例#13
0
        /// <summary>
        /// Magnetic heading message
        /// </summary>
        public HeadingMagnetic(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?angle     = ReadValue(field);
            string reference = ReadString(field) ?? string.Empty;

            // The HDM sentence must have a "M" (Magnetic) reference, otherwise something is fishy
            if (reference == "M" && angle.HasValue)
            {
                Angle = Angle.FromDegrees(angle.Value);
                Valid = true;
            }
            else
            {
                Angle = Angle.Zero;
                Valid = false;
            }
        }
示例#14
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public SatellitesInView(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            Satellites = new List <SatelliteInfo>();

            int?totalSequences  = ReadInt(field);
            int?currentSequence = ReadInt(field);
            int?totalSatellites = ReadInt(field);

            if (!totalSequences.HasValue || !currentSequence.HasValue || !totalSatellites.HasValue)
            {
                TotalSequences = 0;
                Sequence       = 0;
                Valid          = false;
                return;
            }

            TotalSequences  = totalSequences.Value;
            Sequence        = currentSequence.Value;
            TotalSatellites = totalSatellites.Value;

            string id = ReadString(field);

            while (!string.IsNullOrWhiteSpace(id))
            {
                double?       elevation = ReadValue(field);
                double?       azimuth   = ReadValue(field);
                double?       snr       = ReadValue(field);
                SatelliteInfo info      = new SatelliteInfo(id)
                {
                    Azimuth   = azimuth.HasValue ? Angle.FromDegrees(azimuth.Value) : null,
                    Elevation = elevation.HasValue ? Angle.FromDegrees(elevation.Value) : null, Snr = snr
                };
                Satellites.Add(info);
                id = ReadString(field);
            }

            Valid = true;
        }
示例#15
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public DepthBelowSurface(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            string feet       = ReadString(field);
            string feetUnit   = ReadString(field);
            double?meters     = ReadValue(field);
            string metersUnit = ReadString(field);

            if (metersUnit == "M" && meters.HasValue)
            {
                Depth = Length.FromMeters(meters.Value);
                Valid = true;
            }
            else
            {
                Depth = Length.Zero;
                Valid = false;
            }
        }
示例#16
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public WaterSpeedAndAngle(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            double?angleTrue     = ReadValue(field);
            string referenceT    = ReadString(field) ?? string.Empty;
            double?angleMagnetic = ReadValue(field);
            string referenceM    = ReadString(field) ?? string.Empty;
            double?speed         = ReadValue(field);
            string speedUnit     = ReadString(field) ?? string.Empty;

            Valid           = false;
            HeadingTrue     = null;
            HeadingMagnetic = null;
            if (referenceT == "T" && angleTrue.HasValue)
            {
                HeadingTrue = Angle.FromDegrees(angleTrue.Value);
            }

            if (referenceM == "M" && angleMagnetic.HasValue)
            {
                HeadingMagnetic = Angle.FromDegrees(angleMagnetic.Value);
            }

            if (speedUnit == "N" && speed.HasValue)
            {
                Speed = Speed.FromKnots(speed.Value);
            }

            // The other information can be obtained by other messages, the water speed is the only we really need this message
            if (speed.HasValue)
            {
                Valid = true;
            }
        }
示例#17
0
        /// <summary>
        /// Date and time message (ZDA). This should not normally need the last time as argument, because it defines it.
        /// </summary>
        public BearingOriginToDestination(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            OriginName      = string.Empty;
            DestinationName = string.Empty;

            double?bearingTrue       = ReadValue(field);
            string referenceTrue     = ReadString(field);
            double?bearingMagnetic   = ReadValue(field);
            string referenceMagnetic = ReadString(field);
            string waypointToName    = ReadString(field);
            string waypointFromName  = ReadString(field);

            if (bearingTrue.HasValue && bearingMagnetic.HasValue && referenceTrue == "T" && referenceMagnetic == "M")
            {
                BearingTrue     = Angle.FromDegrees(bearingTrue.Value);
                BearingMagnetic = Angle.FromDegrees(bearingMagnetic.Value);
                DestinationName = waypointToName;
                OriginName      = waypointFromName;
                Valid           = true;
            }
        }
示例#18
0
        /// <summary>
        /// See <see cref="NmeaSentence"/> for constructor usage
        /// </summary>
        public RecommendedMinimumNavigationInformation(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            Position = new GeographicPosition();

            string            newTime = ReadString(field);
            NavigationStatus? status  = (NavigationStatus?)ReadChar(field);
            double?           lat     = ReadValue(field);
            CardinalDirection?latTurn = (CardinalDirection?)ReadChar(field);
            double?           lon     = ReadValue(field);
            CardinalDirection?lonTurn = (CardinalDirection?)ReadChar(field);
            double?           speed   = ReadValue(field);
            double?           track   = ReadValue(field);
            string            date    = ReadString(field);

            DateTimeOffset dateTime;

            if (date.Length != 0)
            {
                dateTime = ParseDateTime(date, newTime);
            }
            else
            {
                dateTime = ParseDateTime(time, newTime);
            }

            double?           mag     = ReadValue(field);
            CardinalDirection?magTurn = (CardinalDirection?)ReadChar(field);

            // handle undocumented field
            // per spec we should not have any extra fields but NEO-M8 does have them
            if (field.MoveNext())
            {
                string val = field.Current;
                Status2 = string.IsNullOrEmpty(val) ? (NavigationStatus?)null : (NavigationStatus?)val.FirstOrDefault();
            }

            DateTime = dateTime;
            Status   = status;
            double?latitude  = Nmea0183ToDegrees(lat, latTurn);
            double?longitude = Nmea0183ToDegrees(lon, lonTurn);

            if (latitude.HasValue && longitude.HasValue)
            {
                Position = new GeographicPosition(latitude.Value, longitude.Value, 0);
                // If the message contains no position, it is unusable.
                // On the other hand, if the position is known (meaning the GPS receiver works), speed and track are known, too.
                Valid = true;
            }

            SpeedOverGround = Speed.FromKnots(speed.GetValueOrDefault(0));

            if (track.HasValue)
            {
                TrackMadeGoodInDegreesTrue = Angle.FromDegrees(track.Value);
            }
            else
            {
                TrackMadeGoodInDegreesTrue = Angle.Zero;
            }

            if (mag.HasValue && magTurn.HasValue)
            {
                MagneticVariationInDegrees = Angle.FromDegrees(mag.Value * DirectionToSign(magTurn.Value));
            }
        }
示例#19
0
 public void ThenTheAisTalkerIs(TalkerId talkerId)
 {
     this.Then(parser => Assert.AreEqual(talkerId, parser.AisTalker));
 }
示例#20
0
文件: RawSentence.cs 项目: dotnet/iot
 /// <summary>
 /// Creates an unknown sentence from a split of parameters
 /// </summary>
 public RawSentence(TalkerId talkerId, SentenceId id, IEnumerable <string> fields, DateTimeOffset time)
     : base(talkerId, id, time)
 {
     _fields = fields.ToArray();
     Valid   = true;
 }
示例#21
0
        /// <summary>
        /// See <see cref="NmeaSentence"/> for constructor usage
        /// </summary>
        public RecommendedMinimumNavToDestination(TalkerId talkerId, IEnumerable <string> fields, DateTimeOffset time)
            : base(talkerId, Id, time)
        {
            IEnumerator <string> field = fields.GetEnumerator();

            PreviousWayPointName = string.Empty;
            NextWayPointName     = String.Empty;
            NextWayPoint         = new GeographicPosition();

            string            overallStatus          = ReadString(field);
            double?           crossTrackError        = ReadValue(field);
            string            directionToSteer       = ReadString(field);
            string            previousWayPoint       = ReadString(field);
            string            nextWayPoint           = ReadString(field);
            double?           nextWayPointLatitude   = ReadValue(field);
            CardinalDirection?nextWayPointHemisphere = (CardinalDirection?)ReadChar(field);
            double?           nextWayPointLongitude  = ReadValue(field);
            CardinalDirection?nextWayPointDirection  = (CardinalDirection?)ReadChar(field);
            double?           rangeToWayPoint        = ReadValue(field);
            double?           bearing       = ReadValue(field);
            double?           approachSpeed = ReadValue(field);
            string            arrivalStatus = ReadString(field);

            if (overallStatus == "A")
            {
                Valid = true;
                if (directionToSteer == "R")
                {
                    CrossTrackError = -Length.FromNauticalMiles(crossTrackError.GetValueOrDefault(0));
                }
                else
                {
                    CrossTrackError = Length.FromNauticalMiles(crossTrackError.GetValueOrDefault(0));
                }

                PreviousWayPointName = previousWayPoint ?? string.Empty;
                NextWayPointName     = nextWayPoint ?? string.Empty;
                double?latitude  = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(nextWayPointLatitude, nextWayPointHemisphere);
                double?longitude = RecommendedMinimumNavigationInformation.Nmea0183ToDegrees(nextWayPointLongitude, nextWayPointDirection);

                if (latitude.HasValue && longitude.HasValue)
                {
                    NextWayPoint = new GeographicPosition(latitude.Value, longitude.Value, 0);
                }

                if (rangeToWayPoint.HasValue)
                {
                    DistanceToWayPoint = Length.FromNauticalMiles(rangeToWayPoint.Value);
                }

                if (bearing.HasValue)
                {
                    BearingToWayPoint = Angle.FromDegrees(bearing.Value);
                }

                if (approachSpeed.HasValue)
                {
                    ApproachSpeed = Speed.FromKnots(approachSpeed.Value);
                }

                if (arrivalStatus == "A")
                {
                    Arrived = true;
                }
                else
                {
                    Arrived = false;
                }
            }
        }
示例#22
0
 /// <summary>
 /// Constructs an instance of this abstract class
 /// </summary>
 /// <param name="talker">The talker (sender) of this message</param>
 /// <param name="id">Sentence Id</param>
 /// <param name="time">Date/Time this message was valid (derived from last time message)</param>
 protected NmeaSentence(TalkerId talker, SentenceId id, DateTimeOffset time)
 {
     SentenceId = id;
     TalkerId   = talker;
     DateTime   = time;
 }