继上次用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上,有兴趣的朋友们可以看看。欢迎关注和交流