X-MagicBox-820的luatOS之路連載系列6

繼上次用Qt實現了顯示地圖和MQTT通訊之後(X-MagicBox-820的luatOS之路連載系列5),說是要研究下地圖的開放介面,也看了標記點和線的方法(地圖上自定義標記點和軌跡線的實現)。這次就來調試剩下的部分:GPS數據在地圖上的呈現。

下圖就是測試的結果

 

 

 這個軌跡的測試還是讓家裡小閨女幫助完成的

 

結合之前的基礎,實現圖上的軌跡標記主要兩個技術點。一是Qt的WebEngineView模組實現C++層面與HTML層面的通訊,二是JS數據的解析。

(1)增加派生類WebClass,用來在JS中訪問。

class WebClass : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString content MEMBER m_content NOTIFY contentChanged) //該屬性可由頁面訪問

public:
    WebClass(){};
    QString getContent(){return m_content;}
signals:
    void contentChanged(QString nc);

private:
    QString m_content;
};

(2)WebChannel的實例化,註冊JS的訪問對象。

 webch = new QWebChannel(this);
    webobj = new WebClass();
    webch->registerObject("webobj", webobj);
    ui->widget->page()->setWebChannel(webch);

 (3)在MQTT消息槽內更新註冊類的變數內容。

connect(m_client, &QMqttClient::messageReceived, this, [this](const QByteArray &message, const QMqttTopicName &topic) {
         const QString content = message;
         //qDebug() << content;
         webobj->setProperty("content",  message);
     });

二、JavaScript程式碼的實現:

(1)獲取Qt中的對象的值

//這裡的webChannel是全局的變數,可以在其它位置訪問
  var webChannel = new QWebChannel(qt.webChannelTransport,    
  function(channel){
  var webobj = channel.objects.webobj;
  
    webobj.contentChanged.connect(updateattribute);
  });

(2)解析更新的變數,就是上面updateattribute的函數體實現,同時地圖的標記過程也在該函數內實現。

var updateattribute=function(text)
{  
    //截取所需數據
    var str = [];
    str = text.split(',');
    pointx = str[0].slice(1);
    pointy = str[1].slice(1);
    //根據第一個點確定位置,地圖的初始顯示
    if(isPoint){
      isPoint = false;
      //初始位置
      var pinit = new BMapGL.Point(pointx, pointy); 
      map.centerAndZoom(pinit, 15); 
    }else{
      
    }    
    //gps點集
    var data = [];
    data[0] = pointx;
    data[1] = pointy;
    point.push(data);
    
    var rPoint = new BMapGL.Point(point[point.length-1][0],point[point.length-1][1]);
    bPoints.push(rPoint);
    //更新標記點
    marker = new BMapGL.Marker(rPoint); // 創建點 
    map.addOverlay(marker);
    
    //更新連線
    if(point.length > 1){
      var polyline = new BMapGL.Polyline([ 
        new BMapGL.Point(point[point.length-2][0],point[point.length-2][1]),
        new BMapGL.Point(point[point.length-1][0],point[point.length-1][1]),
      ], {strokeColor:"red", strokeWeight:5, strokeOpacity:0.5});   //創建折線 
      map.addOverlay(polyline);
    }  

    setZoom(bPoints);    
  
  }

(3)為了提升觀察體驗,添加自動縮放顯示的處理。

 // 根據點的數組自動調整縮放級別
    function setZoom(bPoints) {
        var view = map.getViewport(eval(bPoints));
        var mapZoom = view.zoom;
        var centerPoint = view.center;
        map.centerAndZoom(centerPoint, mapZoom);
    }
    map.addControl(new BMapGL.MapTypeControl());
    map.enableScrollWheelZoom(true);

三、完成以上程式碼的調試,就可以實際測試了。這裡不方便上傳影片,搜索微信影片號 懂一點技術的老王 瀏覽完成影片。

抽空完善下推到Github上,有興趣的朋友們可以看看。歡迎關注和交流
 

 

Tags: