#include "frmmapgps.h" #include "ui_frmmapgps.h" #include "quihelper.h" #include "webview.h" #include "maphelper.h" #include "mapbaidu.h" frmMapGps::frmMapGps(QWidget *parent) : QWidget(parent), ui(new Ui::frmMapGps) { ui->setupUi(this); this->initForm(); } frmMapGps::~frmMapGps() { delete ui; } void frmMapGps::showEvent(QShowEvent *) { //只需要加载一次,避免重复初始化 static bool isShow = false; if (!isShow) { isShow = true; QMetaObject::invokeMethod(this, "loadMap", Qt::QueuedConnection); QTimer::singleShot(1000, this, SLOT(on_btnSearchData_clicked())); } } QTableWidget *frmMapGps::getTableWidget() { //哪个可见就采用哪个 if (ui->tableWidgetSource->isVisible()) { return ui->tableWidgetSource; } else { return ui->tableWidgetTarget; } } void frmMapGps::initForm() { //设置右侧固定宽度 ui->widgetRight->setFixedWidth(AppData::RightWidth); //选项卡居中 ui->tabWidget->setStyleSheet("QTabWidget::tab-bar{alignment:center;}"); //实例化百度地图类 baidu = new MapBaiDu(this); //实例化通用浏览器控件 web = new WebView(this); //加入到布局 web->setLayout(ui->gridLayout); //关联浏览器控件信号 connect(web, SIGNAL(receiveDataFromJs(QString, QVariant)), this, SLOT(receiveDataFromJs(QString, QVariant))); //定时器模拟轨迹 timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(moveMarker())); //121.424362,31.175942/121.490229,31.242866 121.427196,31.178764/121.425740,31.176567 ui->txtStartAddr->setText("121.425740,31.176567"); ui->txtEndAddr->setText("121.428545,31.203614"); //添加移动间隔 QStringList listMoveInterval, listMoveIntervalx; listMoveInterval << "0.02 秒钟" << "0.05 秒钟" << "0.10 秒钟" << "0.30 秒钟" << "0.50 秒钟" << "1.00 秒钟" << "3.00 秒钟"; listMoveIntervalx << "20" << "50" << "100" << "300" << "500" << "1000" << "3000"; int count = listMoveInterval.count(); for (int i = 0; i < count; ++i) { ui->cboxMoveInterval->addItem(listMoveInterval.at(i), listMoveIntervalx.at(i)); } ui->cboxMoveInterval->setCurrentIndex(2); ui->cboxMoveMode->addItem("重新绘制"); ui->cboxMoveMode->addItem("沿线运动"); this->initTable(ui->tableWidgetSource); this->initTable(ui->tableWidgetTarget); } void frmMapGps::loadMap() { QString fileName = QString("%1/map_web.html").arg(ConfigPath); QString url = "file:///" + fileName; //设置缩放级别 baidu->setMapZoom(17); //设置单击获取经纬度 baidu->setEnableClickPoint(true); //设置默认的中心点坐标 baidu->setMapCenterPoint("121.424362,31.175942"); //设置离线地图 baidu->setMapLocal(true); baidu->setSaveFile(SaveFile); baidu->setFileName(fileName); QString html = baidu->newMap(); //两种方式加载,一种是传入html文件,一种是html内容 if (baidu->getSaveFile()) { web->load(url); } else { QString baseUrl = QString("%1/").arg(ConfigPath); web->load("", html, baseUrl); } } void frmMapGps::setInfo(int angle, int index, int count) { QString info = QString("角度 %1°/第 %2 个/共 %3 个").arg(angle).arg(index).arg(count); ui->labTip->setText(info); } void frmMapGps::initTable(QTableWidget *tableWidget) { //初始化表格控件 QUIHelper::initTableView(tableWidget); tableWidget->setColumnCount(2); tableWidget->setHorizontalHeaderLabels(QStringList() << "编号" << "经纬度值"); tableWidget->setColumnWidth(0, 45); tableWidget->setColumnWidth(1, 100); } void frmMapGps::addItem(QTableWidget *tableWidget, int index, const QString &point) { //编号 QTableWidgetItem *itemId = new QTableWidgetItem; itemId->setText(QString::number(index + 1)); itemId->setTextAlignment(Qt::AlignCenter); tableWidget->setItem(index, 0, itemId); QTableWidgetItem *itemPoint = new QTableWidgetItem; //重新过滤小数点,对齐更好看 itemPoint->setText(MapHelper::getLngLat2(point)); //设置原始数据更准确 itemPoint->setData(Qt::UserRole, point); tableWidget->setItem(index, 1, itemPoint); } void frmMapGps::receiveDataFromJs(const QString &type, const QVariant &data) { if (data.isNull()) { return; } //qDebug() << TIMEMS << "frmMapGps" << type << data; QString result = data.toString(); if (type == "point") { if (ui->ckSelectAddr->isChecked()) { //判断哪里勾选了就设置到哪里 QString point = MapHelper::getLngLat2(result); //判断哪里勾选了就设置到哪里 if (ui->rbtnStartAddr->isChecked()) { ui->txtStartAddr->setText(point); } else { ui->txtEndAddr->setText(point); } } } else if (type == "routepoints") { //将查询路径转换成经纬度坐标点集合数据显示 routeDatas.clear(); ui->tableWidgetSource->clearContents(); //可能会有多个路径集合,目前测试下来都是一个路径集合 QStringList datas = result.split("|"); foreach (QString data, datas) { QStringList points = data.split(";"); routeDatas << points; int count = points.count(); ui->tableWidgetSource->setRowCount(count); for (int i = 0; i < count; ++i) { addItem(ui->tableWidgetSource, i, points.at(i)); } } setInfo(0, 0, 0); } } void frmMapGps::runJs(const QString &js) { web->runJs(js); } void frmMapGps::on_btnSearchData_clicked() { QString startAddr = ui->txtStartAddr->text().trimmed(); QString endAddr = ui->txtEndAddr->text().trimmed(); baidu->setRotueInfo(2, 0, startAddr, endAddr); this->loadMap(); } void frmMapGps::moveMarker() { QTableWidget *tableWidget = getTableWidget(); int row = tableWidget->currentRow(); int count = tableWidget->rowCount(); if (row >= 0 && row < count) { //找出和上一个点之间的角度 int angle = 0; QString point = tableWidget->item(row, 1)->data(Qt::UserRole).toString(); //第一个点和最后一个点不用处理 if (row > 0 && row < count - 1) { //上一个点坐标 QString point2 = tableWidget->item(row - 1, 1)->data(Qt::UserRole).toString(); //计算当前上一个点和当前点的旋转角度 angle = MapHelper::getAngle(point2, point); } //执行移动设备点函数,参数带旋转角度 QString js = QString("moveMarker('%1', '%2', %3)").arg(name).arg(point).arg(angle); runJs(js); //重新绘制轨迹点 if (ui->cboxMoveMode->currentIndex() == 0) { //清空之前的轨迹点 js = QString("deleteOverlay('Polyline')"); runJs(js); //取出第一个点到当前焦点所在行的点组成已经走过的轨迹点集合重新绘制 QStringList points; for (int i = 0; i <= row; ++i) { points << tableWidget->item(i, 1)->data(Qt::UserRole).toString(); } js = QString("addPolyline('%1')").arg(points.join("|")); runJs(js); } //显示当前第几个数据 setInfo(angle, row + 1, count); tableWidget->setCurrentCell(row + 1, 0); } else { on_btnTestData_clicked(); } } void frmMapGps::moveMarker2() { //演示最简单的步骤 QString name = "测试设备"; //第一步: 添加一个标记,支持添加多个,添加一次存在了就行,后面只需要移动标记 static bool isInit = false; if (!isInit) { QString icon;// = "./device/device_airplane.png"; int size = 60; QString js = QString("addMarker('%1', '', '', '', 60, '%1', 0, 0, '%2', %3)").arg(name).arg(icon).arg(size); runJs(js); } //第二步: 移动标记 static double offset = 0; offset += 0.001; int angle = 0; QString point = QString("%1, %2").arg(121.424362 + offset).arg(31.175942); //执行移动设备点函数,参数带旋转角度 QString js = QString("moveMarker('%1', '%2', %3)").arg(name).arg(point).arg(angle); runJs(js); } void frmMapGps::on_btnTestData_clicked() { #if 0 moveMarker2(); #else QTableWidget *tableWidget = getTableWidget(); if (ui->btnTestData->text() == "模拟轨迹") { //限制最小数量 if (tableWidget->rowCount() < 2) { return; } //第一步: 添加一个标记 name = ui->txtDeviceName->text().trimmed(); if (name.isEmpty()) { name = "国产大飞机C919"; } //图片文件在可执行文件下的config/device目录 QString icon = "./device/device_airplane.png"; int size = 60; QString js = QString("addMarker('%1', '', '', '', 60, '%1', 0, 0, '%2', %3)").arg(name).arg(icon).arg(size); runJs(js); //第二步: 移到第一个点 tableWidget->setFocus(); tableWidget->setCurrentCell(0, 0); ui->btnTestData->setText("停止模拟"); ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, false); //第三步: 启动定时器并立即执行一次 int index = ui->cboxMoveInterval->currentIndex(); timer->start(ui->cboxMoveInterval->itemData(index).toInt()); moveMarker(); } else { //清空标记 QString js = QString("deleteMarker('%1')").arg(name); runJs(js); //停止定时器 timer->stop(); ui->btnTestData->setText("模拟轨迹"); ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, true); } #endif } void frmMapGps::on_btnCheckData_clicked() { if (timer->isActive()) { return; } //第一步: 计算总数,求平均值=实际总数/预期总数+1,预期总数>=实际总数则不用处理 int countSource = ui->tableWidgetSource->rowCount(); int countTarget = ui->txtPointCount->text().trimmed().toInt(); if (countTarget >= countSource) { QUIHelper::showMessageBoxError("目标点数不能大于等于原数据点数!"); ui->txtPointCount->setFocus(); return; } //第二步: 根据平均值挨个取出值 QStringList points; int avg = countSource / countTarget + 1; for (int i = 0; i < countSource; i += avg) { QString point = ui->tableWidgetSource->item(i, 1)->data(Qt::UserRole).toString(); points << point; } //必须加上末尾这个作为结束,如果刚好除尽则不用 QString point = ui->tableWidgetSource->item(countSource - 1, 1)->data(Qt::UserRole).toString(); if (points.last() != point) { points << point; } //第三步: 将数据重新填入筛选数据列表 int count = points.count(); ui->tableWidgetTarget->clearContents(); ui->tableWidgetTarget->setRowCount(count); for (int i = 0; i < count; ++i) { addItem(ui->tableWidgetTarget, i, points.at(i)); } ui->tabWidget->setCurrentIndex(1); } void frmMapGps::on_btnDrawData_clicked() { if (routeDatas.count() == 0) { QUIHelper::showMessageBoxError("请先单击查询路线获取路线的坐标点集合!"); return; } //清空之前的轨迹点 runJs("deleteOverlay('Polyline')"); //将收到的路径点集合分线段绘制 foreach (QStringList data, routeDatas) { QString points = data.join("|"); QString js = QString("addPolyline('%1', '#ff0000')").arg(points); runJs(js); } }