qml调用百度地图api实现卫星地球模式画路书轨迹
总结下类型转换:
pro文件中加入依赖的模块
这里我对工作中matlab的程序需要实现的功能进行讲解:
QT += qml quick webview webchannel websockets webengine
引入头文件 websockettransport.h
#ifndef WEBSOCKETTRANSPORT_H
#define WEBSOCKETTRANSPORT_H
#include <QWebChannelAbstractTransport>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>
class WebSocketTransport : public QWebChannelAbstractTransport
{
Q_OBJECT
public:
Q_INVOKABLE void sendMessage(const QJsonObject &message) override
{
QJsonDocument doc(message);
emit messageChanged(QString::fromUtf8(doc.toJson(QJsonDocument::Compact)));
}
Q_INVOKABLE void textMessageReceive(const QString &messageData)
{
QJsonParseError error;
QJsonDocument message = QJsonDocument::fromJson(messageData.toUtf8(), &error);
if (error.error)
{
qWarning() << "Failed to parse text message as JSON object:" << messageData
<< "Error is:" << error.errorString();
return;
} else if (!message.isObject())
{
qWarning() << "Received JSON message that is not an object: " << messageData;
return;
}
emit messageReceived(message.object(), this);
}
signals:
void messageChanged(const QString & message);
};
#endif // WEBSOCKETTRANSPORT_H
main文件加入
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QGuiApplication>
#include <QtWebView>
#include <QWebChannel>
#include <QWebSocketServer>
#include "./include/websockettransport.h"
int main(int argc, char *argv[])
{
// QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
// QCoreApplication::setAttribute(Qt::AA_UseOpenGLES);
QApplication app(argc, argv);
// don't forget about this
QtWebView::initialize();
qmlRegisterType<WebSocketTransport>("io.decovar.WebSocketTransport", 1, 0, "WebSocketTransport");
QSurfaceFormat format;
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 2);
format.setProfile(QSurfaceFormat::CoreProfile);
QSurfaceFormat::setDefaultFormat(format);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
if (engine.rootObjects().isEmpty()){
QMessageBox::warning(NULL, "Warning!", "qml加载异常!");
return -1;
}
return app.exec();
}
qml
QtObject {
id: someObject
WebChannel.id: "backend"
property string someProperty: "qml data"
signal someSignal(var wxName, var dataLen, var jd, var wd);
signal beginPlay(var order);
function changeText(newText) {
return "New text length: ";
}
}
WebSocketTransport {
id: transport
}
WebSocketServer {
id: server
listen: true
port: 55222
onClientConnected: {
if(webSocket.status === WebSocket.Open) {
channel.connectTo(transport)
webSocket.onTextMessageReceived.connect(transport.textMessageReceive)
transport.onMessageChanged.connect(webSocket.sendTextMessage)
}
}
onErrorStringChanged: {
console.log(qsTr("Server error: %1").arg(errorString));
}
Component.onCompleted: {
console.log(server.url + "已连接");
}
}
WebView {
id: webView
anchors.fill: parent
anchors.margins: 5
url: "qrc:/map/index.html"
onLoadingChanged: {
if (loadRequest.errorString)
{ console.error(loadRequest.errorString); }
}
}
WebChannel {
id: channel
registeredObjects: [someObject]
}
//给前端wx图 这是一个cpp给qml发的信号
onShowWx: {
someObject.someSignal(wxName, dataLen, jd, wd);
}
需要注意的是不能将webView画在如Rectangle类这种控件的里面,否则地图会出现跑点,3D图出不来等一系列问题,需要将其单独放在Page或者底层继承自widget类的控件中才行
index.html
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
body, html,#allmap {width: 100%;height: 100%;overflow: hidden;margin:0;font-family:"微软雅黑";}
</style>
<script type="text/javascript" src="http://api.map.baidu.com/api?type=webgl&v=1.0&ak=HDMmTOItpjjwIugxR3TNuPNmRqQrBWBl"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/LuShu/gl/src/LuShu_min.js"></script>
<script type="text/javascript" src="qrc:/js/qwebchannel.js"></script>
<title>地球模式</title>
</head>
<body>
<div id="allmap"></div>
</body>
</html>
<script type="text/javascript">
var img = document.createElement("img");
img.src = "../pic/卫星.png";
// 百度地图API功能
var map = new BMapGL.Map("allmap"); // 创建Map实例
map.centerAndZoom(new BMapGL.Point(118.5, 27.5), 5); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
map.setMapType(BMAP_EARTH_MAP); // 设置地图类型为地球模式
map.addControl(new BMapGL.ScaleControl()); // 添加比例尺控件
var wxMbData = {};
var polylineList = {};
// here will be our QtObject from QML side
var backend;
var someProperty;
function startLushu(polyline) {
var fly = 'data:image/png;base64,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';
lushu = new BMapGLLib.LuShu(map, polyline.getPath(), {
geodesic: true,
autoCenter: true,
icon: new BMapGL.Icon(fly, new BMapGL.Size(48, 48), { anchor: new BMapGL.Size(24, 24) }),
speed: 1000000,
enableRotation: true
});
setTimeout('lushu.start()', 4000);
}
window.onload = function()
{
var socket = new WebSocket("ws://127.0.0.1:55222");
socket.onopen = function()
{
new QWebChannel(socket, function(channel) {
backend = channel.objects.backend;
someProperty = backend.someProperty;
backend.beginPlay.connect(function(beginStr){
alert("begin play");
});
backend.someSignal.connect(function(wxName, dataLen, jd, wd) {
var j=0;
var maxLen = 0;
for(var i=0;i<wxName.length;i++){
var path = [];
maxLen = maxLen + dataLen[i];
for(j;j<maxLen;j++){
path.push(new BMapGL.Point(jd[j], wd[j]));
}
wxMbData[wxName[i]] = path;
var polyline = new BMapGL.Polyline(path, {
clip: false,
// geodesic: true,
strokeWeight: 1
});
polylineList[wxName[i]] = polyline;
map.addOverlay(polyline);
startLushu(polyline);
}
this.map.clearOverlay();
});
});
};
socket.onerror = function(evt)
{
alert("on error");
}
socket.onmessage = function (evt)
{
var received_msg = evt.data;
alert("Message is received: " + received_msg);
};
socket.onclose = function(evt)
{
alert("Connection is closed: " + evt.code + " - " + evt.reason);
};
}
</script>
注意
该文章仅个人学习使用,欢迎大家一起交流学习