public NmeaMessage ParseLine(string line)
        {
            if ((line == null) || (line.Length <= 0))
            {
                return(null);
            }

            NmeaMessage outMessage = null;

            try
            {
                int csIndex = line.LastIndexOf('*');
                if (csIndex <= 0)
                {
                    return(null);
                }

                csIndex++;
                if (csIndex >= line.Length)
                {
                    return(null);
                }

                string   cs       = line.Substring(csIndex, line.Length - csIndex);
                string   tempLine = line.Substring(0, csIndex - 1);
                string[] parts    = tempLine.ToUpper().Split(',');
                if (parts.Length <= 0)
                {
                    return(null);
                }

                if (!ValidateChecksum(tempLine, cs))
                {
                    return(null);
                }

                foreach (NmeaMessage message in _handlers)
                {
                    if (message.IsApplicable(parts))
                    {
                        outMessage = message.CreateEmpty();
                        outMessage.FromNmea(parts);
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                outMessage = new Error(line, ex);
            }

            return(outMessage);
        }
        private bool CanSetPositionFromMessage(NmeaMessage message)
        {
            switch (message.Id)
            {
            case NmeaMessageType.GGA:
                ParseCGA(message);
                break;

            case NmeaMessageType.RMC:
                ParseRMC(message);
                break;
            }

            return(message.Id == CycleStartMsgType);
        }
        private void ParseRMC(NmeaMessage message)
        {
            var    f = (NmeaField)message.Fields[RMC.FieldIds.Status];
            double longitude = 0, latitude = 0;

            if ((f != null) && f.HasValue)
            {
                char status = f.GetChar((char)0);
                if (status != 'A')
                {
                    return;
                }

                f = (NmeaField)message.Fields[RMC.FieldIds.X];
                if ((f != null) && f.HasValue)
                {
                    longitude = f.GetDouble(_position.Coordinate.Longitude);
                }
                f = (NmeaField)message.Fields[RMC.FieldIds.Y];
                if ((f != null) && f.HasValue)
                {
                    latitude = f.GetDouble(_position.Coordinate.Latitude);
                }
                f = (NmeaField)message.Fields[RMC.FieldIds.Utc];
                if ((f != null) && f.HasValue)
                {
                    _position.Time = f.GetTime(_position.Time);
                }
                f = (NmeaField)message.Fields[RMC.FieldIds.Date];
                if ((f != null) && f.HasValue)
                {
                    _position.Date = f.GetDate(_position.Date);
                }
                f = (NmeaField)message.Fields[RMC.FieldIds.Speed];
                if ((f != null) && f.HasValue)
                {
                    _position.Speed = f.GetDouble(_position.Speed);
                }
                f = (NmeaField)message.Fields[RMC.FieldIds.Course];
                if ((f != null) && f.HasValue)
                {
                    _position.Course = f.GetDouble(_position.Course);
                }
            }
            _position.Coordinate = new GeoCoordinate((float)latitude, (float)longitude);
        }
        private void ParseCGA(NmeaMessage message)
        {
            GeoPosition position = new GeoPosition();
            double      longitude = 0, latitude = 0;
            var         f = (NmeaField)message.Fields[GGA.FieldIds.PositionFixIndicator];

            if ((f != null) && f.HasValue)
            {
                position.PositionFixIndicator = f.GetInt(position.PositionFixIndicator);
            }
            f = (NmeaField)message.Fields[GGA.FieldIds.X];
            if ((f != null) && f.HasValue)
            {
                longitude = f.GetDouble(_position.Coordinate.Longitude);
            }
            f = (NmeaField)message.Fields[GGA.FieldIds.Y];
            if ((f != null) && f.HasValue)
            {
                latitude = f.GetDouble(_position.Coordinate.Latitude);
            }
            f = (NmeaField)message.Fields[GGA.FieldIds.Utc];
            if ((f != null) && f.HasValue)
            {
                position.Time = f.GetTime(position.Time);
            }
            f = (NmeaField)message.Fields[GGA.FieldIds.Satelites];
            if ((f != null) && f.HasValue)
            {
                position.Satelites = f.GetInt(position.Satelites);
            }
            f = (NmeaField)message.Fields[GGA.FieldIds.Hdop];
            if ((f != null) && f.HasValue)
            {
                position.Hdop = f.GetInt(position.Hdop);
            }
            _position.Coordinate = new GeoCoordinate((float)latitude, (float)longitude);
        }