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设备数据的获取

  1. public class UsbNmeaGpsHelper : IGpsHelper
  2. {
  3. private SerialPort serialPort = null;
  4. private Object lockOjb2 = new object();
  5. private string currentPortName = "";
  6. private int currentReadTimeout = 2000;
  7. private int currentBaudRate = 4800;
  8.  
  9. private double latitude = 0;
  10. /// <summary>
  11. /// 最新纬度
  12. /// </summary>
  13. public double Latitude
  14. {
  15. get { return latitude; }
  16. }
  17.  
  18. private double longitude = 0;
  19. /// <summary>
  20. /// 最新经度
  21. /// </summary>
  22. public double Longitude
  23. {
  24. get { return longitude; }
  25. }
  26.  
  27. private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
  28. /// <summary>
  29. /// gps最新状态
  30. /// </summary>
  31. public GeoPositionDeviceStatus LastGeoPositionStatus
  32. {
  33. get { return lastGeoPositionStatus; }
  34. }
  35.  
  36. private DateTime lastTimestamp = DateTime.Now;
  37. /// <summary>
  38. /// 数据时间
  39. /// </summary>
  40. public DateTime LastTimestamp
  41. {
  42. get { return lastTimestamp; }
  43. }
  44.  
  45. public UsbNmeaGpsHelper(string portName, int baudRate, int readTimeout)
  46. {
  47. currentPortName = portName;
  48. currentBaudRate = baudRate;
  49. currentReadTimeout = readTimeout;
  50. }
  51.  
  52. public UsbNmeaGpsHelper(string portName)
  53. : this(portName, 4800, 2000)
  54. {
  55.  
  56. }
  57.  
  58. /// <summary>
  59. /// 打开端口,开始监测
  60. /// </summary>
  61. public void Start()
  62. {
  63. if (serialPort == null)
  64. {
  65. lock (lockOjb2)
  66. {
  67. serialPort = new SerialPort();
  68. /// 名称不能错
  69. serialPort.PortName = currentPortName;
  70. /// 需要设置超时,要不会阻塞
  71. serialPort.ReadTimeout = currentReadTimeout;
  72. /// 波特率不能错,要不读不到数据
  73. serialPort.BaudRate = currentBaudRate;
  74. /// 获取数据
  75. serialPort.DataReceived += serialPort_DataReceived;
  76. /// 打开端口
  77. serialPort.Open();
  78. }
  79. }
  80. else
  81. {
  82. if (serialPort.IsOpen)
  83. {
  84. serialPort.Close();
  85. }
  86. serialPort.Open();
  87. }
  88. }
  89.  
  90. void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
  91. {
  92. try
  93. {
  94. String txt = serialPort.ReadLine();
  95. HandleMsg(txt);
  96. }
  97. catch (Exception exp)
  98. {
  99. System.Diagnostics.Trace.WriteLine(exp.Message);
  100. }
  101. }
  102.  
  103. /// <summary>
  104. /// gps数据解析,只获取需要的数据
  105. /// 当前设备的频率为1秒一次
  106. /// </summary>
  107. /// <param name="msg"></param>
  108. private void HandleMsg(string msg)
  109. {
  110. /// 根据GPGGA取出全部信息
  111. if (msg.StartsWith("$GPRMC") && msg[msg.Length - 4] == '*')
  112. {
  113. String[] infos = msg.Split(',');
  114. if (infos.Length == 13 || infos.Length == 12)
  115. {
  116. ///ddmmyy(日月年)hhmmss.sss(时分秒.毫秒)
  117. string timeText = infos[9] + infos[1];
  118. DateTime utcDt = DateTime.UtcNow;
  119. try
  120. {
  121. DateTime? parseDt = DateTimeHelper.ParseDateTime(timeText,
  122. "ddMMyyHHmmss.fff");
  123. if (parseDt.HasValue)
  124. {
  125. utcDt = parseDt.Value;
  126. }
  127. }
  128. catch (Exception ex)
  129. {
  130. System.Diagnostics.Trace.WriteLine(msg + Environment.CommandLine
  131. + ex.ToString());
  132. }
  133. utcDt = utcDt.ToLocalTime();
  134. lastTimestamp = utcDt;
  135.  
  136. string GPSStateText = infos[2];
  137. if (GPSStateText == "A")
  138. {
  139. lastGeoPositionStatus = GeoPositionDeviceStatus.Ready;
  140. }
  141. else
  142. {
  143. lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
  144. }
  145.  
  146. string latText = infos[3];
  147. latitude = ConvertToJWD(latText, 2);
  148.  
  149. string latNSText = infos[4];
  150.  
  151. string lonText = infos[5];
  152. longitude = ConvertToJWD(lonText, 3);
  153. string lonEWText = infos[6];
  154.  
  155. string velocityText = infos[7];
  156. string northAngleText = infos[8];
  157. }
  158. }
  159. }
  160.  
  161. /// <summary>
  162. /// 经纬度转化
  163. /// </summary>
  164. /// <param name="value"></param>
  165. /// <param name="index"></param>
  166. /// <returns></returns>
  167. private double ConvertToJWD(String value, Int32 index)
  168. {
  169. try
  170. {
  171. Int32 du = DbObjectConverter.ToInt(value.Substring(0, index));
  172. Double fen = Math.Round(DbObjectConverter.ToDouble(value.Substring(index)) / 60, 8);
  173. return du + fen;
  174. }
  175. catch
  176. {
  177. return 0;
  178. }
  179. }
  180.  
  181. /// <summary>
  182. /// 关闭端口
  183. /// </summary>
  184. public void Stop()
  185. {
  186. if (serialPort != null)
  187. {
  188. serialPort.Close();
  189. }
  190. }
  191. }
内置gps设备数据的获取

  1. public class GpsBuildinWatcherHelper : IGpsHelper
  2. {
  3. private GeoCoordinateWatcher geoCoordinateWatcher;
  4. private Object lockOjb2 = new object();
  5.  
  6. private double latitude = 0;
  7. public double Latitude
  8. {
  9. get { return latitude; }
  10. }
  11.  
  12. private double longitude = 0;
  13. public double Longitude
  14. {
  15. get { return longitude; }
  16. }
  17.  
  18. private GeoPositionDeviceStatus lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
  19. public GeoPositionDeviceStatus LastGeoPositionStatus
  20. {
  21. get { return lastGeoPositionStatus; }
  22. }
  23.  
  24. private DateTime lastTimestamp = DateTime.Now;
  25.  
  26. public DateTime LastTimestamp
  27. {
  28. get { return lastTimestamp; }
  29. }
  30.  
  31. //检测到位置更改时
  32. //当定位服务已准备就绪并接收数据时,它将开始引发 PositionChanged 事件
  33. public void watcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
  34. {
  35. latitude = e.Position.Location.Latitude;
  36. longitude = e.Position.Location.Longitude;
  37. lastTimestamp = e.Position.Timestamp.LocalDateTime;
  38. }
  39.  
  40. //当位置服务状态发生变化时
  41. //在 GeoPositionStatusChangedEventArgs 对象中传递的 GeoPositionStatus 枚举获取该服务的当前状态。
  42. //可以使用它在应用程序中启用基于位置的功能,以及将服务的当前状态通知给用户。
  43. public void watcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
  44. {
  45. switch (e.Status)
  46. {
  47. //如果服务的状态为 Disabled,则可以检查 Permission 属性,看用户是否禁用了应用程序的定位服务功能。
  48. case GeoPositionStatus.Disabled:
  49. if (geoCoordinateWatcher.Permission == GeoPositionPermission.Denied)
  50. {
  51. lastGeoPositionStatus = GeoPositionDeviceStatus.Denied;
  52. }
  53. else
  54. {
  55. lastGeoPositionStatus = GeoPositionDeviceStatus.Disabled;
  56. }
  57. break;
  58. case GeoPositionStatus.Initializing:
  59. // 位置服务正在尝试获取数据
  60. lastGeoPositionStatus = GeoPositionDeviceStatus.Initializing;
  61. break;
  62. case GeoPositionStatus.NoData:
  63. lastGeoPositionStatus = GeoPositionDeviceStatus.NoData;
  64. break;
  65. case GeoPositionStatus.Ready:
  66. lastGeoPositionStatus = GeoPositionDeviceStatus.Ready;
  67. break;
  68. }
  69. }
  70.  
  71. public GpsBuildinWatcherHelper(GeoPositionAccuracy desiredAccuracy, double movementThreshold)
  72. {
  73. currentDesiredAccuracy = desiredAccuracy;
  74. currentMovementThreshold = movementThreshold;
  75. }
  76.  
  77. public GpsBuildinWatcherHelper()
  78. : this(GeoPositionAccuracy.High, 5)
  79. {
  80. }
  81.  
  82. private GeoPositionAccuracy currentDesiredAccuracy = GeoPositionAccuracy.Default;
  83. private double currentMovementThreshold = 0;
  84.  
  85. public void Start()
  86. {
  87. if (geoCoordinateWatcher == null)
  88. {
  89. lock (lockOjb2)
  90. {
  91. geoCoordinateWatcher = new GeoCoordinateWatcher(currentDesiredAccuracy); // 采用高精度
  92. geoCoordinateWatcher.MovementThreshold = currentMovementThreshold; // PositionChanged事件之间传送的最小距离
  93. geoCoordinateWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
  94. geoCoordinateWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
  95. geoCoordinateWatcher.Start();//开始使用位置服务
  96. }
  97. }
  98. else//方便测试,实际使用需要注意
  99. {
  100. geoCoordinateWatcher.Start();//开始使用位置服务
  101. }
  102. }
  103.  
  104. public void Stop()
  105. {
  106. if (geoCoordinateWatcher != null)
  107. {
  108. lock (lockOjb2)
  109. {
  110. geoCoordinateWatcher.PositionChanged -= new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(watcher_PositionChanged);
  111. geoCoordinateWatcher.Stop();
  112. geoCoordinateWatcher.StatusChanged -= new EventHandler<GeoPositionStatusChangedEventArgs>(watcher_StatusChanged);
  113. geoCoordinateWatcher.Dispose();
  114. geoCoordinateWatcher = null;
  115. }
  116. }
  117. }
  118. }

使用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. GitBook制作电子书详细教程(命令行版)

    GitBook 是一款基于 Node.js 开发的开源的工具,可以通过命令行的方式创建电子书项目,再使用 MarkDown 编写电子书内容,然后生成 PDF.ePub.mobi 格式的电子书,或生成一 ...

  2. nodejs+sequelize操作mysql数据库

    前言: 本人对mysql不是很熟悉,只会命令行的简单增删改查.有些观点可能不到位请谅解. sequelize是针对node.js和io.js开发的基于ORM的框架,它支持的数据库包括:PostgreS ...

  3. Visual Studio 14 初试,vNext

    下了几天的VS 2014 .终于安装上了,花了好几天时间, VS 2014  下载地址, http://www.visualstudio.com/en-us/downloads/visual-stud ...

  4. 锋利的jQuery学习总结

    通过对<锋利的jQuery>(第二版)一书的学习,发现此书讲解通俗易懂,是学习jQuery的一本很好的指导书,特作如下总结.此书主要讲解了jQuery的常用操作,包括认识jQuery,jQ ...

  5. 【原创】Linux常用管理命令总结

    一.文件夹操作:1.查看文件夹ls [-al]/dir Diredtory_Name2.建立文件夹mkdir [-p] Diredtory_Name3.删除文件夹rm -r[f] Diredtory_ ...

  6. unity中的WWW通讯问题

    网上很多写到WWW的问题. 一.局限性比较大,使用不方便二.WWW类的使用不符合微软的命名规范三.在大量并发使用WWW类会发生"Too Many Threads"的异常 确实有些, ...

  7. Esfog_UnityShader教程_遮挡描边(实现篇)

     在上一篇中,我们基本上说明了遮挡描边实现的一种基本原理.这一篇中我们将了解一下基于这种原理的具体实现代码.本篇中的内容和前几篇教程相比,相对比较难一些,建议先有一些基本的Unity的C#脚本编程经验 ...

  8. Windows消息过滤

    在C#编程中,经常会遇到一些场景,如禁止鼠标拖动窗体,启用某些快捷键,禁止鼠标移动等.遇到这些需求,可以通过窗体的MouseMove事件,OnDragDrop,OnMove等事件来解决问题, 但是该方 ...

  9. SQL语句Where中使用别名作为判断条件

    当我们使用某个表达式作为输出的一列时,我们无法再Where条件中直接使用该列作判断条件.   例如下面的SQL语句: select id, (c1 + c2) as s from t1  where ...

  10. VI 命令 gg 跳到第一行,dG 删除后面的所有内容

    VI 命令 gg 跳到第一行,dG 删除后面的所有内容