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