程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> .NET Compact Framework下的GPS NMEA data數據分析(下)

.NET Compact Framework下的GPS NMEA data數據分析(下)

編輯:關於.NET

代碼5

從ParseGPGSA看,這個比較特別,他把在使用的衛星信息分開 多條語句output。如下:

$GPGSV,3,1,12,03,43,246,46,06,57,263,52,09,10,090,00,14,2 9,357,41*71
$GPGSV,3,2,12,15,12,140,00,16,10,307,00,18,59,140,00,19,20,224,00*75 $GPGSV,3,3,12,21,48,089,00,22,69,265,36,24,09,076,00,34,00,000,00*76

字段1為一共分開多少條語句。字段2為當前語句的序號。字段3為 在使用的衛星的數量。後面字段分別表示三個不同衛星的信息,取其中一個衛星 來解釋,字段4為衛星的ID,字段5為太空海拔,字段6為角度,字段7為信號強弱 。

對於廠商的私有NMEA data也是同樣的方法進行分析,根據文檔的描述 進行分析。下面為整個類的代碼。

NmeaParser
    public class NmeaParser
    {
        public struct Coordinate
        {
            public int Hours;
            public int Minutes;
            public double Seconds;
        }

        public enum FixStatus
        {
            NotSet,
            Obtained, //A
            Lost //V
        }

        public enum FixMode
        {
            Auto,   //A
            Manual
        }

        public enum FixMethod
        {
            NotSet,
            Fix2D,
            Fix3D
        }

        public enum DifferentialGpsType
        {
            NotSet,
            SPS,
            DSPS,
            PPS,
            RTK
        }

        public class GpsSatellite
        {
            public int PRC { get; set; }
            public int Elevation { get; set; }
            public int Azimuth { get; set; }
            public int SNR { get; set; }
            public bool InUsed { get; set; }
            public bool InView { get; set; }
            public bool NotTracking { get; set; }
        }

        private static readonly CultureInfo NmeaCultureInfo = new CultureInfo("en-US");
        private static readonly decimal KMpHPerKnot = decimal.Parse("1.852", NmeaCultureInfo);

         private Coordinate latitude;
        private Coordinate longitude;
        private decimal altitude = 0;

        private DateTime utcDateTime;
        private decimal velocity = 0;
        private decimal azimuth = 0;

        private FixStatus fixStatus;
        private DifferentialGpsType differentialGpsType;
        private FixMode fixMode;
        private FixMethod fixMethod;

        private int satellitesInView;
        private int satellitesInUsed;
        private readonly Dictionary<int, GpsSatellite> satellites;

        private decimal horizontalDilutionOfPrecision = 50;
        private decimal positionDilutionOfPrecision = 50;
        private decimal verticalDilutionOfPrecision = 50;

        public NmeaParser()
        {
            satellites = new Dictionary<int, GpsSatellite>();
        }

        public bool Parse(string sentence)
        {
            string rawData = sentence;
            try
            {
                if (!IsValid(sentence))
                {
                    return false;
                }

                 sentence = sentence.Substring(1, sentence.IndexOf('*') - 1);
                string[] Words = Getwords(sentence);
                switch (Words[0])
                {
                    case "GPRMC":
                        return ParseGPRMC (Words);
                    case "GPGGA":
                        return ParseGPGGA (Words);
                    case "GPGSA":
                        return ParseGPGSA (Words);
                    case "GPGSV":
                        return ParseGPGSV (Words);
                    default:
                        return false;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message + rawData);
                return false;
            }
        }

        private bool IsValid(string sentence)
        {
            // GPS data can't be zero length
            if (sentence.Length == 0)
            {
                return false;
            }

            // first character must be a $
            if (sentence[0] != '$')
            {
                return false;
            }

            // GPS data can't be longer than 82 character
            if (sentence.Length > 82)
            {
                return false;
            }

            try
            {
                string checksum = sentence.Substring (sentence.IndexOf('*') + 1);
                return Checksum(sentence, checksum);
            }
            catch (Exception e)
            {
                Console.WriteLine("Checksum failure. " + e.Message);
                return false;
            }
        }

        private bool Checksum (string sentence, string checksumStr)
        {
            int checksum = 0;
            int length = sentence.IndexOf('*') - 1;
            // go from first character upto last *
            for (int i = 1; i <= length; ++i)
            {
                checksum = checksum ^ Convert.ToByte (sentence[i]);
            }

            return (checksum.ToString("X2") == checksumStr);
        }

        // Divides a sentence into individual Words
        private static string[] Getwords(string sentence)
        {
            return sentence.Split(',');
        }

        private bool ParseGPRMC (string[] Words)
        {
            if (Words[1].Length > 0 & Words [9].Length > 0)
            {
                int UtcHours = Convert.ToInt32(Words [1].Substring(0, 2));
                int UtcMinutes = Convert.ToInt32(Words [1].Substring(2, 2));
                int UtcSeconds = Convert.ToInt32(Words [1].Substring(4, 2));
                int UtcMilliseconds = 0;

                 // Extract milliseconds if it is available
                if (Words[1].Length > 7)
                {
                    UtcMilliseconds = Convert.ToInt32(Words[1].Substring(7));
                }

                 int UtcDay = Convert.ToInt32(Words[9].Substring(0, 2));
                int UtcMonth = Convert.ToInt32(Words [9].Substring(2, 2));
                // available for this century
                int UtcYear = Convert.ToInt32(Words [9].Substring(4, 2)) + 2000;

                utcDateTime = new DateTime(UtcYear, UtcMonth, UtcDay, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds);
            }

            fixStatus = (Words[2][0] == 'A') ? FixStatus.Obtained : FixStatus.Lost;

            if (Words[3].Length > 0 & Words [4].Length == 1 & Words[5].Length > 0 & Words[6].Length == 1)
            {
                latitude.Hours = int.Parse(Words [3].Substring(0, 2));
                latitude.Minutes = int.Parse(Words [3].Substring(2, 2));
                latitude.Seconds = Math.Round (double.Parse(Words[3].Substring(5, 4)) * 6 / 1000.0, 3);
                if ("S" == Words[4])
                {
                    latitude.Hours = - latitude.Hours;
                }

                 longitude.Hours = int.Parse(Words[5].Substring(0, 3));
                longitude.Minutes = int.Parse(Words [5].Substring(3, 2));
                longitude.Seconds = Math.Round (double.Parse(Words[5].Substring(6, 4)) * 6 / 1000.0, 3);
                if ("W" == Words[6])
                {
                    longitude.Hours = - longitude.Hours;
                }
            }

            if (Words [8].Length > 0)
            {
                azimuth = decimal.Parse(Words[8], NmeaCultureInfo);
            }

            if (Words [7].Length > 0)
            {
                velocity = decimal.Parse(Words[7], NmeaCultureInfo) * KMpHPerKnot;
            }
            return true;
        }

        private bool ParseGPGGA (string[] Words)
        {
            if (Words[6].Length > 0)
            {
                switch (Convert.ToInt32(Words[6]))
                {
                    case 0:
                        differentialGpsType = DifferentialGpsType.NotSet;
                        break;
                    case 1:
                        differentialGpsType = DifferentialGpsType.SPS;
                        break;
                    case 2:
                        differentialGpsType = DifferentialGpsType.DSPS;
                        break;
                    case 3:
                        differentialGpsType = DifferentialGpsType.PPS;
                        break;
                    case 4:
                        differentialGpsType = DifferentialGpsType.RTK;
                        break;
                    default:
                        differentialGpsType = DifferentialGpsType.NotSet;
                        break;
                }
            }

            if (Words [7].Length > 0)
            {
                satellitesInUsed = Convert.ToInt32 (Words[7]);
            }

            if (Words [8].Length > 0)
            {
                horizontalDilutionOfPrecision = Convert.ToDecimal(Words[8]);
            }

            if (Words [9].Length > 0)
            {
                altitude = Convert.ToDecimal(Words [9]);
            }
            return true;
        }

        private bool ParseGPGSA (string[] Words)
        {
            if (Words[1].Length > 0)
            {
                fixMode = Words[1][0] == 'A' ? FixMode.Auto : FixMode.Manual;
            }

            if (Words [2].Length > 0)
            {
                switch (Convert.ToInt32(Words[2]))
                {
                    case 1:
                        fixMethod = FixMethod.NotSet;
                        break;
                    case 2:
                        fixMethod = FixMethod.Fix2D;
                        break;
                    case 3:
                        fixMethod = FixMethod.Fix3D;
                        break;
                    default:
                        fixMethod = FixMethod.NotSet;
                        break;
                }
            }

            foreach (GpsSatellite s in satellites.Values)
            {
                s.InUsed = false;
            }
            satellitesInUsed = 0;
            for (int i = 0; i < 12; ++i)
            {
                string id = Words[3 + i];
                if (id.Length > 0)
                {
                    int nId = Convert.ToInt32 (id);
                    if (!satellites.ContainsKey (nId))
                    {
                        satellites[nId] = new GpsSatellite();
                        satellites[nId].PRC = nId;
                    }
                    satellites[nId].InUsed = true;
                    ++satellitesInUsed;
                }
            }

            if (Words [15].Length > 0)
            {
                positionDilutionOfPrecision = Convert.ToDecimal(Words[15]);
            }

            if (Words [16].Length > 0)
            {
                horizontalDilutionOfPrecision = Convert.ToDecimal(Words[16]);
            }

            if (Words [17].Length > 0)
            {
                verticalDilutionOfPrecision = Convert.ToDecimal(Words[17]);
            }
            return true;
        }

        private bool ParseGPGSV (string[] Words)
        {
            int messageNumber = 0;

             if (Words[2].Length > 0)
            {
                messageNumber = Convert.ToInt32(Words [2]);
            }
            if (Words[3].Length > 0)
            {
                satellitesInView = Convert.ToInt32 (Words[3]);
            }

            if (messageNumber == 0 || satellitesInView == 0)
            {
                return false;
            }

            for (int i = 1; i <= 4; ++i)
            {
                if ((Words.Length - 1) >= (i * 4 + 3))
                {
                    int nId = 0;
                    if (Words[i * 4].Length > 0)
                    {
                        string id = Words[i * 4];
                        nId = Convert.ToInt32 (id);
                        if (! satellites.ContainsKey(nId))
                        {
                            satellites[nId] = new GpsSatellite();
                            satellites [nId].PRC = nId;
                        }
                        satellites[nId].InView = true;
                    }

                     if (Words[i * 4 + 1].Length > 0)
                    {
                        satellites [nId].Elevation = Convert.ToInt32(Words[i * 4 + 1]);
                    }

                     if (Words[i * 4 + 2].Length > 0)
                    {
                        satellites[nId].Azimuth = Convert.ToInt32(Words[i * 4 + 2]);
                    }

                     if (Words[i * 4 + 3].Length > 0)
                    {
                        satellites[nId].SNR = Convert.ToInt32(Words[i * 4 + 3]);
                        satellites [nId].NotTracking = false;
                    }
                    else
                    {
                        satellites [nId].NotTracking = true;
                    }
                }
            }
            return true;
        }
    }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved