gps nmea数据格式解析与生成

一、nmea数据格式介绍
nmea数据如下: 
$GPGGA,025620.00,2602.33721,N,11911.49176,E,2,04,1.63,13.5,M,9.9,M,,0000*5D
$GPRMC,121252.000,A,3958.3032,N,11629.6046,E,15.15,359.95,070306,,,A*54 
$GNRMC,230134.00,A,2237.12422,N,11408.08310,E,9.291,215.59,310518,,,A*75
$GPVTG,359.95,T,,M,15.15,N,28.0,K,A*04 
$GPGSA,A,3,14,15,05,22,18,26,,,,,,,2.1,1.2,1.7*3D 
$GPGSV,3,1,10,18,84,067,23,09,67,067,27,22,49,312,28,15,47,231,30*70 
$GPGSV,3,2,10,21,32,199,23,14,25,272,24,05,21,140,32,26,14,070,20*7E 
$GPGSV,3,3,10,29,07,074,,30,07,163,28*7D
说明:NMEA0183格式以“$”开始,主要语句有GPGGA,GPVTG,GPRMC等
1、 GPS DOP and Active Satellites(GSA)当前卫星信息
$GPGSA,<1>,<2>,<3>,<3>,,,,,<3>,<3>,<3>,<4>,<5>,<6>,<7><CR><LF>
<1>模式 :M = 手动, A = 自动。 
<2>定位型式 1 = 未定位, 2 = 二维定位, 3 = 三维定位。 
<3>PRN 数字:01 至 32 表天空使用中的卫星编号,最多可接收12颗卫星信息。 
<4> PDOP位置精度因子(0.5~99.9) 
<5> HDOP水平精度因子(0.5~99.9) 
<6> VDOP垂直精度因子(0.5~99.9) 
<7> Checksum.(检查位).

2、 GPS Satellites in View(GSV)可见卫星信息 
$GPGSV, <1>,<2>,<3>,<4>,<5>,<6>,<7>,?<4>,<5>,<6>,<7>,<8><CR><LF>
<1> GSV语句的总数 
<2> 本句GSV的编号 
<3> 可见卫星的总数,00 至 12。 
<4> 卫星编号, 01 至 32。 
<5>卫星仰角, 00 至 90 度。 
<6>卫星方位角, 000 至 359 度。实际值。 
<7>讯号噪声比(C/No), 00 至 99 dB;无表未接收到讯号。 
<8>Checksum.(检查位).
第<4>,<5>,<6>,<7>项个别卫星会重复出现,每行最多有四颗卫星。其余卫星信息会于次一行出现,若未使用,这些字段会空白。
3、Global Positioning System Fix Data(GGA)GPS定位信息
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
<1> UTC时间,hhmmss(时分秒)格式 
<2> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输) 
<3> 纬度半球N(北半球)或S(南半球) 
<4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输) 
<5> 经度半球E(东经)或W(西经) 
<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算 
<7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输) 
<8> HDOP水平精度因子(0.5~99.9) 
<9> 海拔高度(-9999.9~99999.9) 
<10> 地球椭球面相对大地水准面的高度 
<11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空) 
<12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)

4、Recommended Minimum Specific GPS/TRANSIT Data(RMC)推荐定位信息
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
<1> UTC时间,hhmmss(时分秒)格式 
<2> 定位状态,A=有效定位,V=无效定位 
<3> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输) 
<4> 纬度半球N(北半球)或S(南半球) 
<5> 经度dddmm.mmmm(度分)格式(前面的0也将被传输) 
<6> 经度半球E(东经)或W(西经) 
<7> 地面速率(000.0~999.9节,前面的0也将被传输) 
<8> 地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输) 
<9> UTC日期,ddmmyy(日月年)格式 
<10> 磁偏角(000.0~180.0度,前面的0也将被传输) 
<11> 磁偏角方向,E(东)或W(西) 
<12> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
5、 Track Made Good and Ground Speed(VTG)地面速度信息 
$GPVTG,<1>,T,<2>,M,<3>,N,<4>,K,<5>*hh<CR><LF> 
<1> 以真北为参考基准的地面航向(000~359度,前面的0也将被传输) 
<2> 以磁北为参考基准的地面航向(000~359度,前面的0也将被传输) 
<3> 地面速率(000.0~999.9节,前面的0也将被传输) 
<4> 地面速率(0000.0~1851.8公里/小时,前面的0也将被传输) 
<5> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)

二、gps数据解析与生成类

  1. //CommonFunction.h
  2. #pragma once
  3. #include <string>
  4. #include <vector>
  5. // 字符串分割
  6. int StringSplit(std::vector<std::string>& dst, const std::string& src, const std::string& separator);
  7. // 去掉前后空格
  8. std::string& StringTrim(std::string &str);
  1. //CommonFunction.cpp
  2. #include "stdafx.h"
  3. #include "CommonFunction.h"
  4. // 字符串分割
  5. int StringSplit(std::vector<std::string>& dst, const std::string& src, const std::string& separator)
  6. {
  7. if (src.empty() || separator.empty())
  8. return 0;
  9. int nCount = 0;
  10. std::string temp;
  11. size_t pos = 0, offset = 0;
  12. // 分割第1~n-1
  13. while ((pos = src.find_first_of(separator, offset)) != std::string::npos)
  14. {
  15. temp = src.substr(offset, pos - offset);
  16. if (temp.length() >= 0) {
  17. dst.push_back(temp);
  18. nCount++;
  19. }
  20. offset = pos + 1;
  21. }
  22. // 分割第n个
  23. temp = src.substr(offset, src.length() - offset);
  24. if (temp.length() >= 0) {
  25. dst.push_back(temp);
  26. nCount++;
  27. }
  28. return nCount;
  29. }
  30. //去前后空格
  31. std::string& StringTrim(std::string &str)
  32. {
  33. if (str.empty()) {
  34. return str;
  35. }
  36. str.erase(0, str.find_first_not_of(" "));
  37. str.erase(str.find_last_not_of(" ") + 1);
  38. return str;
  39. }
  1. //GpsNmeaData.h
  2. //gps nmea 数据解析与生成
  3. #pragma once
  4. #include "CommonFunction.h"
  5. //gpsdata格式
  6. enum GpsDataFormat
  7. {
  8. GpsDataFormat_None = 0, //none
  9. GpsDataFormat_GNRMC = 1, //GNRMC
  10. GpsDataFormat_GPRMC = 2, //GPRMC
  11. GpsDataFormat_GPGGA = 3, //GPGGA
  12. };
  13. //Status
  14. enum GpsStatus
  15. {
  16. GpsStatus_Valid = 'A', //数据有效(GPRMC/GNRMC)
  17. GpsStatus_Invalid = 'V', //数据无效(GPRMC/GNRMC)
  18. GpsStatus_NoLocation = '0', //未定位(GPGGA)
  19. GpsStatus_NoDiffLocation = '1', //非差分定位(GPGGA)
  20. GpsStatus_DiffLocation = '2', //差分定位(GPGGA)
  21. GpsStatus_Estimating = '6', //正在估算(GPGGA)
  22. };
  23. //纬度方向
  24. enum GpsLatDirect
  25. {
  26. GpsLatDirect_N = 'N', //北纬
  27. GpsLatDirect_S = 'S', //南纬
  28. };
  29. //经度方向
  30. enum GpsLngDirect
  31. {
  32. GpsLngDirect_E = 'E', //东经
  33. GpsLngDirect_W = 'W', //西经
  34. };
  35. //磁偏角方向,E=东,W=西
  36. enum GpsDeclinationDirect
  37. {
  38. GpsDeclinationDirect_Invalid= '0',
  39. GpsDeclinationDirect_E = 'E',
  40. GpsDeclinationDirect_W = 'W',
  41. };
  42. //模式,A=自动,D=差分,E=估测,N=数据无效
  43. enum GpsMode
  44. {
  45. GpsMode_A = 'A',
  46. GpsMode_D = 'D',
  47. GpsMode_E = 'E',
  48. GpsMode_N = 'N',
  49. };
  50. class GpsNmeaData
  51. {
  52. public:
  53. GpsNmeaData();
  54. virtual ~GpsNmeaData();
  55. //设置初始gps数据格式
  56. void SetInitGpsDataFormat(unsigned char ucInitGpsDataFormat);
  57. //加载GPS字符串
  58. bool LoadGPSString(char *pInputString, bool bIsCompareChecksum = true);
  59. //生成GPS字符串
  60. bool CreateGPSString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag);
  61. //加载GPRMC字符串
  62. bool LoadGPRMCString(char *pInputString,std::vector<std::string> vecValue,bool bIsCompareChecksum=true);
  63. //生成GPRMC字符串
  64. bool CreateGPRMCString(char *pOutputString, int & nOutputStringSize,bool bIsHasEndFlag);
  65. //加载GNRMC字符串
  66. bool LoadGNRMCString(char *pInputString,std::vector<std::string> vecValue, bool bIsCompareChecksum = true);
  67. //生成GNRMC字符串
  68. bool CreateGNRMCString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag);
  69. //加载GPGGA字符串
  70. bool LoadGPGGAString(char *pInputString, std::vector<std::string> vecValue, bool bIsCompareChecksum = true);
  71. //生成GPGGA字符串
  72. bool CreateGPGGAString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag);
  73. //计算经纬度(根据速度和方向计算下一经纬度)
  74. void CalcLngLat(float fDirect, float fSpeed, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat);
  75. void CalcLngLatEx(float fDirect, float fSpeed, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat, int nKeepSeconds=1);
  76. //计算经纬度(根据距离和方向计算下一经纬度)
  77. void CalcLngLatByDistanceAndDirect(float fDirect, double fDistance, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat);
  78. //获取与设置参数
  79. void GetLng(double & fLng,unsigned char & ucDirect);
  80. void SetLng(double fLng, unsigned char ucDirect);
  81. void GetLat(double & fLat,unsigned char & ucDirect);
  82. void SetLat(double fLat, unsigned char ucDirect);
  83. float GetSpeed();
  84. void SetSpeed(float fSpeed);
  85. float GetDirect();
  86. void SetDirect(float fDirect);
  87. unsigned char GetStatus();
  88. void SetStatus(unsigned char ucStatus);
  89. unsigned char GetDeclination();
  90. void SetDeclination(unsigned char ucDeclination);
  91. unsigned char GetDeclinationDirect();
  92. void SetDeclinationDirect(unsigned char ucDeclinationDirect);
  93. unsigned char GetMode();
  94. void SetMode(unsigned char ucMode);
  95. unsigned char GetSatelliteNum();
  96. void SetSatelliteNum(unsigned char ucSatelliteNum);
  97. float GetHDOP();
  98. void SetHDOP(float fHDOP);
  99. float GetHigh();
  100. void SetHigh(float fHigh);
  101. float GetEarthHigh();
  102. void SetEarthHigh(float fHigh);
  103. unsigned int GetDiffTime();
  104. void SetDiffTime(unsigned int uiDiffTime);
  105. unsigned short GetDiffSiteId();
  106. void SetDiffSiteId(unsigned short usDiffSiteId);
  107. unsigned char GetChecksum();
  108. void SetChecksum(unsigned char ucChecksum);
  109. void GetTime(unsigned short & usYear, unsigned short & usMonth, unsigned short & usDay, unsigned short & usHour,
  110. unsigned short & usMiniute, unsigned short & usSecond, unsigned short & usMillsSecond);
  111. void SetTime(unsigned short usYear, unsigned short usMonth, unsigned short usDay, unsigned short usHour,
  112. unsigned short usMiniute, unsigned short usSecond, unsigned short usMillsSecond);
  113. void SetNowTime();
  114. public:
  115. //度分转换度
  116. static double dm_to_degree(double dm);
  117. //度转换度分
  118. static double degree_to_dm(double ddd_dddd);
  119. //计算两点经纬度之间的距离
  120. static double GpsNmeaDataDistance(double latitude1, double longitude1, double latitude2, double longitude2);
  121. protected:
  122. //计算校验和
  123. unsigned char CalcChecksum(unsigned char *pInput, int nInputSize);
  124. protected:
  125. unsigned char m_ucGpsDataFormat; //GPS数据格式
  126. double m_fLng; //经度
  127. unsigned char m_ucGpsLngDirect;
  128. double m_fLat; //纬度
  129. unsigned char m_ucGpsLatDirect;
  130. float m_fSpeed; //速度,千米/小时 (一节也是1.852千米/小时)
  131. float m_fDirect; //方向
  132. unsigned char m_ucStatus; //GPS状态 A=数据有效;V=数据无效
  133. unsigned char m_ucDeclination; //磁偏角,(000 - 180)度(前导位数不足则补0
  134. unsigned char m_ucDeclinationDirect;//磁偏角方向,E=东,W=西
  135. unsigned char m_ucMode; //模式,A=自动,D=差分,E=估测,N=数据无效
  136. unsigned char m_ucChecksum; //校验和
  137. unsigned char m_ucSatelliteNum; //卫星数
  138. float m_fHDOP; //HDOP水平精度因子(0.5~99.9
  139. float m_fHigh; //海拔高度(-9999.9~99999.9
  140. float m_fEarthHigh; //地球椭球面相对大地水准面的高度
  141. unsigned int m_uiDiffTime; //差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空)
  142. unsigned short m_usDiffSiteId; //差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)
  143. unsigned short m_usYear;
  144. unsigned short m_usMonth;
  145. unsigned short m_usDay;
  146. unsigned short m_usHour;
  147. unsigned short m_usMinute;
  148. unsigned short m_usSecond;
  149. unsigned short m_usMillsSecond;
  150. };
  1. //GpsNmeaData.cpp
  2. #include "stdafx.h"
  3. #include "GpsNmeaData.h"
  4. #define GpsNmeaData_StringSplitMinCount 8 //Gprmc字符串分解子字符串最小个数
  5. #define GpsNmeaData_Gnrmc_Head "$GNRMC" //Gps nmea帧头,$GNRMC
  6. #define GpsNmeaData_Gprmc_Head "$GPRMC" //Gps nmea帧头,$GPRMC
  7. #define GpsNmeaData_Gpgga_Head "$GPGGA" //Gps nmea帧头,$GPGGA
  8. const double PI = 3.14159265358979323846;
  9. const double Ea = 6378137; // 赤道半径
  10. const double Eb = 6356725; // 极半径
  11. GpsNmeaData::GpsNmeaData()
  12. {
  13. m_ucGpsDataFormat = GpsDataFormat_None;
  14. m_fLng = 0.0f;
  15. m_ucGpsLngDirect = GpsLngDirect_E;
  16. m_fLat = 0.0;
  17. m_ucGpsLatDirect = GpsLatDirect_N;
  18. m_fSpeed = 0;
  19. m_fDirect = 0;
  20. m_ucStatus = GpsStatus_Valid;
  21. m_ucDeclination = 0;
  22. m_ucDeclinationDirect = GpsDeclinationDirect_E;
  23. m_ucMode = GpsMode_A;
  24. m_ucChecksum = 0;
  25. m_usYear = 0;
  26. m_usMonth = 0;
  27. m_usDay = 0;
  28. m_usHour = 0;
  29. m_usMinute = 0;
  30. m_usSecond = 0;
  31. m_usMillsSecond = 0;
  32. m_ucSatelliteNum = 0;
  33. m_fHDOP = 0.5;
  34. m_fHigh = 0;
  35. m_fEarthHigh = 0;
  36. m_uiDiffTime = 0;
  37. m_usDiffSiteId = 0;
  38. }
  39. GpsNmeaData::~GpsNmeaData()
  40. {
  41. }
  42. //设置初始gps数据格式
  43. void GpsNmeaData::SetInitGpsDataFormat(unsigned char ucInitGpsDataFormat)
  44. {
  45. m_ucGpsDataFormat = ucInitGpsDataFormat;
  46. }
  47. //获取与设置参数
  48. void GpsNmeaData::GetLng(double & fLng, unsigned char & ucDirect)
  49. {
  50. fLng = m_fLng;
  51. ucDirect = m_ucGpsLngDirect;
  52. }
  53. void GpsNmeaData::SetLng(double fLng, unsigned char ucDirect)
  54. {
  55. m_fLng = fLng;
  56. m_ucGpsLngDirect = ucDirect;
  57. }
  58. void GpsNmeaData::GetLat(double & fLat, unsigned char & ucDirect)
  59. {
  60. fLat = m_fLat;
  61. ucDirect = m_ucGpsLatDirect;
  62. }
  63. void GpsNmeaData::SetLat(double fLat, unsigned char ucDirect)
  64. {
  65. m_fLat = fLat;
  66. m_ucGpsLatDirect = ucDirect;
  67. }
  68. float GpsNmeaData::GetSpeed()
  69. {
  70. return m_fSpeed;
  71. }
  72. void GpsNmeaData::SetSpeed(float fSpeed)
  73. {
  74. m_fSpeed = fSpeed;
  75. }
  76. float GpsNmeaData::GetDirect()
  77. {
  78. return m_fDirect;
  79. }
  80. void GpsNmeaData::SetDirect(float fDirect)
  81. {
  82. m_fDirect = fDirect;
  83. }
  84. unsigned char GpsNmeaData::GetStatus()
  85. {
  86. return m_ucStatus;
  87. }
  88. void GpsNmeaData::SetStatus(unsigned char ucStatus)
  89. {
  90. m_ucStatus = ucStatus;
  91. }
  92. unsigned char GpsNmeaData::GetDeclination()
  93. {
  94. return m_ucDeclination;
  95. }
  96. void GpsNmeaData::SetDeclination(unsigned char ucDeclination)
  97. {
  98. m_ucDeclination = ucDeclination;
  99. }
  100. unsigned char GpsNmeaData::GetDeclinationDirect()
  101. {
  102. return m_ucDeclinationDirect;
  103. }
  104. void GpsNmeaData::SetDeclinationDirect(unsigned char ucDeclinationDirect)
  105. {
  106. m_ucDeclinationDirect = ucDeclinationDirect;
  107. }
  108. unsigned char GpsNmeaData::GetMode()
  109. {
  110. return m_ucMode;
  111. }
  112. void GpsNmeaData::SetMode(unsigned char ucMode)
  113. {
  114. m_ucMode = ucMode;
  115. }
  116. unsigned char GpsNmeaData::GetSatelliteNum()
  117. {
  118. return m_ucSatelliteNum;
  119. }
  120. void GpsNmeaData::SetSatelliteNum(unsigned char ucSatelliteNum)
  121. {
  122. m_ucSatelliteNum = ucSatelliteNum;
  123. }
  124. float GpsNmeaData::GetHDOP()
  125. {
  126. return m_fHDOP;
  127. }
  128. void GpsNmeaData::SetHDOP(float fHDOP)
  129. {
  130. m_fHDOP = fHDOP;
  131. }
  132. float GpsNmeaData::GetHigh()
  133. {
  134. return m_fHigh;
  135. }
  136. void GpsNmeaData::SetHigh(float fHigh)
  137. {
  138. m_fHigh = fHigh;
  139. }
  140. float GpsNmeaData::GetEarthHigh()
  141. {
  142. return m_fEarthHigh;
  143. }
  144. void GpsNmeaData::SetEarthHigh(float fHigh)
  145. {
  146. m_fEarthHigh = fHigh;
  147. }
  148. unsigned int GpsNmeaData::GetDiffTime()
  149. {
  150. return m_uiDiffTime;
  151. }
  152. void GpsNmeaData::SetDiffTime(unsigned int uiDiffTime)
  153. {
  154. m_uiDiffTime = uiDiffTime;
  155. }
  156. unsigned short GpsNmeaData::GetDiffSiteId()
  157. {
  158. return m_usDiffSiteId;
  159. }
  160. void GpsNmeaData::SetDiffSiteId(unsigned short usDiffSiteId)
  161. {
  162. m_usDiffSiteId = usDiffSiteId;
  163. }
  164. unsigned char GpsNmeaData::GetChecksum()
  165. {
  166. return m_ucChecksum;
  167. }
  168. void GpsNmeaData::SetChecksum(unsigned char ucChecksum)
  169. {
  170. m_ucChecksum = ucChecksum;
  171. }
  172. void GpsNmeaData::GetTime(unsigned short & usYear, unsigned short & usMonth, unsigned short & usDay, unsigned short & usHour,
  173. unsigned short & usMiniute, unsigned short & usSecond, unsigned short & usMillsSecond)
  174. {
  175. usYear = m_usYear;
  176. usMonth = m_usMonth;
  177. usDay = m_usDay;
  178. usHour = m_usHour;
  179. usMiniute = m_usMinute;
  180. usSecond = m_usSecond;
  181. usMillsSecond = m_usMillsSecond;
  182. }
  183. void GpsNmeaData::SetTime(unsigned short usYear, unsigned short usMonth, unsigned short usDay, unsigned short usHour,
  184. unsigned short usMiniute, unsigned short usSecond, unsigned short usMillsSecond)
  185. {
  186. m_usYear = usYear;
  187. m_usMonth = usMonth;
  188. m_usDay = usDay;
  189. m_usHour = usHour;
  190. m_usMinute = usMiniute;
  191. m_usSecond = usSecond;
  192. m_usMillsSecond = usMillsSecond;
  193. }
  194. void GpsNmeaData::SetNowTime()
  195. {
  196. //格林威治时间
  197. time_t timep;
  198. time(&timep);
  199. struct tm* zeroTM = gmtime(&timep);
  200. SetTime(zeroTM->tm_year + 1900,zeroTM->tm_mon+1,zeroTM->tm_mday,zeroTM->tm_hour,zeroTM->tm_min,zeroTM->tm_sec,0);
  201. }
  202. //加载GPS字符串
  203. bool GpsNmeaData::LoadGPSString(char *pInputString, bool bIsCompareChecksum)
  204. {
  205. bool bRet = false;
  206. std::vector<std::string> vecValue;
  207. int nStringSplitRet = StringSplit(vecValue, pInputString, ",");
  208. if (nStringSplitRet >= GpsNmeaData_StringSplitMinCount)
  209. {
  210. if (strcmp(vecValue[0].c_str(), GpsNmeaData_Gprmc_Head) == 0)
  211. {
  212. //gprmc
  213. m_ucGpsDataFormat = GpsDataFormat_GPRMC;
  214. bRet = LoadGPRMCString(pInputString,vecValue, bIsCompareChecksum);
  215. }
  216. else if (strcmp(vecValue[0].c_str(), GpsNmeaData_Gnrmc_Head) == 0)
  217. {
  218. //gnrmc
  219. m_ucGpsDataFormat = GpsDataFormat_GNRMC;
  220. bRet = LoadGNRMCString(pInputString,vecValue, bIsCompareChecksum);
  221. }
  222. else if (strcmp(vecValue[0].c_str(), GpsNmeaData_Gpgga_Head) == 0)
  223. {
  224. //gpgga
  225. m_ucGpsDataFormat = GpsDataFormat_GPGGA;
  226. bRet = LoadGPGGAString(pInputString, vecValue, bIsCompareChecksum);
  227. }
  228. else
  229. {
  230. //非法数据格式
  231. return false;
  232. }
  233. }
  234. return bRet;
  235. }
  236. //生成GPS字符串
  237. bool GpsNmeaData::CreateGPSString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag)
  238. {
  239. bool bRet = false;
  240. if (m_ucGpsDataFormat == GpsDataFormat_GNRMC)
  241. {
  242. //GNRMC
  243. bRet = CreateGNRMCString(pOutputString, nOutputStringSize, bIsHasEndFlag);
  244. }
  245. else if (m_ucGpsDataFormat == GpsDataFormat_GPRMC)
  246. {
  247. //GPRMC
  248. bRet = CreateGPRMCString(pOutputString, nOutputStringSize, bIsHasEndFlag);
  249. }
  250. else if (m_ucGpsDataFormat == GpsDataFormat_GPGGA)
  251. {
  252. //GPGGA
  253. bRet = CreateGPGGAString(pOutputString, nOutputStringSize, bIsHasEndFlag);
  254. }
  255. else
  256. {
  257. bRet = CreateGNRMCString(pOutputString, nOutputStringSize, bIsHasEndFlag);
  258. }
  259. return bRet;
  260. }
  261. //加载GPRMC字符串
  262. bool GpsNmeaData::LoadGPRMCString(char *pInputString,std::vector<std::string> vecValue, bool bIsCompareChecksum)
  263. {
  264. //$GPRMC,212744.000,A,3721.3623,N,12706.8308,E,5.40,161.91,050317,,,A*65
  265. bool bRet = false;
  266. //utc时间
  267. sscanf(vecValue[1].c_str(), "%2d%2d%2d.%d", &m_usHour, &m_usMinute, &m_usSecond, &m_usMillsSecond);
  268. //状态
  269. if (vecValue[2].size() > 0)
  270. {
  271. m_ucStatus = vecValue[2].c_str()[0];
  272. }
  273. else
  274. {
  275. m_ucStatus = GpsStatus_Invalid;
  276. }
  277. //纬度
  278. double fLatMD = atof(vecValue[3].c_str());
  279. m_fLat = dm_to_degree(fLatMD);
  280. //北纬/南纬
  281. if (vecValue[4].size() > 0)
  282. {
  283. m_ucGpsLatDirect = vecValue[4].c_str()[0];
  284. }
  285. //经度
  286. double fLngMD = atof(vecValue[5].c_str());
  287. m_fLng = dm_to_degree(fLngMD);
  288. //东经/西经
  289. if (vecValue[6].size() > 0)
  290. {
  291. m_ucGpsLngDirect = vecValue[6].c_str()[0];
  292. }
  293. //速度,单位节,一节也是1.852千米/小时
  294. float fSpeedByNodeUnit = atof(vecValue[7].c_str());
  295. m_fSpeed = fSpeedByNodeUnit * 1.852;
  296. //方位角
  297. m_fDirect = atof(vecValue[8].c_str());
  298. //UTC日期
  299. char szDate[12] = { 0 };
  300. strcpy(szDate, vecValue[9].c_str());
  301. int usYear = 0;
  302. int usMonth = 0;
  303. int usDay = 0;
  304. sscanf(szDate, "%02d%02d%02d", &usDay, &usMonth, &usYear);
  305. m_usYear = usYear;
  306. m_usMonth = usMonth;
  307. m_usDay = usDay;
  308. m_usYear += 2000;
  309. //磁偏角
  310. if (vecValue[10].size() > 0)
  311. {
  312. m_ucDeclination = vecValue[10].c_str()[0];
  313. }
  314. //磁偏角方向
  315. if (vecValue[11].size() > 0)
  316. {
  317. m_ucDeclinationDirect = vecValue[11].c_str()[0];
  318. }
  319. else
  320. {
  321. m_ucDeclinationDirect = GpsDeclinationDirect_Invalid;
  322. }
  323. //模式指示、校验
  324. sscanf(vecValue[12].c_str(), "%c*%X", &m_ucMode, &m_ucChecksum);
  325. //计算校验和比对
  326. if (bIsCompareChecksum)
  327. {
  328. char *pFindStarChar = strrchr(pInputString, '*');
  329. if (pFindStarChar != NULL)
  330. {
  331. unsigned char ucTempChecksum = 0;
  332. ucTempChecksum = CalcChecksum((unsigned char *)pInputString, pFindStarChar - pInputString + 1);
  333. if (ucTempChecksum == m_ucChecksum)
  334. {
  335. bRet = true;
  336. }
  337. }
  338. }
  339. else
  340. {
  341. bRet = true;
  342. }
  343. return bRet;
  344. }
  345. //生成GPRMC字符串
  346. bool GpsNmeaData::CreateGPRMCString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag)
  347. {
  348. //$GPRMC,212744.000,A,3721.3623,N,12706.8308,E,5.40,161.91,050317,,,A*65
  349. bool bRet = true;
  350. //memset(pOutputString, 0, nOutputStringSize);
  351. //纬度
  352. double fLatMD = degree_to_dm(m_fLat);
  353. //经度
  354. double fLngMD = degree_to_dm(m_fLng);
  355. //速度(节)
  356. float fSpeedByNodeUnit = m_fSpeed/1.852;
  357. if (m_ucStatus == GpsStatus_Invalid)
  358. {
  359. //数据无效
  360. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,,,,,,,%02d%02d%02d,,,N*",
  361. GpsNmeaData_Gprmc_Head,m_usHour,m_usMinute,m_usSecond,m_usMillsSecond,m_ucStatus,m_usDay,m_usMonth,m_usYear-2000);
  362. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  363. char szChecksum[4] = { 0 };
  364. sprintf_s(szChecksum, "%02X", ucChecksum);
  365. strcat(pOutputString, szChecksum);
  366. if (bIsHasEndFlag)
  367. {
  368. //是否带结束标记符号,0x0d0x0a
  369. char szEndFlag[4] = { 0 };
  370. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  371. strcat(pOutputString, szEndFlag);
  372. }
  373. nOutputStringSize = strlen(pOutputString);
  374. }
  375. else
  376. {
  377. //数据有效
  378. if (m_ucDeclinationDirect == GpsDeclinationDirect_Invalid)
  379. {
  380. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,%.5f,%c,%.5f,%c,%.2f,%.2f,%02d%02d%02d,,,%c*",
  381. GpsNmeaData_Gprmc_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus,
  382. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, fSpeedByNodeUnit, m_fDirect,
  383. m_usDay, m_usMonth, m_usYear - 2000, m_ucMode);
  384. }
  385. else
  386. {
  387. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,%.5f,%c,%.5f,%c,%.2f,%.2f,%02d%02d%02d,%d,%c,%c*",
  388. GpsNmeaData_Gprmc_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus,
  389. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, fSpeedByNodeUnit, m_fDirect,
  390. m_usDay, m_usMonth, m_usYear - 2000, m_ucDeclination, m_ucDeclinationDirect, m_ucMode);
  391. }
  392. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  393. char szChecksum[4] = { 0 };
  394. sprintf_s(szChecksum, "%02X", ucChecksum);
  395. strcat(pOutputString, szChecksum);
  396. if (bIsHasEndFlag)
  397. {
  398. //是否带结束标记符号,0x0d0x0a
  399. char szEndFlag[4] = { 0 };
  400. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  401. strcat(pOutputString, szEndFlag);
  402. }
  403. nOutputStringSize = strlen(pOutputString);
  404. }
  405. return bRet;
  406. }
  407. //加载GNRMC字符串
  408. bool GpsNmeaData::LoadGNRMCString(char *pInputString,std::vector<std::string> vecValue,bool bIsCompareChecksum)
  409. {
  410. //$GNRMC,230134.00,A,2237.12422,N,11408.08310,E,9.291,215.59,310518,,,A*75
  411. bool bRet = false;
  412. //utc时间
  413. sscanf(vecValue[1].c_str(), "%2d%2d%2d.%d", &m_usHour, &m_usMinute, &m_usSecond, &m_usMillsSecond);
  414. //状态
  415. if (vecValue[2].size() > 0)
  416. {
  417. m_ucStatus = vecValue[2].c_str()[0];
  418. }
  419. else
  420. {
  421. m_ucStatus = GpsStatus_Invalid;
  422. }
  423. //纬度
  424. double fLatMD = atof(vecValue[3].c_str());
  425. m_fLat = dm_to_degree(fLatMD);
  426. //北纬/南纬
  427. if (vecValue[4].size() > 0)
  428. {
  429. m_ucGpsLatDirect = vecValue[4].c_str()[0];
  430. }
  431. //经度
  432. double fLngMD = atof(vecValue[5].c_str());
  433. m_fLng = dm_to_degree(fLngMD);
  434. //东经/西经
  435. if (vecValue[6].size() > 0)
  436. {
  437. m_ucGpsLngDirect = vecValue[6].c_str()[0];
  438. }
  439. //速度,单位节,一节也是1.852千米/小时
  440. float fSpeedByNodeUnit = atof(vecValue[7].c_str());
  441. m_fSpeed = fSpeedByNodeUnit * 1.852;
  442. //方位角
  443. m_fDirect = atof(vecValue[8].c_str());
  444. //UTC日期
  445. char szDate[12] = { 0 };
  446. strcpy(szDate, vecValue[9].c_str());
  447. int usYear = 0;
  448. int usMonth = 0;
  449. int usDay = 0;
  450. sscanf(szDate, "%02d%02d%02d", &usDay, &usMonth, &usYear);
  451. m_usYear = usYear;
  452. m_usMonth = usMonth;
  453. m_usDay = usDay;
  454. m_usYear += 2000;
  455. //磁偏角
  456. if (vecValue[10].size() > 0)
  457. {
  458. m_ucDeclination = vecValue[10].c_str()[0];
  459. }
  460. //磁偏角方向
  461. if (vecValue[11].size() > 0)
  462. {
  463. m_ucDeclinationDirect = vecValue[11].c_str()[0];
  464. }
  465. else
  466. {
  467. m_ucDeclinationDirect = GpsDeclinationDirect_Invalid;
  468. }
  469. //模式指示、校验
  470. std::vector<std::string> vecChecksum;
  471. StringSplit(vecChecksum, vecValue[12].c_str(), "*");
  472. if (vecChecksum.size() >= 2)
  473. {
  474. if (vecChecksum[0].c_str() > 0)
  475. {
  476. sscanf(vecChecksum[0].c_str(), "%c", &m_ucMode);
  477. }
  478. char *stop = NULL;
  479. m_ucChecksum = strtol(vecChecksum[1].c_str(), &stop, 16);
  480. }
  481. //计算校验和比对
  482. if (bIsCompareChecksum)
  483. {
  484. char *pFindStarChar = strrchr(pInputString, '*');
  485. if (pFindStarChar != NULL)
  486. {
  487. unsigned char ucTempChecksum = 0;
  488. ucTempChecksum = CalcChecksum((unsigned char *)pInputString, pFindStarChar - pInputString + 1);
  489. if (ucTempChecksum == m_ucChecksum)
  490. {
  491. bRet = true;
  492. }
  493. }
  494. }
  495. else
  496. {
  497. bRet = true;
  498. }
  499. return bRet;
  500. }
  501. //生成GNRMC字符串
  502. bool GpsNmeaData::CreateGNRMCString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag)
  503. {
  504. //$GNRMC,230134.00,A,2237.12422,N,11408.08310,E,9.291,215.59,310518,,,A*75
  505. bool bRet = true;
  506. //memset(pOutputString, 0, nOutputStringSize);
  507. //纬度
  508. double fLatMD = degree_to_dm(m_fLat);
  509. //经度
  510. double fLngMD = degree_to_dm(m_fLng);
  511. //速度(节)
  512. float fSpeedByNodeUnit = m_fSpeed / 1.852;
  513. if (m_ucStatus == GpsStatus_Invalid)
  514. {
  515. //数据无效
  516. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,,,,,,,%02d%02d%02d,,,N*",
  517. GpsNmeaData_Gnrmc_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus, m_usDay, m_usMonth, m_usYear - 2000);
  518. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  519. char szChecksum[4] = { 0 };
  520. sprintf_s(szChecksum, "%02X", ucChecksum);
  521. strcat(pOutputString, szChecksum);
  522. if (bIsHasEndFlag)
  523. {
  524. //是否带结束标记符号,0x0d0x0a
  525. char szEndFlag[4] = { 0 };
  526. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  527. strcat(pOutputString, szEndFlag);
  528. }
  529. nOutputStringSize = strlen(pOutputString);
  530. }
  531. else
  532. {
  533. //数据有效
  534. if (m_ucDeclinationDirect == GpsDeclinationDirect_Invalid)
  535. {
  536. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,%.5f,%c,%.5f,%c,%.3f,%.2f,%02d%02d%02d,,,%c*",
  537. GpsNmeaData_Gnrmc_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus,
  538. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, fSpeedByNodeUnit, m_fDirect,
  539. m_usDay, m_usMonth, m_usYear - 2000, m_ucMode);
  540. }
  541. else
  542. {
  543. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%c,%.5f,%c,%.5f,%c,%.3f,%.2f,%02d%02d%02d,%d,%c,%c*",
  544. GpsNmeaData_Gnrmc_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus,
  545. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, fSpeedByNodeUnit, m_fDirect,
  546. m_usDay, m_usMonth, m_usYear - 2000, m_ucDeclination, m_ucDeclinationDirect, m_ucMode);
  547. }
  548. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  549. char szChecksum[4] = { 0 };
  550. sprintf_s(szChecksum, "%02X", ucChecksum);
  551. strcat(pOutputString, szChecksum);
  552. if (bIsHasEndFlag)
  553. {
  554. //是否带结束标记符号,0x0d0x0a
  555. char szEndFlag[4] = { 0 };
  556. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  557. strcat(pOutputString, szEndFlag);
  558. }
  559. nOutputStringSize = strlen(pOutputString);
  560. }
  561. return bRet;
  562. }
  563. //加载GPGGA字符串
  564. bool GpsNmeaData::LoadGPGGAString(char *pInputString, std::vector<std::string> vecValue,bool bIsCompareChecksum)
  565. {
  566. //$GPGGA,025620.00,2602.33721,N,11911.49176,E,2,04,1.63,13.5,M,9.9,M,,0000*5D
  567. bool bRet = false;
  568. //utc时间
  569. sscanf(vecValue[1].c_str(), "%2d%2d%2d.%d", &m_usHour, &m_usMinute, &m_usSecond, &m_usMillsSecond);
  570. //纬度
  571. double fLatMD = atof(vecValue[2].c_str());
  572. m_fLat = dm_to_degree(fLatMD);
  573. //北纬/南纬
  574. if (vecValue[3].size() > 0)
  575. {
  576. m_ucGpsLatDirect = vecValue[3].c_str()[0];
  577. }
  578. //经度
  579. double fLngMD = atof(vecValue[4].c_str());
  580. m_fLng = dm_to_degree(fLngMD);
  581. //东经/西经
  582. if (vecValue[5].size() > 0)
  583. {
  584. m_ucGpsLngDirect = vecValue[5].c_str()[0];
  585. }
  586. //状态
  587. if (vecValue[6].size() > 0)
  588. {
  589. m_ucStatus = vecValue[6].c_str()[0];
  590. }
  591. else
  592. {
  593. m_ucStatus = '0';
  594. }
  595. //卫星数
  596. m_ucSatelliteNum = atoi(vecValue[7].c_str());
  597. //HDOP水平精度因子(0.5~99.9)
  598. m_fHDOP = atof(vecValue[8].c_str());
  599. //海拔高度( - 9999.9~99999.9)
  600. m_fHigh = atof(vecValue[9].c_str());
  601. //M
  602. //地球椭球面相对大地水准面的高度
  603. m_fEarthHigh = atof(vecValue[11].c_str());
  604. //M
  605. //差分时间
  606. m_uiDiffTime = atol(vecValue[13].c_str());
  607. //差分站ID号、校验
  608. std::vector<std::string> vecDiffIno;
  609. StringSplit(vecDiffIno, vecValue[14].c_str(), "*");
  610. if (vecDiffIno.size() >= 2)
  611. {
  612. m_usDiffSiteId = atoi(vecDiffIno[0].c_str());
  613. char *stop = NULL;
  614. m_ucChecksum = strtol(vecDiffIno[1].c_str(), &stop, 16);
  615. }
  616. //计算校验和比对
  617. if (bIsCompareChecksum)
  618. {
  619. char *pFindStarChar = strrchr(pInputString, '*');
  620. if (pFindStarChar != NULL)
  621. {
  622. unsigned char ucTempChecksum = 0;
  623. ucTempChecksum = CalcChecksum((unsigned char *)pInputString, pFindStarChar - pInputString + 1);
  624. if (ucTempChecksum == m_ucChecksum)
  625. {
  626. bRet = true;
  627. }
  628. }
  629. }
  630. else
  631. {
  632. bRet = true;
  633. }
  634. return bRet;
  635. }
  636. //生成GPGGA字符串
  637. bool GpsNmeaData::CreateGPGGAString(char *pOutputString, int & nOutputStringSize, bool bIsHasEndFlag)
  638. {
  639. //$GPGGA,025620.00,2602.33721,N,11911.49176,E,2,04,1.63,13.5,M,9.9,M,,0000*5D
  640. bool bRet = true;
  641. //memset(pOutputString, 0, nOutputStringSize);
  642. //纬度
  643. double fLatMD = degree_to_dm(m_fLat);
  644. //经度
  645. double fLngMD = degree_to_dm(m_fLng);
  646. //m_ucStatus 0=未定位,1=非差分定位,2=差分定位,6=正在估算
  647. if (m_ucStatus == '0')
  648. {
  649. //数据无效
  650. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,,,,,%c,,,,M,,M,,0000*",
  651. GpsNmeaData_Gpgga_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond, m_ucStatus);
  652. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  653. char szChecksum[4] = { 0 };
  654. sprintf_s(szChecksum, "%02X", ucChecksum);
  655. strcat(pOutputString, szChecksum);
  656. if (bIsHasEndFlag)
  657. {
  658. //是否带结束标记符号,0x0d0x0a
  659. char szEndFlag[4] = { 0 };
  660. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  661. strcat(pOutputString, szEndFlag);
  662. }
  663. nOutputStringSize = strlen(pOutputString);
  664. }
  665. else
  666. {
  667. //数据有效
  668. if (m_ucStatus == '2')
  669. {
  670. //差分定位
  671. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%.4f,%c,%.4f,%c,%c,%02d,%.1f,%.1f,M,%.1f,M,%u,%04d*",
  672. GpsNmeaData_Gpgga_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond,
  673. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, m_ucStatus,
  674. m_ucSatelliteNum,m_fHDOP,m_fHigh,m_fEarthHigh,m_uiDiffTime,m_usDiffSiteId);
  675. }
  676. else if (m_ucStatus == '1')
  677. {
  678. //非差分定位
  679. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%.4f,%c,%.4f,%c,%c,%02d,%.1f,%.1f,M,%.1f,M,,0000d*",
  680. GpsNmeaData_Gpgga_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond,
  681. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, m_ucStatus,
  682. m_ucSatelliteNum, m_fHDOP, m_fHigh, m_fEarthHigh);
  683. }
  684. else
  685. {
  686. sprintf_s(pOutputString, nOutputStringSize - 1, "%s,%02d%02d%02d.%03d,%.4f,%c,%.4f,%c,%c,%02d,%.1f,%.1f,M,%.1f,M,,0000*",
  687. GpsNmeaData_Gpgga_Head, m_usHour, m_usMinute, m_usSecond, m_usMillsSecond,
  688. fLatMD, m_ucGpsLatDirect, fLngMD, m_ucGpsLngDirect, m_ucStatus,
  689. m_ucSatelliteNum, m_fHDOP, m_fHigh, m_fEarthHigh);
  690. }
  691. unsigned char ucChecksum = CalcChecksum((unsigned char *)pOutputString, strlen(pOutputString));
  692. char szChecksum[4] = { 0 };
  693. sprintf_s(szChecksum, "%02X", ucChecksum);
  694. strcat(pOutputString, szChecksum);
  695. if (bIsHasEndFlag)
  696. {
  697. //是否带结束标记符号,0x0d0x0a
  698. char szEndFlag[4] = { 0 };
  699. sprintf_s(szEndFlag, "%c%c", 0x0d, 0x0a);
  700. strcat(pOutputString, szEndFlag);
  701. }
  702. nOutputStringSize = strlen(pOutputString);
  703. }
  704. return bRet;
  705. }
  706. /*
  707. 功能:计算经纬度(根据速度和方向计算下一经纬度)
  708. 参数:fDirect:方向;fSpeed:速度;km/h;dOldLng:旧经度;dOldLat:旧纬度;dNewLng:新经度;dNewLat:新纬度
  709. 返回:无
  710. */
  711. void GpsNmeaData::CalcLngLat(float fDirect, float fSpeed, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat)
  712. {
  713. CalcLngLatEx(fDirect, fSpeed, dOldLng, dOldLat, dNewLng, dNewLat, 1);
  714. }
  715. /*
  716. 功能:计算经纬度(根据速度和方向计算下一经纬度)
  717. 参数:fDirect:方向;fSpeed:速度;km/h;dOldLng:旧经度;dOldLat:旧纬度;dNewLng:新经度;dNewLat:新纬度;nKeepSeconds:保持多少秒
  718. 返回:无
  719. */
  720. void GpsNmeaData::CalcLngLatEx(float fDirect, float fSpeed, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat, int nKeepSeconds)
  721. {
  722. if (nKeepSeconds < 1)
  723. {
  724. nKeepSeconds = 1;
  725. }
  726. float declie = fDirect;// 方位角
  727. float speed = fSpeed;// 速度
  728. float distance = speed * nKeepSeconds / 3600.0;//速度计算单位时间内车辆行驶距离,这里单位为千米。换算成每秒多少km,外部接口一秒发送一次gps数据
  729. float degree = distance / 111;//km
  730. float tempLat = degree * cos(declie);
  731. float tempLong = degree * sin(declie);
  732. dNewLat = dOldLat + tempLat;
  733. dNewLng = dOldLng + tempLong;
  734. }
  735. /*
  736. 功能:计算经纬度(根据距离和方向计算下一经纬度)
  737. 参数:fDirect:方向;fDistance:距离;km;dOldLng:旧经度;dOldLat:旧纬度;dNewLng:新经度;dNewLat:新纬度
  738. 返回:无
  739. */
  740. void GpsNmeaData::CalcLngLatByDistanceAndDirect(float fDirect, double fDistance, double dOldLng, double dOldLat, double & dNewLng, double & dNewLat)
  741. {
  742. double dx = fDistance * 1000 * sin(fDirect*PI / 180.0);
  743. double dy = fDistance * 1000 * cos(fDirect*PI / 180.0);
  744. double ec = Eb + (Ea - Eb) * (90 - dOldLat) / 90.0;
  745. double ed = ec * cos(dOldLat*PI / 180);
  746. dNewLng = (dx / ed + dOldLng*PI / 180.0) * 180.0 / PI;
  747. dNewLat = (dy / ec + dOldLat*PI / 180.0) * 180.0 / PI;
  748. }
  749. //计算校验和
  750. unsigned char GpsNmeaData::CalcChecksum(unsigned char *pInput, int nInputSize)
  751. {
  752. //$与*符号之间的字符进行异或
  753. unsigned char ucChecksum = 0;
  754. int i = 0;
  755. for (i = 1; i < nInputSize - 1; i++)//排除$与*符号
  756. {
  757. ucChecksum ^= pInput[i];
  758. }
  759. return ucChecksum;
  760. }
  761. //度分转换度
  762. double GpsNmeaData::dm_to_degree(double dm)
  763. {
  764. //计算度
  765. int d = (int)(dm / 100);
  766. //计算分
  767. double m = dm - d * 100;
  768. double s = d * 3600 + m * 60;
  769. double dd_dddd = s / 3600.0;
  770. return dd_dddd;
  771. }
  772. //度转换度分
  773. double GpsNmeaData::degree_to_dm(double ddd_dddd)
  774. {
  775. int d = (int)(ddd_dddd);
  776. double m = (ddd_dddd - d) * 60;
  777. double dddmm_mmmm = d * 100 + m;
  778. return dddmm_mmmm;
  779. }
  780. /*
  781. 功能:计算两点经纬度之间的距离
  782. 参数:latitude1:点1纬度值;longitude1:点1经度值;latitude2:点2纬度值;longitude2:点2经度值
  783. 返回:double,距离,单位为m
  784. */
  785. double GpsNmeaData::GpsNmeaDataDistance(double latitude1, double longitude1, double latitude2, double longitude2)
  786. {
  787. double lon1 = longitude1 * PI / 180;
  788. double lat1 = latitude1 * PI / 180;
  789. double lon2 = longitude2 * PI / 180;
  790. double lat2 = latitude2 * PI / 180;
  791. double deltaLat = lat1 - lat2;
  792. double deltaLon = lon1 - lon2;
  793. double s = 2 * asin(sqrt(pow(sin(deltaLat / 2), 2) + cos(lat1)*cos(lat2)*pow(sin(deltaLon / 2), 2)));
  794. return (s * 1000 * 6378.137);
  795. }
  1. //调用实例
  2. GpsNmeaData gndGpsNmeaData;
  3. bool bLoadGpsNmeaDataString = gndGpsNmeaData.LoadGPSString("$GNRMC,230142.00,A,2237.10770,N,11408.06877,E,11.002,218.24,310518,,,A,V*3A");
  4. if(bLoadGpsNmeaDataString)
  5. {
  6. char szOutputGPRMC[128] = { 0 };
  7. int nOutputGPRMCSize = 128;
  8. bool bCreateGPRMCString = false;
  9. float fDirect = 0;
  10. double fLngPrev = 0, fLatPrev = 0;
  11. unsigned char ucLngPrevDirect = 0, ucLatPrevDirect = 0;
  12. double fNewLng = 0, fNewLat = 0;
  13. //获取经纬度等信息
  14. gndGpsNmeaData.GetLng(fLngPrev, ucLngPrevDirect);
  15. gndGpsNmeaData.GetLat(fLatPrev, ucLatPrevDirect);
  16. //计算
  17. gndGpsNmeaData.CalcLngLatByDistanceAndDirect(fDirect, 30, fLngPrev, fLatPrev, fNewLng, fNewLat);
  18. //保存经纬度等信息
  19. gndGpsNmeaData.SetLng(fNewLng, ucLngPrevDirect);
  20. gndGpsNmeaData.SetLat(fNewLat, ucLatPrevDirect);
  21. gndGpsNmeaData.SetNowTime();
  22. nOutputGPRMCSize = 128;
  23. memset(szOutputGPRMC, 0, sizeof(szOutputGPRMC));
  24. bCreateGPRMCString = m_ggdGpsGprmcData.CreateGPSString(szOutputGPRMC, nOutputGPRMCSize, true);
  25. }

 

posted @ 2023-07-20 18:13  SymPny  阅读(762)  评论(0编辑  收藏  举报