.pro文件需加上这些依赖

    1. QT += core gui serialport webchannel webengine webenginewidgets network

    gps_bds_positon.h

    1. #ifndef GPS_BDS_POSION_H
    2. #define GPS_BDS_POSION_H
    3. #include <QMainWindow>
    4. #include <QSerialPort>
    5. #include <QWebChannel>
    6. #pragma execution_character_set("utf-8")
    7. #include <QtWebEngineWidgets/QWebEngineView>
    8. //#include <QHBoxLayout>
    9. #include <QNetworkAccessManager>
    10. namespace Ui {
    11. class GPS_BDS_Posion;
    12. }
    13. class GPS_BDS_Posion : public QMainWindow
    14. {
    15. Q_OBJECT
    16. public:
    17. explicit GPS_BDS_Posion(QWidget *parent = nullptr);
    18. ~GPS_BDS_Posion();
    19. void on_SerialPort_readyRead();
    20. void RxData(QByteArray);
    21. void gpsDatasProcessing(QByteArray GPSBuffer);
    22. void slotSerialTimerOut();
    23. void setCoordinate(QString lon,QString lat);
    24. bool serialRead = true;
    25. int times = 0;
    26. QByteArray rxArray; // 存储数据 A数据
    27. void fromWebPageToLocal(const QString& strTemp); //槽函数,网页端将通过这个函数把信息传回本地应用。
    28. QWebEngineView *webView;
    29. QWebChannel *web;
    30. QString longitude = NULL;
    31. QString latitude = NULL;
    32. QString getJsRetString();
    33. void callJsBtn();
    34. void onBtnGetClicked(QString x, QString y);
    35. QNetworkAccessManager * networkManager;
    36. QString change_lo;
    37. QString change_la;
    38. signals:
    39. void fromLocalToWebPage(const QString& strTemp); //信号,发送这个信号就会把信息发送到网页端
    40. void readyRead();
    41. public slots:
    42. void getData(QNetworkReply *reply);
    43. private:
    44. Ui::GPS_BDS_Posion *ui;
    45. // 判断串口是否连接成功
    46. bool sign = true;
    47. // 串口设置
    48. bool getSerialPortConfig();
    49. QSerialPort mSerialPort; // 串口变量
    50. };
    51. #endif // GPS_BDS_POSION_H

    gps_bds_positon.cpp

    1. #include "gps_bds_posion.h"
    2. #include "ui_gps_bds_posion.h"
    3. #include <QSerialPortInfo>
    4. #include <QSerialPort>
    5. #include <QDebug>
    6. #include <QFile>
    7. #include <QWebEnginePage>
    8. #include <QWebChannel>
    9. #include <QNetworkRequest>
    10. #include <QNetworkReply>
    11. #include <QNetworkAccessManager>
    12. #include <QUrl>
    13. #include <QByteArray>
    14. #include <QJsonDocument>
    15. #include <QJsonObject>
    16. GPS_BDS_Posion::GPS_BDS_Posion(QWidget *parent) :
    17. QMainWindow(parent),
    18. ui(new Ui::GPS_BDS_Posion)
    19. {
    20. ui->setupUi(this);
    21. this->setWindowTitle("北斗GPS定位解析系统");
    22. // 智能识别当前系统的有效串口号
    23. QList<QSerialPortInfo> serialPortInfo = QSerialPortInfo::availablePorts();
    24. int count = serialPortInfo.count();
    25. for(int i = 0; i<count; i++)
    26. {
    27. ui->serialPort->addItem(serialPortInfo.at(i).portName());
    28. }
    29. // 波特率
    30. QStringList list;
    31. list << "110" << "300" << "600" << "1200" << "2400" << "4800" << "9600" << "14400" << "115200";
    32. ui->baudRate->addItems(list);
    33. ui->baudRate->setCurrentIndex(6); // 设置默认值
    34. // // 校验位
    35. // ui->comParity->addItem("NONE");
    36. // ui->comParity->addItem("ODD");
    37. // ui->comParity->addItem("EVEN");
    38. // ui->comParity->addItem("MARK");
    39. // ui->comParity->addItem("SPACE");
    40. // // 数据位
    41. // ui->comDataBits->addItem("5");
    42. // ui->comDataBits->addItem("6");
    43. // ui->comDataBits->addItem("7");
    44. // ui->comDataBits->addItem("8");
    45. // ui->comDataBits->setCurrentIndex(3); // 设置默认值
    46. // // 停止位
    47. // ui->comStopBits->addItem("1");
    48. // ui->comStopBits->addItem("1.5");
    49. // ui->comStopBits->addItem("2");
    50. // 连接串口
    51. connect(ui->openButton, &QPushButton::clicked, [=](){
    52. getSerialPortConfig();
    53. });
    54. // 关闭串口
    55. connect(ui->closeButton, &QPushButton::clicked, [=](){
    56. mSerialPort.close();
    57. });
    58. // 接收数据
    59. connect(&mSerialPort, &QSerialPort::readyRead, this, &GPS_BDS_Posion::on_SerialPort_readyRead);
    60. // 加载网页到界面上
    61. QString htmlPath = QCoreApplication::applicationDirPath() + "/baiduMap/map.html"; //从此html文件中读取内容后写入webview
    62. QUrl baseUrl = QCoreApplication::applicationDirPath() + "/baiduMap/";//外部对象,包括以下CSS和js文件
    63. QFile file(htmlPath);
    64. ui->mapData->load(QUrl(htmlPath));
    65. qDebug() << htmlPath;
    66. // 定位按钮
    67. connect(ui->position, &QPushButton::clicked, this, &GPS_BDS_Posion::callJsBtn);
    68. // 创建网络请求实例
    69. networkManager = new QNetworkAccessManager(this);
    70. //设置get请求数据完成时回调函数getData(QNetworkReply*)
    71. connect(networkManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(getData(QNetworkReply *)));
    72. // onBtnGetClicked();
    73. }
    74. //按钮被点击将使用get方式请求数据
    75. void GPS_BDS_Posion::onBtnGetClicked(QString x, QString y)
    76. {
    77. QString url = QString("http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=%1&y=%2").arg(x).arg(y);
    78. //创建请求对象
    79. QNetworkRequest request=QNetworkRequest(QUrl(url));
    80. //发送get请求
    81. networkManager->get(request);
    82. }
    83. //对http请求的get返回数据进行处理
    84. void GPS_BDS_Posion::getData(QNetworkReply *reply)
    85. {
    86. //获得返回数据存在字节数组中
    87. QByteArray data = reply->readAll();
    88. //将字节数组转为字符串
    89. QString str=QString::fromUtf8(data);
    90. //将数据展示在textEdit中
    91. // ui->textEdit->setText(str);
    92. qDebug() << str;
    93. // QJsonDocument(str);
    94. //change_lo = ;
    95. // change_la;
    96. QJsonParseError json_error;
    97. QJsonDocument parse_doucment = QJsonDocument::fromJson(data, &json_error);
    98. if(json_error.error == QJsonParseError::NoError)
    99. {
    100. if(parse_doucment.isObject())
    101. {
    102. QJsonObject obj = parse_doucment.object();
    103. if(obj.contains("x"))
    104. {
    105. QJsonValue name_value = obj.take("x");
    106. if(name_value.isString())
    107. {
    108. QString name = name_value.toString();
    109. QList<QString> first = name.split(".");
    110. int f = first.at(0).toInt()/100;
    111. QString t = QString("0.%1").arg(first.at(1));
    112. double x = t.toDouble() / 1.6666666666666667;
    113. //1.6666666666666667
    114. QString fx = QString("%1%2").arg(f).arg(x);
    115. change_lo = QString::number(x);
    116. qDebug() << fx << name;
    117. }
    118. }
    119. if(obj.contains("y"))
    120. {
    121. QJsonValue version_value = obj.take("y");
    122. if(version_value.isString())
    123. {
    124. QString name = version_value.toString();
    125. qDebug() << name;
    126. }
    127. }
    128. }
    129. }
    130. }
    131. // 调用js函数
    132. void GPS_BDS_Posion::callJsBtn()
    133. {
    134. // longitude = ui->longitudeData_p->text();
    135. // latitude = ui->latitudeData_p->text();
    136. onBtnGetClicked(longitude, latitude);
    137. //qt调用html的js函数
    138. QString strJs = QString("myFun(%1, %2)").arg(longitude).arg(latitude);
    139. qDebug() << strJs;
    140. ui->mapData->page()->runJavaScript(strJs);
    141. }
    142. GPS_BDS_Posion::~GPS_BDS_Posion()
    143. {
    144. delete ui;
    145. }
    146. // 串口设置
    147. bool GPS_BDS_Posion::getSerialPortConfig()
    148. {
    149. // 获取当前选择框值
    150. QString getSerialPort = ui->serialPort->currentText(); // 串口
    151. QString getBaudRate = ui->baudRate->currentText(); // 波特率
    152. // 设置端口号
    153. mSerialPort.setPortName(getSerialPort);
    154. // 设置波特率
    155. if(getBaudRate == "9600") {
    156. mSerialPort.setBaudRate(QSerialPort::Baud9600);
    157. }else if(getBaudRate == "19200"){
    158. mSerialPort.setBaudRate(QSerialPort::Baud19200);
    159. }else if(getBaudRate == "115200"){
    160. mSerialPort.setBaudRate(QSerialPort::Baud115200);
    161. }
    162. // 数据位
    163. mSerialPort.setDataBits(QSerialPort::Data8);
    164. // 设置停止位
    165. mSerialPort.setStopBits(QSerialPort::OneAndHalfStop);
    166. // 打开
    167. bool isOpen = mSerialPort.open(QSerialPort::ReadWrite);
    168. if (isOpen)
    169. {
    170. qDebug() << "打开成功";
    171. }
    172. return isOpen;
    173. }
    174. void GPS_BDS_Posion::on_SerialPort_readyRead()
    175. {
    176. // 取出所有数据
    177. QByteArray recvData = mSerialPort.readAll();
    178. // 传值
    179. RxData(recvData);
    180. }
    181. void GPS_BDS_Posion::RxData( QByteArray recvData ){
    182. QString rxString;
    183. // 判断第一次是否是是$开头的数据
    184. if (recvData.at(0) != '$' && sign)
    185. {
    186. qDebug() << recvData.at(0);
    187. sign = false;
    188. return;
    189. }
    190. // 将数据添加到ui界面
    191. ui->dataList->append(recvData);
    192. // 判断结束参数
    193. if (recvData.contains("OK"))
    194. {
    195. qDebug() << "88888";
    196. rxArray.append(recvData);
    197. // 整理好数据之后进行处理
    198. gpsDatasProcessing( rxArray );
    199. rxArray.clear();
    200. } else {
    201. // 如果接收的信息不是结束,则继续将数据添加进去
    202. rxArray.append(recvData);
    203. }
    204. }
    205. void GPS_BDS_Posion::gpsDatasProcessing(QByteArray GPSBuffer)
    206. {
    207. QString GPSBufferString = QString( GPSBuffer );
    208. int error_pos = 0;
    209. QString GNRMC_String = NULL;
    210. QString GPGGA_String = NULL;
    211. QString GPGSV_String = NULL;
    212. QString GPRMC_String = NULL;
    213. QString GPGLL_String = NULL;
    214. QString GNGGA_String = NULL;
    215. bool latiflag = false;
    216. bool atiflag = false;
    217. bool utcflag = false;
    218. bool speedflag = false;
    219. bool longtiflag = false;
    220. QList<QString> gpsStringList = GPSBufferString.split("\r\n");
    221. qDebug() << "gpsStringList" << gpsStringList;
    222. qDebug() << "error_pos" << error_pos;
    223. // 由于定时间隔,数据包发生黏连,纠正数据。
    224. // if( gpsStringList.at(0).at(0) != '$' ) {
    225. // QString ErrorString = gpsStringList.at(gpsStringList.length()-1) + gpsStringList.at(0);
    226. // error_pos = 1;
    227. // if( ErrorString.contains("$GNRMC") ){
    228. // GNRMC_String = ErrorString;
    229. // }else if( ErrorString.contains("$GPGGA") ) {
    230. // GPGGA_String = ErrorString;
    231. // }else if( ErrorString.contains("$GPGSV") ) {
    232. // GPGSV_String = ErrorString;
    233. // }else if( ErrorString.contains("$GPRMC") ) {
    234. // GPRMC_String = ErrorString;
    235. // }else if( ErrorString.contains("$GPGLL") ) {
    236. // GPGLL_String = ErrorString;
    237. // }else if( ErrorString.contains("$GNGGA") ) {
    238. // GNGGA_String = ErrorString;
    239. // }
    240. // }else{
    241. // error_pos = 0;
    242. // }
    243. // 从QList中得到数据
    244. for( int i = 0; i < gpsStringList.length(); i++ ) {
    245. qDebug() << "i" << i;
    246. if( gpsStringList.at(i).contains("$GNRMC") ){
    247. GNRMC_String = gpsStringList.at(i);
    248. }else if( gpsStringList.at(i).contains("$GPGGA") ) {
    249. GPGGA_String = gpsStringList.at(i);
    250. }else if( gpsStringList.at(i).contains("$GPGSV") ) {
    251. GPGSV_String = gpsStringList.at(i);
    252. }else if( gpsStringList.at(i).contains("$GPRMC") ) {
    253. GPRMC_String = gpsStringList.at(i);
    254. }else if( gpsStringList.at(i).contains("$GPGLL") ) {
    255. GPGLL_String = gpsStringList.at(i);
    256. }else if( gpsStringList.at(i).contains("$GNGGA") ) {
    257. GNGGA_String = gpsStringList.at(i);
    258. }
    259. // 循环到$GPTXT时就跳出循环
    260. if (gpsStringList.at(i).contains("$GPTXT"))
    261. {
    262. break;
    263. }
    264. }
    265. // 有GPS数据
    266. // if( !GPGGA_String.isNull() ) {
    267. // QList<QString> gpggaStrList = GPGGA_String.split(",");
    268. // QString utcstr = gpggaStrList.at(1);
    269. // ui->timeData->setText("格林威治时间:"+utcstr.mid(0,2)+":"+utcstr.mid(2,2)+":"+utcstr.mid(4,2));
    270. // QString latistr = gpggaStrList.at(2);
    271. // ui->latitudeData->setText("北纬"+latistr.mid(0,2)+"度"+latistr.mid(2,7)+"分");
    272. // QString altistr = gpggaStrList.at(4);
    273. // ui->longitudeData->setText("西经"+altistr.mid(0,3)+"度"+altistr.mid(3,7)+"分");
    274. // utcflag = true;
    275. // latiflag = true;
    276. // atiflag = true;
    277. // qDebug() << "GPGGA_String";
    278. // }
    279. qDebug() << "有1";
    280. qDebug() << "GNRMC_String" << GNRMC_String;
    281. // 有GN数据
    282. if( !GNRMC_String.isNull() ) {
    283. qDebug() << "有2";
    284. if( !latiflag ) {
    285. QList<QString> gnggaStrList = GNRMC_String.split(",");
    286. // 是否有效定位
    287. if (gnggaStrList.at(2) == "V")
    288. {
    289. qDebug() << "GNRMC无效数据";
    290. return;
    291. }
    292. // 获取时间
    293. QString utcstr_str = gnggaStrList.at(1);
    294. // 将UTC转BTC
    295. QString utcstr = QString("%1").arg(utcstr_str.toFloat() + 080000.000);
    296. qDebug() << utcstr_str;
    297. qDebug() << utcstr;
    298. ui->timeData->setText("北京时间:"+utcstr.mid(0,2) + ":" + utcstr.mid(2,2) + ":" + utcstr.mid(4,2));
    299. // 获取维度
    300. QString latistr = gnggaStrList.at(3);
    301. if (gnggaStrList.at(4) == "N")
    302. {
    303. ui->latitudeData->setText("北纬"+latistr.mid(0,2)+"°"+latistr.mid(2,9)+"'");
    304. }else {
    305. ui->latitudeData->setText("南纬"+latistr.mid(0,2)+"°"+latistr.mid(2,9)+"'");
    306. }
    307. double double_lati = latistr.mid(0,2).toDouble()+(latistr.mid(2,7).toDouble()+0.25)/60;
    308. ui->latitudeData_p->setText(latistr);
    309. // double wd = (latistr.toDouble() / 100);
    310. latitude = latistr;
    311. // 获取经度
    312. QString altistr = gnggaStrList.at(5);
    313. if (gnggaStrList.at(6) == "E")
    314. {
    315. ui->longitudeData->setText("西经"+altistr.mid(0,3)+"°"+altistr.mid(3,9)+"'");
    316. }else {
    317. ui->longitudeData->setText("东经"+altistr.mid(0,3)+"°"+altistr.mid(3,9)+"'");
    318. }
    319. double double_alti = altistr.mid(0,3).toDouble()+(altistr.mid(3,7).toDouble()+0.25)/60;
    320. ui->longitudeData_p->setText(altistr);
    321. longitude = altistr;
    322. qDebug() << "latistr:" << latistr << "altistr" << altistr;
    323. // setCoordinate(QString::number(double_alti),QString::number(double_lati));
    324. // setCoordinate(QString::number(108.886119),QString::number(34.223921));
    325. qDebug()<< "纬度:"<<QString::number(double_alti)<<"|"<<"经度:"<< QString::number(double_lati) << "\n";
    326. // 地面速率
    327. QString speed = gnggaStrList.at(7);
    328. ui->speedData->setText(speed + "节");
    329. utcflag = true;
    330. latiflag = true;
    331. atiflag = true;
    332. qDebug() << "GNGGA_String";
    333. }
    334. }
    335. if( !GNGGA_String.isNull() ) {
    336. QList<QString> gnggaStrList = GNGGA_String.split(",");
    337. // 是否有效定位
    338. if (gnggaStrList.at(2) == "V")
    339. {
    340. qDebug() << "GNGGA无效数据";
    341. return;
    342. }
    343. // 获取海拔高度
    344. QString longtistr = gnggaStrList.at(9);
    345. ui->hightData->setText(longtistr + "m ");
    346. }
    347. }
    348. //void GPS_BDS_Posion::slotSerialTimerOut()
    349. //{
    350. // if( serialRead == false ){
    351. // serialRead = true;
    352. // }
    353. //}
    354. //void GPS_BDS_Posion::setCoordinate(QString lon,QString lat)
    355. //{
    356. // QWebFrame *webFrame = ui->webView->page()->mainFrame();
    357. // QString cmd = QString("showAddress(\"%1\",\"%2\")").arg(lon).arg(lat);
    358. // webFrame->evaluateJavaScript(cmd);
    359. //}

    ui界面
    image.png

    参考文章:
    Qt开发北斗定位系统融合百度地图API及Qt程序打包发布:https://www.cnblogs.com/sigma0/p/7220334.html
    Qt加载百度离线地图:https://blog.csdn.net/caoshangpa/article/details/51015483
    QT之调用百度地图离线API:https://blog.csdn.net/aitaoge/article/details/82425188

    文件:
    GPS-BDS_Posion.zip

    百度地图js、html等资源文件,需要将这些文件放在debug文件夹中
    baiduMap.zip