.pro文件需加上这些依赖
QT += core gui serialport webchannel webengine webenginewidgets network
gps_bds_positon.h
#ifndef GPS_BDS_POSION_H
#define GPS_BDS_POSION_H
#include <QMainWindow>
#include <QSerialPort>
#include <QWebChannel>
#pragma execution_character_set("utf-8")
#include <QtWebEngineWidgets/QWebEngineView>
//#include <QHBoxLayout>
#include <QNetworkAccessManager>
namespace Ui {
class GPS_BDS_Posion;
}
class GPS_BDS_Posion : public QMainWindow
{
Q_OBJECT
public:
explicit GPS_BDS_Posion(QWidget *parent = nullptr);
~GPS_BDS_Posion();
void on_SerialPort_readyRead();
void RxData(QByteArray);
void gpsDatasProcessing(QByteArray GPSBuffer);
void slotSerialTimerOut();
void setCoordinate(QString lon,QString lat);
bool serialRead = true;
int times = 0;
QByteArray rxArray; // 存储数据 A数据
void fromWebPageToLocal(const QString& strTemp); //槽函数,网页端将通过这个函数把信息传回本地应用。
QWebEngineView *webView;
QWebChannel *web;
QString longitude = NULL;
QString latitude = NULL;
QString getJsRetString();
void callJsBtn();
void onBtnGetClicked(QString x, QString y);
QNetworkAccessManager * networkManager;
QString change_lo;
QString change_la;
signals:
void fromLocalToWebPage(const QString& strTemp); //信号,发送这个信号就会把信息发送到网页端
void readyRead();
public slots:
void getData(QNetworkReply *reply);
private:
Ui::GPS_BDS_Posion *ui;
// 判断串口是否连接成功
bool sign = true;
// 串口设置
bool getSerialPortConfig();
QSerialPort mSerialPort; // 串口变量
};
#endif // GPS_BDS_POSION_H
gps_bds_positon.cpp
#include "gps_bds_posion.h"
#include "ui_gps_bds_posion.h"
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QDebug>
#include <QFile>
#include <QWebEnginePage>
#include <QWebChannel>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QUrl>
#include <QByteArray>
#include <QJsonDocument>
#include <QJsonObject>
GPS_BDS_Posion::GPS_BDS_Posion(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::GPS_BDS_Posion)
{
ui->setupUi(this);
this->setWindowTitle("北斗GPS定位解析系统");
// 智能识别当前系统的有效串口号
QList<QSerialPortInfo> serialPortInfo = QSerialPortInfo::availablePorts();
int count = serialPortInfo.count();
for(int i = 0; i<count; i++)
{
ui->serialPort->addItem(serialPortInfo.at(i).portName());
}
// 波特率
QStringList list;
list << "110" << "300" << "600" << "1200" << "2400" << "4800" << "9600" << "14400" << "115200";
ui->baudRate->addItems(list);
ui->baudRate->setCurrentIndex(6); // 设置默认值
// // 校验位
// ui->comParity->addItem("NONE");
// ui->comParity->addItem("ODD");
// ui->comParity->addItem("EVEN");
// ui->comParity->addItem("MARK");
// ui->comParity->addItem("SPACE");
// // 数据位
// ui->comDataBits->addItem("5");
// ui->comDataBits->addItem("6");
// ui->comDataBits->addItem("7");
// ui->comDataBits->addItem("8");
// ui->comDataBits->setCurrentIndex(3); // 设置默认值
// // 停止位
// ui->comStopBits->addItem("1");
// ui->comStopBits->addItem("1.5");
// ui->comStopBits->addItem("2");
// 连接串口
connect(ui->openButton, &QPushButton::clicked, [=](){
getSerialPortConfig();
});
// 关闭串口
connect(ui->closeButton, &QPushButton::clicked, [=](){
mSerialPort.close();
});
// 接收数据
connect(&mSerialPort, &QSerialPort::readyRead, this, &GPS_BDS_Posion::on_SerialPort_readyRead);
// 加载网页到界面上
QString htmlPath = QCoreApplication::applicationDirPath() + "/baiduMap/map.html"; //从此html文件中读取内容后写入webview
QUrl baseUrl = QCoreApplication::applicationDirPath() + "/baiduMap/";//外部对象,包括以下CSS和js文件
QFile file(htmlPath);
ui->mapData->load(QUrl(htmlPath));
qDebug() << htmlPath;
// 定位按钮
connect(ui->position, &QPushButton::clicked, this, &GPS_BDS_Posion::callJsBtn);
// 创建网络请求实例
networkManager = new QNetworkAccessManager(this);
//设置get请求数据完成时回调函数getData(QNetworkReply*)
connect(networkManager,SIGNAL(finished(QNetworkReply*)),this,SLOT(getData(QNetworkReply *)));
// onBtnGetClicked();
}
//按钮被点击将使用get方式请求数据
void GPS_BDS_Posion::onBtnGetClicked(QString x, QString y)
{
QString url = QString("http://api.map.baidu.com/ag/coord/convert?from=0&to=4&x=%1&y=%2").arg(x).arg(y);
//创建请求对象
QNetworkRequest request=QNetworkRequest(QUrl(url));
//发送get请求
networkManager->get(request);
}
//对http请求的get返回数据进行处理
void GPS_BDS_Posion::getData(QNetworkReply *reply)
{
//获得返回数据存在字节数组中
QByteArray data = reply->readAll();
//将字节数组转为字符串
QString str=QString::fromUtf8(data);
//将数据展示在textEdit中
// ui->textEdit->setText(str);
qDebug() << str;
// QJsonDocument(str);
//change_lo = ;
// change_la;
QJsonParseError json_error;
QJsonDocument parse_doucment = QJsonDocument::fromJson(data, &json_error);
if(json_error.error == QJsonParseError::NoError)
{
if(parse_doucment.isObject())
{
QJsonObject obj = parse_doucment.object();
if(obj.contains("x"))
{
QJsonValue name_value = obj.take("x");
if(name_value.isString())
{
QString name = name_value.toString();
QList<QString> first = name.split(".");
int f = first.at(0).toInt()/100;
QString t = QString("0.%1").arg(first.at(1));
double x = t.toDouble() / 1.6666666666666667;
//1.6666666666666667
QString fx = QString("%1%2").arg(f).arg(x);
change_lo = QString::number(x);
qDebug() << fx << name;
}
}
if(obj.contains("y"))
{
QJsonValue version_value = obj.take("y");
if(version_value.isString())
{
QString name = version_value.toString();
qDebug() << name;
}
}
}
}
}
// 调用js函数
void GPS_BDS_Posion::callJsBtn()
{
// longitude = ui->longitudeData_p->text();
// latitude = ui->latitudeData_p->text();
onBtnGetClicked(longitude, latitude);
//qt调用html的js函数
QString strJs = QString("myFun(%1, %2)").arg(longitude).arg(latitude);
qDebug() << strJs;
ui->mapData->page()->runJavaScript(strJs);
}
GPS_BDS_Posion::~GPS_BDS_Posion()
{
delete ui;
}
// 串口设置
bool GPS_BDS_Posion::getSerialPortConfig()
{
// 获取当前选择框值
QString getSerialPort = ui->serialPort->currentText(); // 串口
QString getBaudRate = ui->baudRate->currentText(); // 波特率
// 设置端口号
mSerialPort.setPortName(getSerialPort);
// 设置波特率
if(getBaudRate == "9600") {
mSerialPort.setBaudRate(QSerialPort::Baud9600);
}else if(getBaudRate == "19200"){
mSerialPort.setBaudRate(QSerialPort::Baud19200);
}else if(getBaudRate == "115200"){
mSerialPort.setBaudRate(QSerialPort::Baud115200);
}
// 数据位
mSerialPort.setDataBits(QSerialPort::Data8);
// 设置停止位
mSerialPort.setStopBits(QSerialPort::OneAndHalfStop);
// 打开
bool isOpen = mSerialPort.open(QSerialPort::ReadWrite);
if (isOpen)
{
qDebug() << "打开成功";
}
return isOpen;
}
void GPS_BDS_Posion::on_SerialPort_readyRead()
{
// 取出所有数据
QByteArray recvData = mSerialPort.readAll();
// 传值
RxData(recvData);
}
void GPS_BDS_Posion::RxData( QByteArray recvData ){
QString rxString;
// 判断第一次是否是是$开头的数据
if (recvData.at(0) != '$' && sign)
{
qDebug() << recvData.at(0);
sign = false;
return;
}
// 将数据添加到ui界面
ui->dataList->append(recvData);
// 判断结束参数
if (recvData.contains("OK"))
{
qDebug() << "88888";
rxArray.append(recvData);
// 整理好数据之后进行处理
gpsDatasProcessing( rxArray );
rxArray.clear();
} else {
// 如果接收的信息不是结束,则继续将数据添加进去
rxArray.append(recvData);
}
}
void GPS_BDS_Posion::gpsDatasProcessing(QByteArray GPSBuffer)
{
QString GPSBufferString = QString( GPSBuffer );
int error_pos = 0;
QString GNRMC_String = NULL;
QString GPGGA_String = NULL;
QString GPGSV_String = NULL;
QString GPRMC_String = NULL;
QString GPGLL_String = NULL;
QString GNGGA_String = NULL;
bool latiflag = false;
bool atiflag = false;
bool utcflag = false;
bool speedflag = false;
bool longtiflag = false;
QList<QString> gpsStringList = GPSBufferString.split("\r\n");
qDebug() << "gpsStringList" << gpsStringList;
qDebug() << "error_pos" << error_pos;
// 由于定时间隔,数据包发生黏连,纠正数据。
// if( gpsStringList.at(0).at(0) != '$' ) {
// QString ErrorString = gpsStringList.at(gpsStringList.length()-1) + gpsStringList.at(0);
// error_pos = 1;
// if( ErrorString.contains("$GNRMC") ){
// GNRMC_String = ErrorString;
// }else if( ErrorString.contains("$GPGGA") ) {
// GPGGA_String = ErrorString;
// }else if( ErrorString.contains("$GPGSV") ) {
// GPGSV_String = ErrorString;
// }else if( ErrorString.contains("$GPRMC") ) {
// GPRMC_String = ErrorString;
// }else if( ErrorString.contains("$GPGLL") ) {
// GPGLL_String = ErrorString;
// }else if( ErrorString.contains("$GNGGA") ) {
// GNGGA_String = ErrorString;
// }
// }else{
// error_pos = 0;
// }
// 从QList中得到数据
for( int i = 0; i < gpsStringList.length(); i++ ) {
qDebug() << "i" << i;
if( gpsStringList.at(i).contains("$GNRMC") ){
GNRMC_String = gpsStringList.at(i);
}else if( gpsStringList.at(i).contains("$GPGGA") ) {
GPGGA_String = gpsStringList.at(i);
}else if( gpsStringList.at(i).contains("$GPGSV") ) {
GPGSV_String = gpsStringList.at(i);
}else if( gpsStringList.at(i).contains("$GPRMC") ) {
GPRMC_String = gpsStringList.at(i);
}else if( gpsStringList.at(i).contains("$GPGLL") ) {
GPGLL_String = gpsStringList.at(i);
}else if( gpsStringList.at(i).contains("$GNGGA") ) {
GNGGA_String = gpsStringList.at(i);
}
// 循环到$GPTXT时就跳出循环
if (gpsStringList.at(i).contains("$GPTXT"))
{
break;
}
}
// 有GPS数据
// if( !GPGGA_String.isNull() ) {
// QList<QString> gpggaStrList = GPGGA_String.split(",");
// QString utcstr = gpggaStrList.at(1);
// ui->timeData->setText("格林威治时间:"+utcstr.mid(0,2)+":"+utcstr.mid(2,2)+":"+utcstr.mid(4,2));
// QString latistr = gpggaStrList.at(2);
// ui->latitudeData->setText("北纬"+latistr.mid(0,2)+"度"+latistr.mid(2,7)+"分");
// QString altistr = gpggaStrList.at(4);
// ui->longitudeData->setText("西经"+altistr.mid(0,3)+"度"+altistr.mid(3,7)+"分");
// utcflag = true;
// latiflag = true;
// atiflag = true;
// qDebug() << "GPGGA_String";
// }
qDebug() << "有1";
qDebug() << "GNRMC_String" << GNRMC_String;
// 有GN数据
if( !GNRMC_String.isNull() ) {
qDebug() << "有2";
if( !latiflag ) {
QList<QString> gnggaStrList = GNRMC_String.split(",");
// 是否有效定位
if (gnggaStrList.at(2) == "V")
{
qDebug() << "GNRMC无效数据";
return;
}
// 获取时间
QString utcstr_str = gnggaStrList.at(1);
// 将UTC转BTC
QString utcstr = QString("%1").arg(utcstr_str.toFloat() + 080000.000);
qDebug() << utcstr_str;
qDebug() << utcstr;
ui->timeData->setText("北京时间:"+utcstr.mid(0,2) + ":" + utcstr.mid(2,2) + ":" + utcstr.mid(4,2));
// 获取维度
QString latistr = gnggaStrList.at(3);
if (gnggaStrList.at(4) == "N")
{
ui->latitudeData->setText("北纬"+latistr.mid(0,2)+"°"+latistr.mid(2,9)+"'");
}else {
ui->latitudeData->setText("南纬"+latistr.mid(0,2)+"°"+latistr.mid(2,9)+"'");
}
double double_lati = latistr.mid(0,2).toDouble()+(latistr.mid(2,7).toDouble()+0.25)/60;
ui->latitudeData_p->setText(latistr);
// double wd = (latistr.toDouble() / 100);
latitude = latistr;
// 获取经度
QString altistr = gnggaStrList.at(5);
if (gnggaStrList.at(6) == "E")
{
ui->longitudeData->setText("西经"+altistr.mid(0,3)+"°"+altistr.mid(3,9)+"'");
}else {
ui->longitudeData->setText("东经"+altistr.mid(0,3)+"°"+altistr.mid(3,9)+"'");
}
double double_alti = altistr.mid(0,3).toDouble()+(altistr.mid(3,7).toDouble()+0.25)/60;
ui->longitudeData_p->setText(altistr);
longitude = altistr;
qDebug() << "latistr:" << latistr << "altistr" << altistr;
// setCoordinate(QString::number(double_alti),QString::number(double_lati));
// setCoordinate(QString::number(108.886119),QString::number(34.223921));
qDebug()<< "纬度:"<<QString::number(double_alti)<<"|"<<"经度:"<< QString::number(double_lati) << "\n";
// 地面速率
QString speed = gnggaStrList.at(7);
ui->speedData->setText(speed + "节");
utcflag = true;
latiflag = true;
atiflag = true;
qDebug() << "GNGGA_String";
}
}
if( !GNGGA_String.isNull() ) {
QList<QString> gnggaStrList = GNGGA_String.split(",");
// 是否有效定位
if (gnggaStrList.at(2) == "V")
{
qDebug() << "GNGGA无效数据";
return;
}
// 获取海拔高度
QString longtistr = gnggaStrList.at(9);
ui->hightData->setText(longtistr + "m ");
}
}
//void GPS_BDS_Posion::slotSerialTimerOut()
//{
// if( serialRead == false ){
// serialRead = true;
// }
//}
//void GPS_BDS_Posion::setCoordinate(QString lon,QString lat)
//{
// QWebFrame *webFrame = ui->webView->page()->mainFrame();
// QString cmd = QString("showAddress(\"%1\",\"%2\")").arg(lon).arg(lat);
// webFrame->evaluateJavaScript(cmd);
//}
ui界面
参考文章:
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
百度地图js、html等资源文件,需要将这些文件放在debug文件夹中
baiduMap.zip