Windows Mobile下的GPS开发
2008年07月08日02:15   编辑:cppguy 来源: 博客 浏览: 362 次

  内置GPS: 对于通用的WM设备,我们是通过串口Com9来获得内置GPS的信息的,而一般我们打开的比特率使用的是4800

    gPort.OpenPort(“com9”, 4800)

  打开端口之后,一般我们会启用新线程进行读数据

 

void ReadThreadFun()
        {
            byte[] buf = new byte[512];//端口缓存大小为512
            int readLength = 0;
            while (_isWorking)
            {
                readLength = gPort.ReadPort(buf.Length, buf);
                lastReport += System.Text.Encoding.ASCII.GetString(buf, 0, readLength);
                    try
                    {
                        string[] reports = lastReport.Split(new char[] { '\n' });

                        if ((reports[reports.Length - 1].Length > 0)
 && (reports[reports.Length - 1][reports[reports.Length - 1].Length - 1] != '\r'))
                            lastReport = reports[reports.Length - 1];
                        else
                            lastReport = "";
                        for (int i = 0; i < reports.Length; i++)
                        {

                         if (GetGpsInfo(reports[i]))
                           {
                           //记录GPS的各种信息
                        }
                    }
                    catch (Exception err)
                    {
                    }
                }
            }
        }

根据从端口读出的帧数据,我们需要根据协议NMEA0183来解析出GPS所包含的信息

public bool GetGpsInfo(string scr)
        {
            if (scr.Length < 1)
                return false;
            bool ret = false;

            if (scr.StartsWith("$GPGGA"))
                ret = GetAltitudeFromGGA(scr);
            else if (scr.StartsWith("$GPRMC"))
                ret = GetGpsInfoFromRMC(scr);

            if ((this.latitude <= 90 && this.latitude >= -90) &&
                (this.longitude <= 360 && this.longitude >= -360))
                return ret;
            else
                return false;
        }

根据NMEA0183协议的规定,以“$”开始,主要语句有GPGGA,GPVTG,GPRMC等

他们分别是 1、 GPS DOP and Active Satellites(GSA)当前卫星信息

                 2、 GPS Satellites in View(GSV)可见卫星信息

                 3、Global Positioning System Fix Data(GGA)GPS定位信息

  private bool GetAltitudeFromGGA(string scr)
        {
            float altitude = -1000, geoideAltitude = -1000;
            string[] fields;
            bool paramChanged = false;

            fields = scr.Split(',');
            if (fields.GetLength(0) < 15)
                return false;
            // 获取altitude
            if (fields[9].Length > 2)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[9],
 @"^[0-9]+[.]?([\d]+)?").Value == fields[9])
                {
                    altitude = Convert.ToSingle(fields[9]);
                    if (altitude != this.altitude && altitude != -1000)
                    {
                        this.altitude = altitude;
                        paramChanged = true;
                    }
                }
            }
            // 获取geoideAltitude
            if (fields[11].Length > 2)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[11],
@"^[0-9]+[.]?([\d]+)?").Value == fields[11])
                {
                    geoideAltitude = Convert.ToSingle(fields[11]);
                    if (geoideAltitude != this.geoideAltitude && geoideAltitude != -1000)
                    {
                        this.geoideAltitude = geoideAltitude;
                        paramChanged = true;
                    }
                }
            }
            //高度信息作为辅助信息,不单独报告,只有当经纬度这样的主信息发生变化的时候跟随主信息一起上报

            return false;// paramChanged;
        }

                4、Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐定位信息

             private bool GetGpsInfoFromRMC(string scr)
        {
            int latiDegree = 400, longiDegree = 400;
            float latiMinute = 400, longiMinute = 400, speedTemp = 0, directionTemp = this.direction;
            char statusTemp = (char)0x0;
            float latitudeTemp = 400, longitudeTemp = 400;
            bool paramChanged = false;

            string[] fields = scr.Split(',');

            if (fields.GetLength(0) < 12)
                return false;
            // 状态

            if (fields[2].Length == 1)
            {
                statusTemp = Convert.ToChar(fields[2]);
            }
            // Lati
            if (fields[3].Length > 5)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[3],
@"^[0-9]+[.]?([\d]+)?").Value == fields[3])
                {
                    latiDegree = Convert.ToInt32(fields[3].Substring(0, 2), 10);
                    latiMinute = Convert.ToSingle(fields[3].Substring(2, fields[3].Length - 2));
                    paramChanged = true;
                }
            }
            // NSHemisphere
            if (fields[4].Length == 1)
            {
                //'s' 'S'
                if (string.Equals(fields[4], "S", StringComparison.CurrentCultureIgnoreCase))
                {
                    latitudeTemp = -latitudeTemp;
                }
            }
            // long
            if (fields[5].Length > 5)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[5],
@"^[0-9]+[.]?([\d]+)?").Value == fields[5])
                {
                    longiDegree = Convert.ToInt32(fields[5].Substring(0, 3), 10);
                    longiMinute = Convert.ToSingle(fields[5].Substring(3, fields[5].Length - 3));
                    paramChanged = true;
                }
            }
            // EWHemisphere
            if (fields[6].Length == 1)
            {
                //'w' 'W'
                if (string.Equals(fields[6], "W", StringComparison.CurrentCultureIgnoreCase))
                {
                    longitudeTemp = -longitudeTemp;
                }
            }
            // speed
            if (fields[7].Length > 2)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[7],
@"^[0-9]+[.]?([\d]+)?").Value == fields[7])
                {
                    speedTemp = (float)(Convert.ToSingle(fields[7]) * 1.852);
                    paramChanged = true;
                }
            }
            // direction
            if (fields[8].Length > 2)
            {
                if (System.Text.RegularExpressions.Regex.Match(fields[8],
 @"^[0-9]+[.]?([\d]+)?").Value == fields[8])
                {
                    directionTemp = Convert.ToSingle(fields[8]);
                    paramChanged = true;
                }
            }
            if ((latiDegree != 400) && (latiMinute != (float)400.0))
            {
                latitudeTemp = (float)(latiDegree + latiMinute / 60.0);
            }
            if ((longiDegree != 400) && (longiMinute != (float)400.0))
            {
                longitudeTemp = (float)(longiDegree + longiMinute / 60.0);
            }
            if (paramChanged)
            {
                if ((this.latitude == latitudeTemp) &&
                    (this.longitude == longitudeTemp) &&
                    (this.speed == speedTemp) &&
                    (this.direction == directionTemp) &&
                    (this.status == statusTemp))
                    return false;
                else
                {
                    this.latitude = latitudeTemp;
                    this.longitude = longitudeTemp;
                    this.direction = directionTemp;
                    this.speed = speedTemp;
                    this.status = statusTemp;
                    return true;
                }
            }
            else
                return false;
        }

 

http://www.winbile.net/cms/News/Newsc8c68i8629.aspx

 

 

 

posted on 2009-04-26 11:25  蓝色心语  阅读(1604)  评论(1编辑  收藏  举报