NMEA数据转Google Earth的KML工具

1. 背景

在关于GPS定位的研究分析过程中,经常想要看在一段测试路径上,GPS的定位准确性如何,实际上,很自然的会想到把GPS数据显示在地图上,然而,并且,Google提供的Google Earth就是一个不错的工具,至于为什么不选择别的地图工具,是因为别的地图需要进行WGS84坐标系进行转换。

2. 实现代码

2.1 NMEA格式数据转化为KML的头文件

 
  1. #ifndef CONVERT_H

  2. #define CONVERT_H

  3. #include <iostream>

  4. #include <string>

  5. #include <vector>

  6. #include <fstream>

  7. #include <memory.h>

  8. #include <math.h>

  9. #include <sstream>

  10. #include <string.h>

  11. using namespace std;

  12.  
  13. // 模块名称: convert

  14. // Author: HSW

  15. // Date: 2018-01-17

  16. // 功能: 实现NMEA GGA数据分析

  17. //

  18. //

  19.  
  20. // NMEA GGA 数据分析

  21. int splitString1(string lineBuf, vector<string>& subStrs, char dim = ',');

  22.  
  23.  
  24. // ddmm.mmmm <==> dd.dddd

  25. int fromDMToDegree(double ddmmPointMMMM, double& ddPointDDDD);

  26. int fromDegreeToDM(double ddPointDDDD, double& ddmmPointMMMM);

  27.  
  28. // KML: 保存为KML文件

  29. // strs: 分别包含: 描述

  30. // 名称

  31. // 经度

  32. // 纬度

  33. // 高度

  34. int convertToKMLWithoutName(vector<string>& pointInfo, ofstream* pOfstr, int Mode);

  35.  
  36. #endif // CONVERT_H

 
  1. #include "convert.h"

  2. #include <windows.h>

  3. #include <ctmstrconvert.h>

  4.  
  5. static wstring kml_S = L"<kml xmlns=\"http://earth.google.com/kml/2.0\">\r\n";

  6.  
  7. static wstring kmlFolder_S = L"<Folder>\r\n";

  8.  
  9. static wstring kmlPlacemark_S = L"<Placemark>";

  10.  
  11. static wstring kmlDescription_S = L"<description>";

  12. static wstring kmlDescription_E = L"</description>";

  13.  
  14. static wstring kmlName_S = L"<name>";

  15. static wstring kmlName_E = L"</name>";

  16.  
  17. static wstring kmlLookat_S = L"<LookAt>";

  18.  
  19. static wstring kmlLon_S = L"<longitude>";

  20. static wstring kmlLon_E = L"</longitude>";

  21.  
  22. static wstring kmlLat_S = L"<latitude>";

  23. static wstring kmlLat_E = L"</latitude>";

  24.  
  25. static wstring kmlRange_S = L"<range>";

  26. static wstring kmlRange_E = L"</range>";

  27.  
  28. static wstring kmlTilt_S = L"<tilt>";

  29. static wstring kmlTilt_E = L"</tilt>";

  30.  
  31. static wstring kmlHeading_S = L"<heading>";

  32. static wstring kmlHeading_E = L"</heading>";

  33.  
  34. static wstring kmlLookat_E = L"</LookAt>";

  35.  
  36. static wstring kmlPoint_S = L"<Point>";

  37.  
  38. static wstring kmlCoordinates_S = L"<coordinates>";

  39. static wstring kmlCoordinates_E = L"</coordinates>";

  40.  
  41. static wstring kmlPoint_E = L"</Point>";

  42.  
  43. static wstring kmlPlacemark_E = L"</Placemark>\r\n";

  44.  
  45. static wstring kmlFolder_E = L"</Folder>\r\n";

  46.  
  47. static wstring kml_E = L"</kml>\r\n";

  48.  
  49. static wstring kml_default_range = L"20000";

  50. static wstring kml_default_tilt = L"0";

  51. static wstring kml_default_heading = L"3";

  52. static string kml_default_altitude = "0";

  53. static wstring kml_default_pointSetName = L"Positions";

  54.  
  55. // 实现差分前后的数据处理

  56. //

  57. static char exampleGGA[4][128] = {"$GPGGA,062926.000,4538.7429,N,12639.4155,E,2,08,1.0,196.6,M,0.0,M,23,1544*6C",

  58. "$GPGGA,062926.000,4538.7429,N,12639.4155,W,2,08,1.0,196.6,M,0.0,M,23,1544*6C",

  59. "$GPGGA,062926.000,4538.7429,S,12639.4155,E,2,08,1.0,196.6,M,0.0,M,23,1544*6C",

  60. "$GPGGA,062926.000,4538.7429,N,12639.4155,W,2,08,1.0,196.6,M,0.0,M,23,1544*6C"};

  61.  
  62. // 将std::string 转为 利用UTF-8编码的std::string

  63. // step1: 将std::string 转为 std::wstring

  64. // 方法1:

  65. BOOL StringToWString(const std::string &str,std::wstring &wstr)

  66. {

  67. int nLen = (int)str.length();

  68. wstr.resize(nLen,L' ');

  69.  
  70. int nResult = MultiByteToWideChar(CP_ACP,0,(LPCSTR)str.c_str(),nLen,(LPWSTR)wstr.c_str(),nLen);

  71.  
  72. if (nResult == 0)

  73. {

  74. return FALSE;

  75. }

  76.  
  77. return TRUE;

  78. }

  79. //wstring高字节不为0,返回FALSE

  80. BOOL WStringToString(const std::wstring &wstr,std::string &str)

  81. {

  82. int nLen = (int)wstr.length();

  83. str.resize(nLen,' ');

  84.  
  85. int nResult = WideCharToMultiByte(CP_ACP,0,(LPCWSTR)wstr.c_str(),nLen,(LPSTR)str.c_str(),nLen,NULL,NULL);

  86.  
  87. if (nResult == 0)

  88. {

  89. return FALSE;

  90. }

  91.  
  92. return TRUE;

  93. }

  94.  
  95. std::string to_utf8(const wchar_t* buffer, int len)

  96. {

  97. int nChars = ::WideCharToMultiByte(

  98. CP_UTF8,

  99. 0,

  100. buffer,

  101. len,

  102. NULL,

  103. 0,

  104. NULL,

  105. NULL);

  106. if (nChars == 0) return "";

  107.  
  108. string newbuffer;

  109. newbuffer.resize(nChars) ;

  110. ::WideCharToMultiByte(

  111. CP_UTF8,

  112. 0,

  113. buffer,

  114. len,

  115. const_cast< char* >(newbuffer.c_str()),

  116. nChars,

  117. NULL,

  118. NULL);

  119.  
  120. return newbuffer;

  121. }

  122.  
  123. // std::string 转为 std::string UTF-8

  124. std::string to_utf8(const std::wstring& str)

  125. {

  126. return to_utf8(str.c_str(), (int)str.size());

  127. }

  128.  
  129.  
  130. // NMEA GGA 数据分析

  131. int splitString1(string lineBuf, vector<string>& subStrs, char dim)

  132. {

  133. size_t startPos = lineBuf.find('$');

  134. size_t endPos = lineBuf.find('*');

  135. int iter;

  136. int count = 0;

  137. char subStr[64] = {0};

  138. int findGGA = 0;

  139. if(startPos != string::npos && endPos != string::npos)

  140. {

  141. for(iter = startPos + 1; iter < endPos; ++iter)

  142. {

  143. char ch = lineBuf.at(iter);

  144. if(ch == dim)

  145. {

  146. string tmp = string(subStr);

  147. if(tmp.find("GGA") != string::npos)

  148. {

  149. findGGA = 1;

  150. }

  151. subStrs.push_back(string(subStr));

  152. memset(subStr,0, sizeof(subStr));

  153. count = 0;

  154. }

  155. else

  156. {

  157. subStr[count] = lineBuf.at(iter);

  158. count++;

  159. }

  160. }

  161. subStrs.push_back(string(subStr));

  162. }

  163. if(findGGA)

  164. {

  165. return 0;

  166. }

  167. else

  168. {

  169. return -1;

  170. }

  171. }

  172.  
  173. // DD.DDDD ==> ddmm.mmmm

  174. int fromDegreeToDM(double ddPointDDDD, double& ddmmPointMMMM)

  175. {

  176. int tmpInt = (int)floor(ddPointDDDD);

  177. double tmpFloat = ddPointDDDD - tmpInt;

  178. ddmmPointMMMM = tmpInt * 100 + tmpFloat * 60;

  179. return 0;

  180. }

  181.  
  182. // ddmm.mmmm ==> DD.DDDD

  183. int fromDMToDegree(double ddmmPointMMMM, double& ddPointDDDD)

  184. {

  185. int tmpInt = floor(ddmmPointMMMM / 100);

  186. double tmpFloat = ddmmPointMMMM - tmpInt * 100;

  187. ddPointDDDD = tmpInt + tmpFloat / 60;

  188. return 0;

  189. }

  190.  
  191. // nmea 计算检查和

  192. unsigned char checkSum(const char* buf)

  193. {

  194. int isStart = 0;

  195. int iter = 0;

  196. unsigned char checksum = 0;

  197. while(1)

  198. {

  199. if((unsigned char)buf[iter] == '$')

  200. {

  201. isStart = 1;

  202. ++iter;

  203. continue;

  204. }

  205. if(isStart)

  206. {

  207. if((unsigned char)buf[iter] == '*')

  208. {

  209. break;

  210. }

  211. checksum ^= buf[iter];

  212. }

  213. ++iter;

  214. }

  215. // cout << "checksum = " << checksum << endl;

  216. return checksum;

  217. }

  218.  
  219. // KML: 保存为KML文件, 不包含点的名称

  220. // strs: 分别包含: 描述

  221. // 经度

  222. // 纬度

  223. // 注意:坐标点的高度默认设置为0

  224. int convertToKMLWithoutName(vector<string>& pointInfo, ofstream* pOfstr, int Mode)

  225. {

  226. wstring utf8wStr = L""; // 宽字符

  227. string utf8Str = ""; // UTF-8字符串

  228. if(Mode == 0)

  229. {

  230. utf8Str = to_utf8(kml_S);

  231. // pOfstr->write(kml_S.c_str(), kml_S.length());

  232. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  233. utf8Str.clear();

  234.  
  235. utf8Str = to_utf8(kmlFolder_S);

  236. // pOfstr->write(kmlFolder_S.c_str(), kmlFolder_S.length());

  237. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  238. utf8Str.clear();

  239.  
  240. // 名称: kml文件的名称

  241. utf8Str = to_utf8(kmlName_S);

  242. //pOfstr->write(kmlName_S.c_str(), kmlName_S.length());

  243. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  244. utf8Str.clear();

  245.  
  246. StringToWString(pointInfo[0], utf8wStr);

  247. utf8Str = to_utf8(utf8wStr);

  248. //pOfstr->write(pointInfo[0].c_str(), pointInfo[0].length());

  249. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  250. utf8Str.clear();

  251. utf8wStr.clear();

  252.  
  253. utf8Str = to_utf8(kmlName_E);

  254. // pOfstr->write(kmlName_E.c_str(), kmlName_E.length());

  255. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  256. utf8Str.clear();

  257.  
  258.  
  259. // 点集合名称: kml

  260. // 点集合名称: kml

  261. string outputPath = pointInfo[0];

  262. size_t pos = outputPath.find_last_of('/');

  263. if(pos != string::npos)

  264. {

  265. utf8Str = to_utf8(kmlName_S);

  266. //pOfstr->write(kmlName_S.c_str(), kmlName_S.length());

  267. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  268. utf8Str.clear();

  269.  
  270. // utf8Str = to_utf8(kml_default_pointSetName);

  271. //pOfstr->write(kml_default_pointSetName.c_str(), kml_default_pointSetName.length());

  272.  
  273. CTMStrConvert converter;

  274. wstring wPointsetName = converter.StringToWString(outputPath.substr(pos + 1, outputPath.length() - pos -1));

  275. utf8Str = converter.WStringToUtf8(wPointsetName);

  276.  
  277. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  278. utf8Str.clear();

  279. utf8wStr.clear();

  280.  
  281. utf8Str = to_utf8(kmlName_E);

  282. // pOfstr->write(kmlName_E.c_str(), kmlName_E.length());

  283. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  284. utf8Str.clear();

  285. }

  286. else

  287. {

  288. utf8Str = to_utf8(kmlName_S);

  289. //pOfstr->write(kmlName_S.c_str(), kmlName_S.length());

  290. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  291. utf8Str.clear();

  292.  
  293. utf8Str = to_utf8(kml_default_pointSetName);

  294. //pOfstr->write(kml_default_pointSetName.c_str(), kml_default_pointSetName.length());

  295. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  296. utf8Str.clear();

  297. utf8wStr.clear();

  298.  
  299. utf8Str = to_utf8(kmlName_E);

  300. // pOfstr->write(kmlName_E.c_str(), kmlName_E.length());

  301. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  302. utf8Str.clear();

  303. }

  304.  
  305. wstring lineBuf = L"\r\n";

  306. utf8Str = to_utf8(lineBuf);

  307. // pOfstr->write(lineBuf.c_str(), lineBuf.length());

  308. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  309. utf8Str.clear();

  310.  
  311. }

  312. else if(Mode == 1)

  313. {

  314. // Placemark

  315. utf8Str = to_utf8(kmlPlacemark_S);

  316. // pOfstr->write(kmlPlacemark_S.c_str(), kmlPlacemark_S.length());

  317. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  318. utf8Str.clear();

  319.  
  320. // -描述

  321. utf8Str = to_utf8(kmlDescription_S);

  322. // pOfstr->write(kmlDescription_S.c_str(), kmlDescription_S.length());

  323. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  324. utf8Str.clear();

  325.  
  326. StringToWString(pointInfo[0], utf8wStr);

  327. utf8Str = to_utf8(utf8wStr);

  328. // pOfstr->write(pointInfo[0].c_str(), pointInfo[0].length());

  329. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  330. utf8Str.clear();

  331. utf8wStr.clear();

  332.  
  333. utf8Str = to_utf8(kmlDescription_E);

  334. // pOfstr->write(kmlDescription_E.c_str(), kmlDescription_E.length());

  335. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  336. utf8Str.clear();

  337. #if 0

  338. // -名称

  339. utf8Str = to_utf8(kmlName_S);

  340. //pOfstr->write(kmlName_S.c_str(), kmlName_S.length());

  341. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  342. utf8Str.clear();

  343.  
  344. StringToWString(pointInfo[1], utf8wStr);

  345. utf8Str = to_utf8(utf8wStr);

  346. // pOfstr->write(pointInfo[1].c_str(), pointInfo[1].length());

  347. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  348. utf8Str.clear();

  349. utf8wStr.clear();

  350.  
  351. utf8Str = to_utf8(kmlName_E);

  352. // pOfstr->write(kmlName_E.c_str(), kmlName_E.length());

  353. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  354. utf8Str.clear();

  355. #endif

  356. // -LookAt

  357. utf8Str = to_utf8(kmlLookat_S);

  358. // pOfstr->write(kmlLookat_S.c_str(), kmlLookat_S.length());

  359. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  360. utf8Str.clear();

  361.  
  362. // --lon 经度

  363. utf8Str = to_utf8(kmlLon_S);

  364. // pOfstr->write(kmlLon_S.c_str(), kmlLon_S.length());

  365. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  366. utf8Str.clear();

  367.  
  368. StringToWString(pointInfo[1], utf8wStr);

  369. utf8Str = to_utf8(utf8wStr);

  370. // pOfstr->write(pointInfo[2].c_str(), pointInfo[2].length());

  371. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  372. utf8Str.clear();

  373. utf8wStr.clear();

  374.  
  375. utf8Str = to_utf8(kmlLon_E);

  376. // pOfstr->write(kmlLon_E.c_str(), kmlLon_E.length());

  377. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  378. utf8Str.clear();

  379.  
  380. // --lat 纬度

  381. utf8Str = to_utf8(kmlLat_S);

  382. // pOfstr->write(kmlLat_S.c_str(), kmlLat_S.length());

  383. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  384. utf8Str.clear();

  385.  
  386. StringToWString(pointInfo[2], utf8wStr);

  387. utf8Str = to_utf8(utf8wStr);

  388. // pOfstr->write(pointInfo[3].c_str(), pointInfo[3].length());

  389. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  390. utf8Str.clear();

  391. utf8wStr.clear();

  392.  
  393. utf8Str = to_utf8(kmlLat_E);

  394. // pOfstr->write(kmlLat_E.c_str(), kmlLat_E.length());

  395. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  396. utf8Str.clear();

  397.  
  398. // --range

  399. utf8Str = to_utf8(kmlRange_S);

  400. // pOfstr->write(kmlRange_S.c_str(), kmlRange_S.length());

  401. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  402. utf8Str.clear();

  403.  
  404. utf8Str = to_utf8(kml_default_range);

  405. // pOfstr->write(kml_default_range.c_str(), kml_default_range.length());

  406. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  407. utf8Str.clear();

  408. utf8wStr.clear();

  409.  
  410. utf8Str = to_utf8(kmlRange_E);

  411. // pOfstr->write(kmlRange_E.c_str(), kmlRange_E.length());

  412. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  413. utf8Str.clear();

  414.  
  415. // --tilt

  416. utf8Str = to_utf8(kmlTilt_S);

  417. // pOfstr->write(kmlTilt_S.c_str(), kmlTilt_S.length());

  418. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  419. utf8Str.clear();

  420.  
  421. utf8Str = to_utf8(kml_default_tilt);

  422. // pOfstr->write(kml_default_tilt.c_str(), kml_default_tilt.length());

  423. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  424. utf8Str.clear();

  425. utf8wStr.clear();

  426.  
  427. utf8Str = to_utf8(kmlTilt_E);

  428. // pOfstr->write(kmlTilt_E.c_str(), kmlTilt_E.length());

  429. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  430. utf8Str.clear();

  431.  
  432. // --heading

  433. utf8Str = to_utf8(kmlHeading_S);

  434. // pOfstr->write(kmlHeading_S.c_str(), kmlHeading_S.length());

  435. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  436. utf8Str.clear();

  437.  
  438. utf8Str = to_utf8(kml_default_heading);

  439. // pOfstr->write(kml_default_heading.c_str(), kml_default_heading.length());

  440. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  441. utf8Str.clear();

  442. utf8wStr.clear();

  443.  
  444. utf8Str = to_utf8(kmlHeading_E);

  445. // pOfstr->write(kmlHeading_E.c_str(), kmlHeading_E.length());

  446. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  447. utf8Str.clear();

  448.  
  449. // -LookAt

  450. utf8Str = to_utf8(kmlLookat_E);

  451. // pOfstr->write(kmlLookat_E.c_str(), kmlLookat_E.length());

  452. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  453. utf8Str.clear();

  454.  
  455. // -Point

  456. utf8Str = to_utf8(kmlPoint_S);

  457. // pOfstr->write(kmlPoint_S.c_str(), kmlPoint_S.length());

  458. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  459. utf8Str.clear();

  460.  
  461. // --coordinate

  462. utf8Str = to_utf8(kmlCoordinates_S);

  463. // pOfstr->write(kmlCoordinates_S.c_str(), kmlCoordinates_S.length());

  464. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  465. utf8Str.clear();

  466.  
  467. string coordinate = pointInfo[1] + "," + pointInfo[2] + "," + kml_default_altitude;

  468. StringToWString(coordinate, utf8wStr);

  469. utf8Str = to_utf8(utf8wStr);

  470. // pOfstr->write(coordinate.c_str(), coordinate.length());

  471. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  472. utf8Str.clear();

  473. utf8wStr.clear();

  474.  
  475. // --coordinate

  476. utf8Str = to_utf8(kmlCoordinates_E);

  477. // pOfstr->write(kmlCoordinates_E.c_str(), kmlCoordinates_E.length());

  478. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  479. utf8Str.clear();

  480.  
  481. // -Point

  482. utf8Str = to_utf8(kmlPoint_E);

  483. // pOfstr->write(kmlPoint_E.c_str(), kmlPoint_E.length());

  484. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  485. utf8Str.clear();

  486.  
  487. // Placemark

  488. utf8Str = to_utf8(kmlPlacemark_E);

  489. // pOfstr->write(kmlPlacemark_E.c_str(), kmlPlacemark_E.length());

  490. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  491. utf8Str.clear();

  492.  
  493. }

  494. else if(Mode == 2)

  495. {

  496. utf8Str = to_utf8(kmlFolder_E);

  497. // pOfstr->write(kmlFolder_E.c_str(), kmlFolder_E.length());

  498. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  499. utf8Str.clear();

  500.  
  501. utf8Str = to_utf8(kml_E);

  502. // pOfstr->write(kml_E.c_str(), kml_E.length());

  503. pOfstr->write(utf8Str.c_str(), utf8Str.length());

  504. utf8Str.clear();

  505. }

  506. pOfstr->flush();

  507. return 0;

  508. }

 

2.2 ASCII字符集和UTF-8字符集转换类

 
  1. #ifndef CTMSTRCONVERT_H

  2. #define CTMSTRCONVERT_H

  3. #include <windows.h>

  4. #include <iostream>

  5. #include <string>

  6. #include <wchar.h>

  7.  
  8. using namespace std;

  9.  
  10. // 模块名称:windows中字符串转换类

  11. // Author: HSW

  12. // Date: 2018-01-30

  13. // 功能: 实现多字节字符串与宽字节字符串之间的转换

  14. // 多字节集合: ASCII / UTF8 等, 一般情况下,ASCII为常用的字符串;UTF8主要在网页

  15. // 宽字节集合: 表示汉字等需要使用宽字节

  16.  
  17. class CTMStrConvert

  18. {

  19. public:

  20. CTMStrConvert();

  21. ~CTMStrConvert();

  22. public:

  23. wstring StringToWString(const char* abuffer, const int nLen);

  24. wstring StringToWString(const string &astr);

  25. wstring Utf8ToWString(const char* ubuffer, int nLen);

  26. wstring Utf8ToWString(const string ustr);

  27. string WStringToString(const wchar_t* wbuffer, const int nLen);

  28. string WStringToString(const wstring &wstr);

  29. string WStringToUtf8(const wchar_t* wbuffer, int nLen);

  30. string WStringToUtf8(const wstring& wstr);

  31. string StringToUtf8(const string &astr);

  32. string StringToUtf8(const char* abuffer, const int nLen);

  33. string Utf8ToString(const string ustr);

  34. string Utf8ToString(const char* ubuffer, const int nLen);

  35. };

  36.  
  37. #endif // CTMSTRCONVERT_H

 

 
  1. #include "ctmstrconvert.h"

  2.  
  3. CTMStrConvert::CTMStrConvert()

  4. {

  5.  
  6. }

  7.  
  8. CTMStrConvert::~CTMStrConvert()

  9. {

  10.  
  11. }

  12.  
  13.  
  14.  
  15. // 功能: 多字节(ASCII)字符串转宽字节字符串

  16. // aBuffer: ASCII的多字节字符数组

  17. // nLen: ASCII的多字节数组长度

  18. // 返回: 成功返回包含内容的字符串,失败返回空串

  19. // 日期: 2018-01-30

  20. // 修改记录:

  21. //

  22. wstring CTMStrConvert::StringToWString(const char* abuffer, const int nLen)

  23. {

  24. // 需要的缓冲区大小

  25. int nResult = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)abuffer, nLen, NULL, 0);

  26.  
  27. if (nResult == 0)

  28. {

  29. cout << "Get Wide Char Buffer Size Failed " << endl;

  30. return L"";

  31. }

  32.  
  33. wstring wstr;

  34. wstr.resize(nResult, L' ');

  35. nResult = MultiByteToWideChar(CP_ACP, 0, (LPCSTR)abuffer, nLen, (LPWSTR)wstr.c_str(), nResult);

  36.  
  37. if(nResult == 0)

  38. {

  39. cout << "From MultiByte To Wide Char Translate Failed " << endl;

  40. return L"";

  41. }

  42. else

  43. {

  44. return wstr;

  45. }

  46. }

  47.  
  48. // 功能: 多字节(ASCII)字符串转宽字节字符串

  49. // astr: ASCII的多字节字符串

  50. // 返回: 成功返回包含内容的字符串,失败返回空串

  51. // 日期: 2018-01-30

  52. // 修改记录:

  53. //

  54. wstring CTMStrConvert::StringToWString(const string &astr)

  55. {

  56. return StringToWString(astr.c_str(), astr.length());

  57. }

  58.  
  59.  
  60. // 功能: 宽字节字符数组转为多字节(ASCII)字符串

  61. // wbuffer: ASCII的多字节字符串

  62. // len: 宽字节字符串

  63. // 返回: 成功返回包含内容的字符串,失败返回空串

  64. // 日期: 2018-01-30

  65. // 修改记录:

  66. //

  67. string CTMStrConvert::WStringToString(const wchar_t* wbuffer, const int nLen)

  68. {

  69. // 获取需要的缓冲区的大小

  70. int nResult = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wbuffer, nLen, NULL, 0, NULL, NULL);

  71.  
  72. if (nResult == 0)

  73. {

  74. cout << "Get Multi Byte Buffer Size Failed " << endl;

  75. return "";

  76. }

  77.  
  78. string astr;

  79. astr.resize(nResult, ' ');

  80. nResult = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)wbuffer, nLen, (LPSTR)astr.c_str(), nResult, NULL, NULL);

  81.  
  82. if (nResult == 0)

  83. {

  84. cout << "From Wide Char To Multi Byte Translate Failed " << endl;

  85. return "";

  86. }

  87. else

  88. {

  89. return astr;

  90. }

  91. }

  92.  
  93.  
  94. // 功能: 宽字节字符串转为多字节(ASCII)字符串

  95. // wstr: 宽字节字符串

  96. // 返回: 成功返回包含内容的字符串,失败返回空串

  97. // 日期: 2018-01-30

  98. // 修改记录:

  99. //

  100. string CTMStrConvert::WStringToString(const wstring &wstr)

  101. {

  102. return WStringToString(wstr.c_str(), wstr.length());

  103. }

  104.  
  105.  
  106. // 功能: 宽字节字符数组转为UTF-8多字节字符串

  107. // wbuffer: 宽字节字符数组

  108. // nLen: 宽字节字符数组的长度

  109. // 返回值: 成功返回包含内容的字符串,失败返回空串

  110. // 日期: 2018-01-30

  111. // 修改记录:

  112. //

  113. string CTMStrConvert::WStringToUtf8(const wchar_t* wbuffer, int nLen)

  114. {

  115. // 获取所需的缓冲区大小

  116. int nResult = WideCharToMultiByte(CP_UTF8, 0, wbuffer, nLen, NULL, 0, NULL, NULL);

  117. if (nResult == 0)

  118. {

  119. cout << "Get Multi Byte Buffer Size Failed " << endl;

  120. return "";

  121. }

  122.  
  123. string ustr;

  124. ustr.resize(nResult, ' ');

  125. nResult = WideCharToMultiByte(CP_UTF8, 0, wbuffer, nLen, const_cast< char* >(ustr.c_str()), nResult, NULL, NULL);

  126. if(nResult == 0)

  127. {

  128. cout << "Wide Char To Multi Byte Translate Failed " << endl;

  129. return "";

  130. }

  131. else

  132. {

  133. return ustr;

  134. }

  135. }

  136.  
  137. // 功能: 宽字节字符串 转为 UTF-8

  138. // wstr: 宽字节字符串

  139. // 返回值: 成功返回包含内容的字符串,失败返回空串

  140. // 日期: 2018-01-30

  141. // 修改记录:

  142. //

  143. string CTMStrConvert::WStringToUtf8(const wstring& wstr)

  144. {

  145. return WStringToUtf8(wstr.c_str(), (int)wstr.size());

  146. }

  147.  
  148. // 功能: UTF-8多字节数组 转为 宽字节字符串

  149. // ubuffer: UTF-8多字节数组

  150. // len: UTF-8多字节数组长度

  151. // 返回值: 成功返回包含内容的字符串,失败返回空串

  152. // 日期: 2018-01-30

  153. // 修改记录:

  154. //

  155. wstring CTMStrConvert::Utf8ToWString(const char* ubuffer, int nLen)

  156. {

  157. // 需要的缓冲区大小

  158. int nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)ubuffer, nLen, NULL, 0);

  159.  
  160. if (nResult == 0)

  161. {

  162. cout << "Get Wide Char Buffer Size Failed " << endl;

  163. return L"";

  164. }

  165.  
  166. wstring wstr;

  167. wstr.resize(nResult, L' ');

  168. nResult = MultiByteToWideChar(CP_UTF8, 0, (LPCSTR)ubuffer, nLen, (LPWSTR)wstr.c_str(), nResult);

  169.  
  170. if(nResult == 0)

  171. {

  172. cout << "From MultiByte To Wide Char Translate Failed " << endl;

  173. return L"";

  174. }

  175. else

  176. {

  177. return wstr;

  178. }

  179. }

  180.  
  181. // 功能: UTF-8多字节字符串 转为 宽字节字符串

  182. // ustr: UTF-8多字节字符串

  183. // 返回值: 成功返回包含内容的字符串,失败返回空串

  184. // 日期: 2018-01-30

  185. // 修改记录:

  186. wstring CTMStrConvert::Utf8ToWString(const string ustr)

  187. {

  188. return Utf8ToWString(ustr.c_str(), ustr.length());

  189. }

  190.  
  191. // 功能: 多字节(ASCII)字符串 转为 UTF-8多字节字符串

  192. // astr: 多字节(ASCII)字符串

  193. // 返回值: 成功返回包含内容的字符串,失败返回空串

  194. // 日期: 2018-03-29

  195. // 修改记录:

  196. string CTMStrConvert::StringToUtf8(const string &astr)

  197. {

  198. wstring wstr = StringToWString(astr);

  199. return WStringToUtf8(wstr);

  200. }

  201.  
  202. // 功能: 多字节(ASCII)字符串 转为 UTF-8多字节字符串

  203. // abuffer: 多字节(ASCII)字符串

  204. // 返回值: 成功返回包含内容的字符串,失败返回空串

  205. // 日期: 2018-03-29

  206. // 修改记录:

  207. string CTMStrConvert::StringToUtf8(const char* abuffer, const int nLen)

  208. {

  209. wstring wstr = StringToWString(abuffer, nLen);

  210. return WStringToUtf8(wstr);

  211. }

  212.  
  213. // 功能: UTF-8多字节字符串 转为 多字节(ASCII)字符串

  214. // ustr: UTF-8多字节字符串

  215. // 返回值: 成功返回包含内容的字符串,失败返回空串

  216. // 日期: 2018-03-29

  217. // 修改记录:

  218. string CTMStrConvert::Utf8ToString(const string ustr)

  219. {

  220. wstring wstr = Utf8ToWString(ustr);

  221. return WStringToString(wstr);

  222. }

  223.  
  224. // 功能: UTF-8多字节字符串 转为 多字节(ASCII)字符串

  225. // ubuffer: UTF-8多字节字符串

  226. // 返回值: 成功返回包含内容的字符串,失败返回空串

  227. // 日期: 2018-03-29

  228. // 修改记录:

  229. string CTMStrConvert::Utf8ToString(const char* ubuffer, const int nLen)

  230. {

  231. wstring wstr = Utf8ToWString(ubuffer, nLen);

  232. return WStringToString(wstr);

  233. }

 

2.3 QT界面类

 
  1. #ifndef MAINWINDOW_H

  2. #define MAINWINDOW_H

  3.  
  4. #include <QMainWindow>

  5. #include <iostream>

  6. #include <vector>

  7. #include <string>

  8.  
  9. using namespace std;

  10.  
  11. namespace Ui {

  12. class MainWindow;

  13. }

  14.  
  15. typedef struct st_Support_Format

  16. {

  17. unsigned int supportTXT;

  18. unsigned int supportCSV;

  19. unsigned int supportRDF;

  20. }st_Support_Format;

  21.  
  22. class MainWindow : public QMainWindow

  23. {

  24. Q_OBJECT

  25.  
  26. public:

  27. explicit MainWindow(QWidget *parent = 0);

  28. ~MainWindow();

  29. private:

  30. void initialWindows();

  31. int getFilePaths();

  32. private slots:

  33. void auto_slot();

  34. void split_slot();

  35.  
  36. void batch_slot();

  37. void support_txt_slot();

  38. void support_csv_slot();

  39.  
  40. void openfile_slot();

  41. void nmea_slot();

  42. private:

  43. Ui::MainWindow* ui;

  44. unsigned int m_isAuto; // 是否通过Google自动打开

  45. unsigned int m_isSplit; // 是否对每个KML文件分开显示

  46. unsigned int m_isBatch; // 是否批处理

  47. string m_googleEarthPath; // google Earth 的路径

  48. string m_firstPath; // 选择的文件路径

  49. string m_guiFirstPath; // 用于在GUI显示选择的文件路径

  50. vector<string> m_filePaths; // 文件路径

  51. st_Support_Format m_supportFormat; // 支持的文件格式

  52. };

  53.  
  54. #endif // MAINWINDOW_H

 
  1. #include "mainwindow.h"

  2. #include "ui_mainwindow.h"

  3. #include "convert.h"

  4. #include "ctmstrconvert.h"

  5. #include <QFileDialog>

  6. #include <QDir>

  7. #include <QFile>

  8. #include <QTextCodec>

  9. #include <QMessageBox>

  10. #include <QSettings>

  11. #include <QDebug>

  12. #include <windows.h>

  13.  
  14. MainWindow::MainWindow(QWidget *parent) :

  15. QMainWindow(parent),

  16. ui(new Ui::MainWindow)

  17. {

  18. ui->setupUi(this);

  19.  
  20. // 初始化windows

  21. initialWindows();

  22.  
  23. // Connect <===> Slot

  24. connect(ui->autoCheckBox, SIGNAL(clicked(bool)), this, SLOT(auto_slot()));

  25. connect(ui->splitCheckBox, SIGNAL(clicked(bool)), this, SLOT(split_slot()));

  26.  
  27. connect(ui->batchCheckBox, SIGNAL(clicked(bool)), this, SLOT(batch_slot()));

  28. connect(ui->txtCheckBox, SIGNAL(clicked(bool)), this, SLOT(support_txt_slot()));

  29. connect(ui->csvCheckBox, SIGNAL(clicked(bool)), this, SLOT(support_csv_slot()));

  30.  
  31. connect(ui->openFilePushButton, SIGNAL(clicked(bool)), this, SLOT(openfile_slot()));

  32. connect(ui->convertNMEAPushButton, SIGNAL(clicked(bool)), this, SLOT(nmea_slot()));

  33. // 设置support Push Button 的边框

  34. ui->supportPushButton->setEnabled(false);

  35. ui->supportPushButton->setStyleSheet("border: none");

  36. }

  37.  
  38. MainWindow::~MainWindow()

  39. {

  40. delete ui;

  41. }

  42.  
  43.  
  44.  
  45. void MainWindow::initialWindows()

  46. {

  47. if(ui->autoCheckBox->isChecked())

  48. {

  49. m_isAuto = 1;

  50. ui->splitCheckBox->setEnabled(true);

  51. }

  52. else

  53. {

  54. m_isAuto = 0;

  55. ui->splitCheckBox->setEnabled(false);

  56. }

  57.  
  58. if(ui->splitCheckBox->isChecked())

  59. {

  60. m_isSplit = 1;

  61. }

  62. else

  63. {

  64. m_isSplit = 0;

  65. }

  66.  
  67. if(ui->batchCheckBox->isChecked())

  68. {

  69. m_isBatch = 1;

  70. ui->txtCheckBox->setEnabled(true);

  71. ui->csvCheckBox->setEnabled(true);

  72. }

  73. else

  74. {

  75. m_isBatch = 0;

  76. ui->txtCheckBox->setEnabled(false);

  77. ui->csvCheckBox->setEnabled(false);

  78. }

  79.  
  80. m_firstPath = ""; // 初始化为空

  81. m_filePaths.clear();

  82.  
  83. QPixmap imagePix;

  84. imagePix.load("gpsImage.jpg"); // 加载

  85. ui->tmLabel->setScaledContents(true); // 设置自适应

  86. ui->tmLabel->clear(); // 清空

  87. ui->tmLabel->setPixmap(imagePix); // 加载到Label标签

  88. ui->tmLabel->show(); // 显示

  89. }

  90.  
  91. void MainWindow::auto_slot()

  92. {

  93. if(ui->autoCheckBox->isChecked())

  94. {

  95. m_isAuto = 1;

  96. ui->splitCheckBox->setEnabled(true);

  97. // Check Google Earth

  98. QSettings *configIniRead = new QSettings("TM_Google_Earth.ini", QSettings::IniFormat);

  99. QString googleEarthPath = configIniRead->value("/Path/googleEarthPath").toString();

  100. // qDebug() << googleEarthPath;

  101. if(googleEarthPath.isEmpty())

  102. {

  103. // 释放文件

  104. configIniRead->deleteLater();

  105.  
  106. // 弹出选择google Earth 的路径

  107. QMessageBox Msg(QMessageBox::Question,

  108. QString(tr("配置GoogleEarth")),

  109. QString(tr("选择GoogleEarth路径(例如:C:\\Program Files (x86)\\Google\\Google Earth\\client\\googleearth.exe)")));

  110. QAbstractButton *pYesBtn = (QAbstractButton *)Msg.addButton(QString(tr("是")), QMessageBox::YesRole);

  111. QAbstractButton *pNoBtn = (QAbstractButton *)Msg.addButton(QString(tr("否")), QMessageBox::NoRole);

  112. Msg.exec();

  113.  
  114. if (Msg.clickedButton() != pYesBtn)

  115. {

  116. m_isAuto = 0;

  117. ui->autoCheckBox->setChecked(false);

  118. ui->splitCheckBox->setEnabled(false);

  119. return ;

  120. }

  121.  
  122. // 文件选择对话框:选择Google Earth 路径

  123. QString qFilePath = QFileDialog::getOpenFileName(this, QString(tr("选择GoogleEarth路径")), "", "File(*.exe)", NULL);

  124. if(!qFilePath.isEmpty())

  125. {

  126. m_googleEarthPath = qFilePath.toStdString();

  127.  
  128. QSettings *configIniWrite = new QSettings("TM_Google_Earth.ini", QSettings::IniFormat);

  129. //向ini文件中写入内容,setValue函数的两个参数是键值对

  130. configIniWrite->setValue("/Path/googleEarthPath", qFilePath);

  131. configIniWrite->deleteLater();

  132. }

  133. else

  134. {

  135. QMessageBox Msg(QMessageBox::Question,

  136. QString(tr("配置GoogleEarth")),

  137. QString(tr("设置Google Earth 路径失败!")));

  138.  
  139. Msg.exec();

  140. m_isAuto = 0;

  141. ui->splitCheckBox->setEnabled(false);

  142. }

  143. }

  144. else

  145. {

  146. m_googleEarthPath = googleEarthPath.toStdString();

  147. configIniRead->deleteLater();

  148. }

  149. }

  150. else

  151. {

  152. m_isAuto = 0;

  153. ui->splitCheckBox->setEnabled(false);

  154. }// if ... else ... isChecked()

  155. }

  156.  
  157. void MainWindow::split_slot()

  158. {

  159. if(ui->splitCheckBox->isChecked())

  160. {

  161. m_isSplit = 1;

  162. }

  163. else

  164. {

  165. m_isSplit = 0;

  166. }

  167. }

  168.  
  169.  
  170. void MainWindow::batch_slot()

  171. {

  172. if(ui->batchCheckBox->isChecked())

  173. {

  174. m_isBatch = 1;

  175. ui->txtCheckBox->setEnabled(true);

  176. ui->csvCheckBox->setEnabled(true);

  177. }

  178. else

  179. {

  180. m_isBatch = 0;

  181. ui->txtCheckBox->setChecked(false);

  182. ui->csvCheckBox->setChecked(false);

  183.  
  184. ui->txtCheckBox->setEnabled(false);

  185. ui->csvCheckBox->setEnabled(false);

  186. }

  187.  
  188. if(!ui->txtCheckBox->isChecked()

  189. && !ui->csvCheckBox->isChecked())

  190. {

  191.  
  192. ui->convertNMEAPushButton->setEnabled(true);

  193. }

  194. }

  195.  
  196. void MainWindow::support_txt_slot()

  197. {

  198. if(ui->txtCheckBox->isChecked())

  199. {

  200. m_supportFormat.supportTXT = 1;

  201. ui->convertNMEAPushButton->setEnabled(true);

  202. }

  203. else

  204. {

  205. m_supportFormat.supportTXT = 0;

  206. if(!ui->txtCheckBox->isChecked()

  207. && !ui->csvCheckBox->isChecked())

  208. {

  209. ui->convertNMEAPushButton->setEnabled(true);

  210. }

  211. else if(!ui->csvCheckBox->isChecked())

  212. {

  213. ui->convertNMEAPushButton->setEnabled(false);

  214. }

  215. }

  216. }

  217.  
  218. void MainWindow::support_csv_slot()

  219. {

  220. if(ui->csvCheckBox->isChecked())

  221. {

  222. m_supportFormat.supportCSV = 1;

  223. ui->convertNMEAPushButton->setEnabled(true);

  224. }

  225. else

  226. {

  227. m_supportFormat.supportCSV = 0;

  228. if(!ui->txtCheckBox->isChecked()

  229. && !ui->csvCheckBox->isChecked())

  230. {

  231. ui->convertNMEAPushButton->setEnabled(true);

  232. }

  233. else if(!ui->txtCheckBox->isChecked())

  234. {

  235. ui->convertNMEAPushButton->setEnabled(false);

  236. }

  237. }

  238. }

  239.  
  240.  
  241. void MainWindow::openfile_slot()

  242. {

  243. if(m_isBatch)

  244. {// 批量处理

  245. QString qFileDir = QFileDialog::getExistingDirectory(this, QString(tr("选择文件夹")), "");

  246. if(!qFileDir.isEmpty())

  247. {

  248. QTextCodec *codec =QTextCodec::codecForName("UTF-8");

  249. QString str = codec->toUnicode(qFileDir.toStdString().c_str());

  250. wstring fileName = str.toStdWString();

  251. CTMStrConvert converter;

  252. m_firstPath = converter.WStringToString(fileName);

  253. m_guiFirstPath = qFileDir.toStdString();

  254. }

  255. else

  256. {

  257. m_firstPath = "";

  258. m_guiFirstPath = "";

  259. }

  260.  
  261. }

  262. else

  263. {// 处理单个文件

  264. QString qFilePath = QFileDialog::getOpenFileName(this, QString(tr("选择文件")), "", "File(*.txt *.csv)", NULL);

  265. if(!qFilePath.isEmpty())

  266. {

  267. QTextCodec *codec =QTextCodec::codecForName("UTF-8");

  268. QString str = codec->toUnicode(qFilePath.toStdString().c_str());

  269. wstring fileName = str.toStdWString();

  270. CTMStrConvert converter;

  271. m_firstPath = converter.WStringToString(fileName);

  272. m_guiFirstPath = qFilePath.toStdString();

  273. }

  274. else

  275. {

  276. m_firstPath = "";

  277. m_guiFirstPath = "";

  278. }

  279. }

  280. ui->openTextBrowser->setText(QString::fromStdString(m_guiFirstPath));

  281. }

  282.  
  283. void MainWindow::nmea_slot()

  284. {

  285. int ret;

  286. ret = getFilePaths();

  287. if(ret == 0)

  288. {

  289. vector<string> kmlPaths; // 存储输出的kml文件路径

  290. vector<string>::iterator iter;

  291. for(iter = m_filePaths.begin(); iter != m_filePaths.end(); ++iter)

  292. {

  293. ifstream ifstr(*iter, ios_base::binary | ios_base::in);

  294. string outputFilePath = (*iter) + ".kml";

  295. ofstream* pOfstr = new ofstream(outputFilePath, ios_base::out | ios_base::binary | ios_base::trunc);

  296. if(pOfstr == NULL)

  297. {

  298. QString message = QString(tr("打开(创建)输出文件(")) + QString::fromStdString(outputFilePath) + QString(tr(")失败"));

  299. QMessageBox msgBox(QMessageBox::Warning,"Information",message,QMessageBox::Yes,NULL);

  300. msgBox.exec();

  301. continue;

  302. }

  303. else if(!pOfstr->is_open())

  304. {

  305. QString message = QString(tr("打开(创建)输出文件(")) + QString::fromStdString(outputFilePath) + QString(tr(")失败"));

  306. QMessageBox msgBox(QMessageBox::Warning,"Information",message,QMessageBox::Yes,NULL);

  307. msgBox.exec();

  308. continue;

  309. }

  310.  
  311. if(ifstr.is_open())

  312. {

  313. int isFirst = 1;

  314. vector<string> kmlPointInfo;

  315. int emptyCnt = 0;

  316. char bufPos[64] = {0};

  317. while(1)

  318. {

  319. char buf[256] = {0};

  320. ifstr.getline(buf, sizeof(buf));

  321. int buflen = strlen((const char*)buf);

  322. if(buflen > 32)

  323. {

  324. vector<string> substrs;

  325. ret = splitString1(string(buf), substrs, ',');

  326. if(ret < 0)

  327. {

  328. continue;

  329. }

  330.  
  331. if(isFirst)

  332. {

  333. kmlPointInfo.clear();

  334. kmlPointInfo.push_back(outputFilePath);

  335. ret = convertToKMLWithoutName(kmlPointInfo, pOfstr, 0); //

  336. if(ret < 0)

  337. {

  338. continue;

  339. }

  340. isFirst = 0;

  341. }

  342.  
  343. if(!isFirst)

  344. {

  345. kmlPointInfo.clear();

  346. kmlPointInfo.push_back(substrs[1]); // utcTime

  347. double lonDDPointDDDD;

  348. double lonDDMMPointMMMM;

  349. stringstream sLon1(substrs[4]);

  350. sLon1 >> lonDDMMPointMMMM;

  351. fromDMToDegree(lonDDMMPointMMMM, lonDDPointDDDD);

  352. memset(bufPos, 0, sizeof(bufPos));

  353. sprintf(bufPos, "%lf", lonDDPointDDDD);

  354. kmlPointInfo.push_back(string(bufPos)); // Lon: 经度

  355. double latDDPointDDDD;

  356. double latDDMMPointMMMM;

  357. stringstream sLat1(substrs[2]);

  358. sLat1 >> latDDMMPointMMMM;

  359. fromDMToDegree(latDDMMPointMMMM, latDDPointDDDD);

  360. memset(bufPos, 0, sizeof(bufPos));

  361. sprintf(bufPos, "%lf", latDDPointDDDD);

  362. kmlPointInfo.push_back(string(bufPos)); // Lat

  363.  
  364. ret = convertToKMLWithoutName(kmlPointInfo, pOfstr, 1);

  365. if(ret < 0)

  366. {

  367. continue;

  368. }

  369. }

  370. emptyCnt = 0;

  371. continue;

  372. }

  373. else if(buflen > 0)

  374. {

  375. emptyCnt = 0;

  376. continue;

  377. }

  378. else

  379. {

  380. emptyCnt++;

  381. }

  382.  
  383. if(emptyCnt > 20)

  384. {

  385. break;

  386. }

  387. }

  388.  
  389. ret = convertToKMLWithoutName(kmlPointInfo, pOfstr, 2); // kml 文件结束

  390. ifstr.close();

  391. pOfstr->close();

  392. delete pOfstr;

  393. pOfstr = NULL;

  394. kmlPaths.push_back(outputFilePath);

  395. QMessageBox msgBox(QMessageBox::Warning,"Information",tr("处理完成"),QMessageBox::Yes,NULL);

  396. msgBox.exec();

  397. }

  398. else

  399. {

  400. QString message = QString(tr("打开文件(")) + QString::fromStdString(*iter) + QString(tr(")失败"));

  401. QMessageBox msgBox(QMessageBox::Warning,"Information",message,QMessageBox::Yes,NULL);

  402. msgBox.exec();

  403. }

  404. }//for

  405. // 利用Google Earth 自动打开

  406. if(m_isAuto)

  407. {

  408. CTMStrConvert converter;

  409. wstring googleEarthPath = converter.StringToWString(m_googleEarthPath);

  410. vector<string>::iterator iterKmlPath;

  411. if(m_isSplit)

  412. {// 每个KML文件单独显示

  413. for(iterKmlPath = kmlPaths.begin(); iterKmlPath != kmlPaths.end(); ++iterKmlPath)

  414. {

  415. string kmlPath = *iterKmlPath;

  416. wstring wkmlPath = converter.StringToWString(kmlPath);

  417. HINSTANCE ret = ShellExecute(NULL, L"open", googleEarthPath.c_str(), wkmlPath.c_str(), NULL, SW_SHOWNORMAL);

  418. if((int)ret < 32)

  419. {

  420. int errorNo = (int)ret;

  421. QString message = QString(tr("启动Google Earth 显示 KML 文件:("))

  422. + QString::fromStdString(kmlPath)

  423. + QString(tr(") 失败, Error Code: "))

  424. + QString::number(errorNo);

  425. QMessageBox msgBox(QMessageBox::Warning,"Information",message,QMessageBox::Yes,NULL);

  426. msgBox.exec();

  427. }

  428. }

  429. }

  430. else

  431. {// 全部KML文件同时显示

  432. wstring wkmlPath;

  433. for(iterKmlPath = kmlPaths.begin(); iterKmlPath != kmlPaths.end(); ++iterKmlPath)

  434. {

  435. string kmlPath = *iterKmlPath;

  436. wkmlPath += converter.StringToWString(kmlPath) + wstring(L" ");

  437.  
  438. }

  439. HINSTANCE ret = ShellExecute(NULL, L"open", googleEarthPath.c_str(), wkmlPath.c_str(), NULL, SW_SHOWNORMAL);

  440. if((int)ret < 32)

  441. {

  442. int errorNo = (int)ret;

  443. QString message = QString(tr("启动Google Earth 显示 KML 文件失败, Error Code: ")) + QString::number(errorNo);

  444. QMessageBox msgBox(QMessageBox::Warning,"Information",message,QMessageBox::Yes,NULL);

  445. msgBox.exec();

  446. }

  447. }

  448. }// if m_isAuto

  449. }// if ret

  450. }

  451.  
  452. int MainWindow::getFilePaths()

  453. {

  454. if(m_firstPath.empty())

  455. {

  456. QMessageBox msgBox(QMessageBox::Warning,"Information",tr("未选择文件(夹),请选择"),QMessageBox::Yes,NULL);

  457. msgBox.exec();

  458. return -1;

  459. }

  460. // 清空路径

  461. if(!m_filePaths.empty())

  462. {

  463. m_filePaths.clear();

  464. }

  465.  
  466. if(m_isBatch)

  467. {// 遍历文件夹

  468. QDir dir(QString::fromStdString(m_firstPath));

  469. int supportCnt = m_supportFormat.supportTXT + m_supportFormat.supportCSV + m_supportFormat.supportRDF;

  470. if(supportCnt == 0)

  471. {

  472. QMessageBox msgBox(QMessageBox::Warning,"Information",tr("文件夹中无.txt/.csv/.rdf文件格式文件,请确定"),QMessageBox::Yes,NULL);

  473. msgBox.exec();

  474. return -1;

  475. }

  476.  
  477. foreach(QFileInfo mfi ,dir.entryInfoList())

  478. {

  479. if(mfi.isFile())

  480. {

  481. QString filePath = mfi.filePath();

  482. QString fileName = mfi.fileName();

  483. string sfileName = fileName.toLower().toStdString();

  484. if(m_supportFormat.supportTXT)

  485. {

  486. if(sfileName.find(".txt") != string::npos)

  487. {

  488. QTextCodec *codec = QTextCodec::codecForName("UTF-8");

  489. QString str = codec->toUnicode(filePath.toStdString().c_str());

  490. wstring wFilePath = str.toStdWString();

  491. CTMStrConvert converter;

  492. m_filePaths.push_back(converter.WStringToString(wFilePath));

  493. // m_filePaths.push_back(filePath.toStdString());

  494. }

  495. }

  496. if(m_supportFormat.supportCSV)

  497. {

  498. if(sfileName.find(".csv") != string::npos)

  499. {

  500. QTextCodec *codec =QTextCodec::codecForName("UTF-8");

  501. QString str = codec->toUnicode(filePath.toStdString().c_str());

  502. wstring wFilePath = str.toStdWString();

  503. CTMStrConvert converter;

  504. m_filePaths.push_back(converter.WStringToString(wFilePath));

  505. // m_filePaths.push_back(filePath.toStdString());

  506. }

  507. }

  508. if(m_supportFormat.supportRDF)

  509. {

  510. if(sfileName.find(".rdf") != string::npos)

  511. {

  512. QTextCodec *codec =QTextCodec::codecForName("UTF-8");

  513. QString str = codec->toUnicode(filePath.toStdString().c_str());

  514. wstring wFilePath = str.toStdWString();

  515. CTMStrConvert converter;

  516. m_filePaths.push_back(converter.WStringToString(wFilePath));

  517. // m_filePaths.push_back(filePath.toStdString());

  518. }

  519. }

  520. }

  521. else

  522. {

  523. continue;

  524. }

  525. }

  526. }

  527. else

  528. {

  529. m_filePaths.push_back(m_firstPath);

  530. }

  531.  
  532. if(m_filePaths.size() == 0)

  533. {

  534. QMessageBox msgBox(QMessageBox::Warning,"Information",tr("无有效文件,请确定"),QMessageBox::Yes,NULL);

  535. msgBox.exec();

  536. return -1;

  537. }

  538. return 0;

  539. }

2.4 UI文件请到如下路径下载,同时也包含可执行文件(.exe):

https://download.csdn.net/download/hit1524468/10316766

3. 工具效果(选择用googleEarth打开转换的KML文件)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值