1. 简介
    最近工作中需要读取gps设备的信息,平板本身有内置的gps设备,但是精度不够,就又添加了一个外置的gps。
    对于外置的gps,我们主要通过SerialPort类来获得串口的信息,然后对接收到的内容进行解析处理,
    对于内置的gps,我们可以通过GeoCoordinateWatcher类来方便的获取gps数据。
  2. 使用 SerialPort 设置串口属性
    进行串口通讯时,需要设置一些相关参数,可以通过设置SerialPort 类的属性来进行。串口属性主要包括
    .PortName 串口名称,COM1, COM2等。
    .BaudRate 波特率,也就是串口通讯的速度,进行串口通讯的双方其波特率需要相同,如果用PC连接其他非PC系统,一般地,波特率由非PC系统决定。
    .ReadTimeout超时时间。
    .Parity 奇偶校验。可以选取枚举Parity中的值
    .DataBits 数据位
    .StopBits 停止位,可以选取枚举StopBits中的值
    .Handshake 握手方式,也就是数据流控制方式,可以选取枚举Handshake中的值
  3. 事件DataReceived
    SerialPort 提供了DataReceived事件。当有数据进入时,该事件被触发。该事件的触发由操作系统决定,当有数据到达时,该事件在辅助线程中被触发。辅助线程的优先级比较低,因此并不能确保每个字节的数据到达时,该事件都被触发。
    在使用该事件接收数据时,最好对定义通讯协议格式,添加桢头和桢尾。在DataReceived事件中接收数据时,把数据放在数组中或字符串中缓冲起来,当接收的包含桢头和桢尾的完整数据时,再进行处理。
  4. 解析Gps信息
外置gps设备数据的获取

   public class UsbNmeaGpsHelper : IGpsHelper
    {
        private SerialPort serialPort = null;
        private Object lockOjb2 = new object();
        private string currentPortName = "";
        private int currentReadTimeout = 2000;
        private int currentBaudRate = 4800;

        private double latitude = 0;
        /// <summary>
        /// 最新纬度
        /// </summary>
        public double Latitude
        {
            get { return latitude; }
        }

        private double longitude = 0;
        /// <summary>
        /// 最新经度
        /// </summary>
        public double Longitude
        {
            get { return longitude; }
        }

        private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
        /// <summary>
        /// gps最新状态
        /// </summary>
        public GeoPositionDeviceStatus LastGeoPositionStatus
        {
            get { return lastGeoPositionStatus; }
        }

        private DateTime lastTimestamp = DateTime.Now;
        /// <summary>
        /// 数据时间
        /// </summary>
        public DateTime LastTimestamp
        {
            get { return lastTimestamp; }
        }

        public UsbNmeaGpsHelper(string portName, int baudRate, int readTimeout)
        {
            currentPortName = portName;
            currentBaudRate = baudRate;
            currentReadTimeout = readTimeout;
        }

        public UsbNmeaGpsHelper(string portName)
            : this(portName, 4800, 2000)
        {

        }

        /// <summary>
        /// 打开端口,开始监测
        /// </summary>
        public void Start()
        {
            if (serialPort == null)
            {
                lock (lockOjb2)
                {
                    serialPort = new SerialPort();
                    /// 名称不能错
                    serialPort.PortName = currentPortName;
                    /// 需要设置超时,要不会阻塞
                    serialPort.ReadTimeout = currentReadTimeout;
                    /// 波特率不能错,要不读不到数据
                    serialPort.BaudRate = currentBaudRate;
                    /// 获取数据
                    serialPort.DataReceived += serialPort_DataReceived;
                    /// 打开端口
                    serialPort.Open();
                }
            }
            else
            {
                if (serialPort.IsOpen)
                {
                    serialPort.Close();
                }
                serialPort.Open();
            }
        }

        void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                String txt = serialPort.ReadLine();
                HandleMsg(txt);
            }
            catch (Exception exp)
            {
                System.Diagnostics.Trace.WriteLine(exp.Message);
            }
        }

        /// <summary>
        /// gps数据解析,只获取需要的数据
        /// 当前设备的频率为1秒一次
        /// </summary>
        /// <param name="msg"></param>
        private void HandleMsg(string msg)
        {
            /// 根据GPGGA取出全部信息
            if (msg.StartsWith("$GPRMC") && msg[msg.Length - 4] == '*')
            {
                String[] infos = msg.Split(',');
                if (infos.Length == 13 || infos.Length == 12)
                {
                    ///ddmmyy(日月年)hhmmss.sss(时分秒.毫秒)
                    string timeText = infos[9] + infos[1];
                    DateTime utcDt = DateTime.UtcNow;
                    try
                    {
                        DateTime? parseDt = DateTimeHelper.ParseDateTime(timeText,
                            "ddMMyyHHmmss.fff");
                        if (parseDt.HasValue)
                        {
                            utcDt = parseDt.Value;
                        }
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Trace.WriteLine(msg + Environment.CommandLine
                            + ex.ToString());
                    }
                    utcDt = utcDt.ToLocalTime();
                    lastTimestamp = utcDt;

                    string GPSStateText = infos[2];
                    if (GPSStateText == "A")
                    {
                        lastGeoPositionStatus = GeoPositionDeviceStatus.Ready;
                    }
                    else
                    {
                        lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
                    }

                    string latText = infos[3];
                    latitude = ConvertToJWD(latText, 2);

                    string latNSText = infos[4];

                    string lonText = infos[5];
                    longitude = ConvertToJWD(lonText, 3);
                    string lonEWText = infos[6];

                    string velocityText = infos[7];
                    string northAngleText = infos[8];
                }
            }
        }

        /// <summary>
        /// 经纬度转化
        /// </summary>
        /// <param name="value"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        private double ConvertToJWD(String value, Int32 index)
        {
            try
            {
                Int32 du = DbObjectConverter.ToInt(value.Substring(0, index));
                Double fen = Math.Round(DbObjectConverter.ToDouble(value.Substring(index)) / 60, 8);
                return du + fen;
            }
            catch
            {
                return 0;
            }
        }

        /// <summary>
        /// 关闭端口
        /// </summary>
        public void Stop()
        {
            if (serialPort != null)
            {
                serialPort.Close();
            }
        }
    }
内置gps设备数据的获取

    public class GpsBuildinWatcherHelper : IGpsHelper
    {
        private GeoCoordinateWatcher geoCoordinateWatcher;
        private Object lockOjb2 = new object();

        private double latitude = 0;
        public double Latitude
        {
            get { return latitude; }
        }

        private double longitude = 0;
        public double Longitude
        {
            get { return longitude; }
        }

        private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
        public GeoPositionDeviceStatus LastGeoPositionStatus
        {
            get { return lastGeoPositionStatus; }
        }

        private DateTime lastTimestamp = DateTime.Now;

        public DateTime LastTimestamp
        {
            get { return lastTimestamp; }
        }

        //检测到位置更改时
        //当定位服务已准备就绪并接收数据时,它将开始引发 PositionChanged 事件
        public void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
        {
            latitude = e.Position.Location.Latitude;
            longitude = e.Position.Location.Longitude;
            lastTimestamp = e.Position.Timestamp.LocalDateTime;
        }

        //当位置服务状态发生变化时
        //在 GeoPositionStatusChangedEventArgs 对象中传递的 GeoPositionStatus 枚举获取该服务的当前状态。
        //可以使用它在应用程序中启用基于位置的功能,以及将服务的当前状态通知给用户。
        public void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
        {
            switch (e.Status)
            {
                //如果服务的状态为 Disabled,则可以检查 Permission 属性,看用户是否禁用了应用程序的定位服务功能。
                case GeoPositionStatus.Disabled:
                    if (geoCoordinateWatcher.Permission == GeoPositionPermission.Denied)
                    {
                        lastGeoPositionStatus = GeoPositionDeviceStatus.Denied;
                    }
                    else
                    {
                        lastGeoPositionStatus = GeoPositionDeviceStatus.Disabled;
                    }
                    break;
                case GeoPositionStatus.Initializing:
                    // 位置服务正在尝试获取数据
                    lastGeoPositionStatus = GeoPositionDeviceStatus.Initializing;
                    break;
                case GeoPositionStatus.NoData:
                    lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
                    break;
                case GeoPositionStatus.Ready:
                    lastGeoPositionStatus = GeoPositionDeviceStatus.Ready;
                    break;
            }
        }

        public GpsBuildinWatcherHelper(GeoPositionAccuracy desiredAccuracy, double movementThreshold)
        {
            currentDesiredAccuracy = desiredAccuracy;
            currentMovementThreshold = movementThreshold;
        }

        public GpsBuildinWatcherHelper()
            : this(GeoPositionAccuracy.High, 5)
        {
        }

        private GeoPositionAccuracy currentDesiredAccuracy = GeoPositionAccuracy.Default;
        private double currentMovementThreshold = 0;

        public void Start()
        {
            if (geoCoordinateWatcher == null)
            {
                lock (lockOjb2)
                {
                    geoCoordinateWatcher = new GeoCoordinateWatcher(currentDesiredAccuracy); // 采用高精度
                    geoCoordinateWatcher.MovementThreshold = currentMovementThreshold; // PositionChanged事件之间传送的最小距离
                    geoCoordinateWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
                    geoCoordinateWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
                    geoCoordinateWatcher.Start();//开始使用位置服务
                }
            }
            else//方便测试,实际使用需要注意
            {
                geoCoordinateWatcher.Start();//开始使用位置服务
            }
        }

        public void Stop()
        {
            if (geoCoordinateWatcher != null)
            {
                lock (lockOjb2)
                {
                    geoCoordinateWatcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
                    geoCoordinateWatcher.Stop();
                    geoCoordinateWatcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
                    geoCoordinateWatcher.Dispose();
                    geoCoordinateWatcher = null;
                }
            }
        }
    }

使用SerialPort 读取外置GPS信息和使用GeoCoordinateWatcher获取内置gps的信息的更多相关文章

  1. Android获取内置sdcard跟外置sdcard路径

    Android获取内置sdcard跟外置sdcard路径.(测试过两个手机,亲测可用) 1.先得到外置sdcard路径,这个接口是系统提供的标准接口. 2.得到上一级文件夹目录 3.得到该目录的所有文 ...

  2. android获取内置和外置SD卡路径 - z

    本文将介绍Android真机环境下如何获取内置和外置SD卡路径. 测试环境:三星Note3,其他手机待测试... 所需权限(AndroidManifest.xml文件里) <uses-permi ...

  3. linux 获取shell内置命令帮助信息 help xx

    shell,命令解释器 shell内置命令有cd/umask/pwd等 help shell内置命令适用于所有用户获取shell内置命令的帮助信息help umaskhelp if

  4. Inxi:获取Linux系统和硬件信息的神器

    导读 在这篇文章里,我们将看到如何使用inxi来获取这些详情信息.在论坛技术支持中,它可以作为调试工具,迅速确定用户的系统配置和硬件信息. Inxi是一个可以获取完整的系统和硬件详情信息的命令行工具, ...

  5. Android开发获取多个存储空间的路径(内置SD卡以及外置SD卡)

    Android开发中经常会遇到多存储空间的问题,包括内置存储路径以及外置SD卡,而且有的时候会有多张外置SD卡,此时就需要获取不同的SD卡路径,然后根据需要来写入或者读出文件. 此处给出常用的SD卡工 ...

  6. 如何通过SerialPort读取和写入设备COM端口数据

    SerialPort类用于控制串行端口文件资源.提供同步 I/O 和事件驱动的 I/O.对管脚和中断状态的访问以及对串行驱动程序属性的访问.另外,SerialPort的功能可以包装在内部 Stream ...

  7. 实战项目——获取图片中的GPS位置信息和拍摄时间

    今天突然看到有人写过获取图片中位置信息的程序.我觉得很有趣,也就自己实践了一下,研究了一下 话不多说,先上代码 #!/usr/bin/env python3 # -*- coding: utf-8 - ...

  8. MTK Android 读取SIM卡参数,获取sim卡运营商信息

    android 获取sim卡运营商信息(转)   TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TE ...

  9. Win CE 6.0 获取手持机GPS定位2----示例代码 (C#)

    一.须知 1.手持机(PDA)必须有GPS模块,才能通过代码使用串口通信获取GPS相关信息 2.要清楚自己手持机(PDA)固定的GPS通信串口号,如我们公司的手持机获取GPS信息的串口为COM4 3. ...

随机推荐

  1. day25、 静态属性、类方法、静态方法、组合、继承、

    一. 静态属性.类方法.静态方法 1.1静态属性 class Room: def __init__(self,name,owner,width,length): self.name=name self ...

  2. JMeter压测Rest请求

    下载及安装 官网下载JMeter3.0: 找到bin目录下的jmeter.bat启动: 压测Rest请求 1.添加线程组 路径:右键“测试计划”->添加“Threads(Users)”-> ...

  3. sql:劳务统计各分公司管理费用明细合计(等同汇总报表)

    select gl_balance.year, bd_accsubj.dispname, sum(gl_balance.debitamount) 收入, sum(gl_balance.creditam ...

  4. 黄聪:css3实现图片划过一束光闪过效果(图片光影掠过效果)

    CSS代码 .guangshu { display:block; position: relative; width:800px; height:450px; margin:0 auto;} .gua ...

  5. 【巩固】Bootstrap笔记三

    这段笔记介绍了bootstrp中以下几点应用点: 警告框的使用 面板功能 运用chart.js制作图表 进度条的制作 媒体对象的制作 有一个元素如果有属性alert-dismissible" ...

  6. Kafka深度解析,众人推荐,精彩好文!

    作者: Jason Guo 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,并保证即使对TB级以上数据 ...

  7. ADVDAV驱动

    // ADV7179 register configuration array for PAL mode ADI_DEV_ACCESS_REGISTER ADV7179_Cfg[]={ {ADV717 ...

  8. 从头开始学算法--NUM operation in MIX

    从前往后,按照课本顺序刚刚看到MIX这部分.NUM是一个转换操作符,可以把字符编码转换为数字.它把registerA & registerX的值转换为数字并赋值给registerA.转换过程是 ...

  9. Node Server管理

    停止服务 Ctrl+Z暂停 Ctrl+C: kill it 先找到process ID (second from the left), 再kill it:$ ps axu | grep node$ k ...

  10. thinkphp3.2!Go for it!

    http://document.thinkphp.cn/manual_3_2.html