欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Qt編寫地圖實(shí)現(xiàn)實(shí)時(shí)動(dòng)態(tài)軌跡效果

 更新時(shí)間:2022年02月10日 16:26:03   作者:feiyangqingyun  
實(shí)時(shí)動(dòng)態(tài)軌跡主要是需要在地圖上動(dòng)態(tài)顯示GPS的運(yùn)動(dòng)軌跡,也是編寫地圖時(shí)一個(gè)重要的功能。本文將利用Qt實(shí)現(xiàn)這一功能,需要的可以參考一下

一、前言

實(shí)時(shí)動(dòng)態(tài)軌跡經(jīng)歷過很多個(gè)版本的迭代,此功能最初是一個(gè)客戶定制的,主要是需要在地圖上動(dòng)態(tài)顯示GPS的運(yùn)動(dòng)軌跡,有個(gè)應(yīng)用場景就是一個(gè)帶有監(jiān)控的車子,實(shí)時(shí)在運(yùn)動(dòng)中,后臺可以接收到經(jīng)緯度信息,需要繪制對應(yīng)的軌跡,相當(dāng)于這些攝像機(jī)點(diǎn)位是動(dòng)態(tài)移動(dòng)的,這樣就可以觀測到攝像機(jī)的實(shí)時(shí)位置信息,雙擊攝像機(jī)還可以彈出畫面實(shí)時(shí)預(yù)覽,很直觀。

GPS運(yùn)動(dòng)軌跡這個(gè)功能,也需要用到j(luò)s的知識,其實(shí)就是封裝一個(gè)js函數(shù),繪制對應(yīng)的線條路徑,這個(gè)軌跡點(diǎn)可能包括的信息有經(jīng)度、緯度、速度、時(shí)間、是否標(biāo)記、時(shí)間等信息,寫個(gè)結(jié)構(gòu)體封裝下,方便后期拓展,是否標(biāo)記的含義是是否改點(diǎn)同時(shí)作為一個(gè)設(shè)備點(diǎn)添加,分段線的含義。

后面陸續(xù)增加了可以設(shè)置旋轉(zhuǎn)角度、可以過濾坐標(biāo)點(diǎn)這兩個(gè)要點(diǎn),設(shè)置旋轉(zhuǎn)角度采用的是內(nèi)置的setRotation函數(shù),流程是先從一堆覆蓋物中通過唯一標(biāo)識比如name找到當(dāng)前要移動(dòng)的點(diǎn),然后對這個(gè)標(biāo)注點(diǎn)調(diào)用setRotation設(shè)置要旋轉(zhuǎn)的角度值,所以這里衍生了另外一個(gè)需求,如何計(jì)算兩個(gè)點(diǎn)之間的旋轉(zhuǎn)角度值,這個(gè)值必須是提前計(jì)算好的,這就要用到數(shù)學(xué)知識了,用atan2來計(jì)算,同時(shí)做矯正。

二、功能特點(diǎn)

定時(shí)器排隊(duì)下載省市輪廓圖點(diǎn)坐標(biāo)集合存儲到JS文件。

支持一個(gè)行政區(qū)域多個(gè)不規(guī)則區(qū)域下載。

自動(dòng)計(jì)算行政區(qū)域的下載輪廓數(shù)量。

可精確選擇省份、市區(qū)、縣城,也可直接輸入行政區(qū)域的名稱。

可以設(shè)置下載間隔、隨時(shí)開始下載和停止下載。

提供編輯邊界功能,可以直接在地圖上編輯好不規(guī)則區(qū)域的點(diǎn)集合,然后獲取邊界點(diǎn)集合數(shù)據(jù),這個(gè)可以用來自己繪制區(qū)域拿到數(shù)據(jù),比如某個(gè)鄉(xiāng)鎮(zhèn)甚至某個(gè)小區(qū)的行政區(qū)域數(shù)據(jù),很牛逼。

三、體驗(yàn)地址

體驗(yàn)地址:https://pan.baidu.com/s/15ZKAlptW-rDcNq8zlzdYLg  提取碼:uyes 文件名:bin_map.zip

國內(nèi)站點(diǎn):https://gitee.com/feiyangqingyun

國際站點(diǎn):https://github.com/feiyangqingyun

四、效果圖

五、相關(guān)代碼

void frmMapGps::receiveDataFromJs(const QString &type, const QVariant &data)
{
    if (data.isNull()) {
        return;
    }

    //qDebug() << "frmMapGps" << type << data;
    QString result = data.toString();
    if (type == "point") {
        if (ui->ckSelectAddr->isChecked()) {
            //判斷哪里勾選了就設(shè)置到哪里
            QString point = WebHelper::getLngLat2(result);
            //判斷哪里勾選了就設(shè)置到哪里
            if (ui->rbtnStartAddr->isChecked()) {
                ui->txtStartAddr->setText(point);
            } else {
                ui->txtEndAddr->setText(point);
            }
        }
    } else if (type == "routepoints") {
        //將查詢路徑轉(zhuǎn)換成經(jīng)緯度坐標(biāo)點(diǎn)集合數(shù)據(jù)顯示
        routeDatas.clear();
        ui->tableWidgetSource->clearContents();
        //可能會(huì)有多個(gè)路徑集合,目前測試下來都是一個(gè)路徑集合
        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) {
        //找出和上一個(gè)點(diǎn)之間的角度
        int angle = 0;
        QString point = tableWidget->item(row, 1)->data(Qt::UserRole).toString();
        //第一個(gè)點(diǎn)和最后一個(gè)點(diǎn)不用處理
        if (row > 0 && row < count - 1) {
            //上一個(gè)點(diǎn)坐標(biāo)
            QString point2 = tableWidget->item(row - 1, 1)->data(Qt::UserRole).toString();
            //計(jì)算當(dāng)前上一個(gè)點(diǎn)和當(dāng)前點(diǎn)的旋轉(zhuǎn)角度
            angle = WebHelper::getAngle(point2, point);
        }

        //執(zhí)行移動(dòng)設(shè)備點(diǎn)函數(shù),參數(shù)帶旋轉(zhuǎn)角度
        QString js = QString("moveMarker('%1', '%2', %3)").arg(name).arg(point).arg(angle);
        runJs(js);

        //重新繪制軌跡點(diǎn)
        if (ui->cboxMoveMode->currentIndex() == 0) {
            //清空之前的軌跡點(diǎn)
            js = QString("deleteOverlay('Polyline')");
            runJs(js);

            //取出第一個(gè)點(diǎn)到當(dāng)前焦點(diǎn)所在行的點(diǎn)組成已經(jīng)走過的軌跡點(diǎn)集合重新繪制
            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);
        }

        //顯示當(dāng)前第幾個(gè)數(shù)據(jù)
        setInfo(angle, row + 1, count);
        tableWidget->setCurrentCell(row + 1, 0);
    } else {
        on_btnTestData_clicked();
    }
}

void frmMapGps::on_btnTestData_clicked()
{
    QTableWidget *tableWidget = getTableWidget();
    if (ui->btnTestData->text() == "模擬軌跡") {
        //限制最小數(shù)量
        if (tableWidget->rowCount() < 2) {
            return;
        }

        //第一步: 添加一個(gè)標(biāo)記
        name = ui->txtDeviceName->text().trimmed();
        if (name.isEmpty()) {
            name = "馬航MH370";
        }

        //圖片文件在可執(zhí)行文件下的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);

        //第二步: 移到第一個(gè)點(diǎn)
        tableWidget->setFocus();
        tableWidget->setCurrentCell(0, 0);
        ui->btnTestData->setText("停止模擬");
        ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, false);

        //第三步: 啟動(dòng)定時(shí)器并立即執(zhí)行一次
        int index = ui->cboxMoveInterval->currentIndex();
        timer->start(ui->cboxMoveInterval->itemData(index).toInt());
        moveMarker();
    } else {
        //清空標(biāo)記
        QString js = QString("deleteMarker('%1')").arg(name);
        runJs(js);

        //停止定時(shí)器
        timer->stop();
        ui->btnTestData->setText("模擬軌跡");
        ui->tabWidget->setTabEnabled(ui->tableWidgetSource->isVisible() ? 1 : 0, true);
    }
}

void frmMapGps::on_btnCheckData_clicked()
{
    if (timer->isActive()) {
        return;
    }

    //第一步: 計(jì)算總數(shù),求平均值=實(shí)際總數(shù)/預(yù)期總數(shù)+1,預(yù)期總數(shù)>=實(shí)際總數(shù)則不用處理
    int countSource = ui->tableWidgetSource->rowCount();
    int countTarget = ui->txtPointCount->text().trimmed().toInt();
    if (countTarget >= countSource) {
        QUIHelper::showMessageBoxError("目標(biāo)點(diǎn)數(shù)不能大于等于原數(shù)據(jù)點(diǎn)數(shù)!");
        ui->txtPointCount->setFocus();
        return;
    }

    //第二步: 根據(jù)平均值挨個(gè)取出值
    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;
    }

    //必須加上末尾這個(gè)作為結(jié)束,如果剛好除盡則不用
    QString point = ui->tableWidgetSource->item(countSource - 1, 1)->data(Qt::UserRole).toString();
    if (points.last() != point) {
        points << point;
    }

    //第三步: 將數(shù)據(jù)重新填入篩選數(shù)據(jù)列表
    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("請先單擊查詢路線獲取路線的坐標(biāo)點(diǎn)集合!");
        return;
    }

    //清空之前的軌跡點(diǎn)
    runJs("deleteOverlay('Polyline')");

    //將收到的路徑點(diǎn)集合分線段繪制
    foreach (QStringList data, routeDatas) {
        QString points = data.join("|");
        QString js = QString("addPolyline('%1', '#ff0000')").arg(points);
        runJs(js);
    }
}

以上就是Qt編寫地圖實(shí)現(xiàn)實(shí)時(shí)動(dòng)態(tài)軌跡效果的詳細(xì)內(nèi)容,更多關(guān)于Qt地圖實(shí)時(shí)動(dòng)態(tài)軌跡的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C語言數(shù)組全面詳細(xì)講解

    C語言數(shù)組全面詳細(xì)講解

    數(shù)組是一組有序的數(shù)據(jù)的集合,數(shù)組中元素類型相同,由數(shù)組名和下標(biāo)唯一地確定,數(shù)組中數(shù)據(jù)不僅數(shù)據(jù)類型相同,而且在計(jì)算機(jī)內(nèi)存里連續(xù)存放,地址編號最低的存儲單元存放數(shù)組的起始元素,地址編號最高的存儲單元存放數(shù)組的最后一個(gè)元素
    2022-05-05
  • Qt實(shí)現(xiàn)卡牌對對碰游戲(附demo)

    Qt實(shí)現(xiàn)卡牌對對碰游戲(附demo)

    本文主要介紹了Qt實(shí)現(xiàn)卡牌對對碰游戲,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-10-10
  • 解析C++無鎖隊(duì)列的實(shí)現(xiàn)代碼

    解析C++無鎖隊(duì)列的實(shí)現(xiàn)代碼

    本篇文章是對C++無鎖隊(duì)列的實(shí)現(xiàn)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • VC++中HTControl控件類之CHTRichEdit富文本編輯控件實(shí)例

    VC++中HTControl控件類之CHTRichEdit富文本編輯控件實(shí)例

    這篇文章主要介紹了VC++中HTControl控件類之CHTRichEdit富文本編輯控件,是一個(gè)比較實(shí)用的功能,需要的朋友可以參考下
    2014-08-08
  • Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    Qt?TCP網(wǎng)絡(luò)通信學(xué)習(xí)

    用于數(shù)據(jù)傳輸?shù)牡蛯泳W(wǎng)絡(luò)協(xié)議,多個(gè)物聯(lián)網(wǎng)協(xié)議都是基于TCP協(xié)議的,這篇文章為大家介紹了Qt?TCP網(wǎng)絡(luò)通信,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語言怎么獲得進(jìn)程的PE文件信息

    C語言怎么獲得進(jìn)程的PE文件信息

    這篇文章主要介紹了C語言怎么獲得進(jìn)程的PE文件信息的相關(guān)代碼,需要的朋友可以參考下
    2016-01-01
  • 解析為何要關(guān)閉數(shù)據(jù)庫連接,可不可以不關(guān)閉的問題詳解

    解析為何要關(guān)閉數(shù)據(jù)庫連接,可不可以不關(guān)閉的問題詳解

    本篇文章是對為何要關(guān)閉數(shù)據(jù)庫連接,可不可以不關(guān)閉的問題進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • C++實(shí)現(xiàn)惡搞電腦關(guān)機(jī)小程序的示例代碼

    C++實(shí)現(xiàn)惡搞電腦關(guān)機(jī)小程序的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用C++實(shí)現(xiàn)一個(gè)簡單的惡搞電腦關(guān)機(jī)小程序,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以嘗試一下
    2022-11-11
  • C語言超詳細(xì)講解指針的使用

    C語言超詳細(xì)講解指針的使用

    C語言這門課程在計(jì)算機(jī)的基礎(chǔ)教學(xué)中一直占有比較重要的地位,然而要想突破C語言的學(xué)習(xí),對指針的掌握是非常重要的,本文將具體針對指針的基礎(chǔ)做詳盡的介紹
    2022-05-05
  • C++基于消息隊(duì)列的多線程實(shí)現(xiàn)示例代碼

    C++基于消息隊(duì)列的多線程實(shí)現(xiàn)示例代碼

    這篇文章主要給大家介紹了關(guān)于C++基于消息隊(duì)列的多線程實(shí)現(xiàn)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04

最新評論