Qt加载腾讯地图

该博客介绍了如何在Qt桌面应用中集成腾讯地图API,包括申请key、加载地图、数据传递和定位服务等关键步骤。通过QWebChannel实现Qt与JavaScript的数据交互,提供了详细的代码示例,涉及地图点击获取坐标、定位服务以及轨迹规划等功能。
摘要由CSDN通过智能技术生成

引言

地图是桌面客户端经常使用到的组件之一,诸如热点标记、轨迹规划等。多数情况下是使用js实现,通过QWebEngine将其加载嵌入Qt中,地图方面可以使用Ceisum或是其他三方库实现,也可以通过其他第三方服务商提供的成熟接口,诸如腾讯地图、高德地图等。本文使用的就是腾讯地图提供的API。

在这里插入图片描述

关键步骤

申请key

实际使用前需要先申请对应权限的key,保证服务的正常使用,如下图所示
在这里插入图片描述

加载地图

申请完key之后,需要加载在线API资源,调用接口即可。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>点击地图拾取坐标</title>
</head>
<script charset="utf-8" src="http://map.qq.com/api/gljs?v=1.exp&key=你的key"></script>
<script src="handleCmd.js"></script>
<script src="qwebchannel.js"></script>
<script src="jquery.min.js"></script>
<style type="text/css">
    html,
    body {
        height: 100%;
        margin: 0px;
        padding: 0px;
    }

    #container {
        width: 100%;
        height: 100%;
    }

    #info {
        position: absolute;
        left: 20px;
        top: 20px;
        font-size: 14px;
        background: #FFF;
        width: 270px;
        padding: 10px;
        border-radius: 3px;
    }
</style>

<body onload="initMap()">
    <div id="container"></div>
    <script>
        function initMap() {
            var position = document.getElementById("position");

            var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标
            // 初始化地图
            window.map = new TMap.Map("container", {
                center: center
            });

            // 绑定点击事件
            window.map.on("click", function (evt) {
                var lat = evt.latLng.getLat().toFixed(6);
                var lng = evt.latLng.getLng().toFixed(6);
                position.innerHTML = lat + "," + lng;
            })
        }
    </script>
    <div id="info">当前点击坐标为:<span id="position"></span></div>
</body>

</html>

数据传递

数据传递需要通过QWebChannel完成,数据从qt传递至js中选中的是通过信号传递,传递回来是通过槽函数。

qt代码如下:

class CustomWebWidget : public QWidget
{
    Q_OBJECT

public:
    CustomWebWidget(QWidget *parent = nullptr);
    ~CustomWebWidget();

signals:
    void sig_pickupLocation(double lat, double lng);
    void sig_currentLocation(double lat, double lng);
    void sig_keywordSearch(QList<QPair<QString, QPointF>> tmpList);
    void sig_clearPolylineLayer();

// 传递至web
signals:
    void sig_tips(QString str);
    void sig_setCenter(double lat, double lng);
    void sig_addMarker(double lat, double lng);
    void sig_requestCurrentLocation();
    void sig_requestKeywordSearch(QString str);
    void sig_requestRoutePlanning(QString startPos, QString endPos);

public slots:
    void slot_pickupLocation(double lat, double lng);
    void slot_currentLocation(double lat, double lng);
    void slot_keywordSearch(QJsonArray val);

private:
    class QWebEngineView* m_view;
    class QWebChannel* m_channel;
};
CustomWebWidget::CustomWebWidget(QWidget *parent)
    : QWidget(parent)
{
    m_view=new QWebEngineView(this);
    m_channel = new QWebChannel(this);
    m_channel->registerObject("webObject", this);
    m_view->page()->setWebChannel(m_channel);

    m_view->load(QUrl("file:///E:/JsTest/TencentMap/index.html"));
    //m_view->load(QUrl("http://127.0.0.1:8088"));

    auto mainLayout = new QHBoxLayout(this);
    mainLayout->addWidget(m_view);
}

CustomWebWidget::~CustomWebWidget()
{
    m_channel->deregisterObject(this);
}

void CustomWebWidget::slot_pickupLocation(double lat, double lng)
{
    emit sig_pickupLocation(lat, lng);
}

void CustomWebWidget::slot_currentLocation(double lat, double lng)
{
    emit sig_currentLocation(lat, lng);
}

void CustomWebWidget::slot_keywordSearch(QJsonArray val)
{
    QList<QPair<QString, QPointF>> tmpList;
    for(auto iter = val.begin(); iter != val.end(); iter++){
        QJsonObject tmpObj = iter->toObject();
        QJsonObject locationObj =tmpObj.value("location").toObject();
        tmpList << qMakePair(tmpObj.value("title").toString(), QPointF(locationObj.value("lat").toDouble(), locationObj.value("lng").toDouble()));
    }

    if(!tmpList.isEmpty())
        sig_keywordSearch(tmpList);
}

js代码如下:

// 创建通道对象并设置全局变量
new QWebChannel(qt.webChannelTransport, function (channel) {
    window.webObj = channel.objects.webObject;  //对象名与QT中一致
    window.webObj.sig_tips.connect(function (name) {
        alert(name);
    });
    window.webObj.sig_setCenter.connect(function (lat, lng) {
        window.map.setCenter(new TMap.LatLng(lat, lng));
    });
    window.webObj.sig_requestCurrentLocation.connect(function () {
        requestCurrtLocation();
    });
    window.webObj.sig_requestKeywordSearch.connect(function (keyword) {
        requestKeywordSearch(keyword);
    });
    window.webObj.sig_requestRoutePlanning.connect(function (startPos, endPos) {
        requestRoutePlanning(startPos, endPos);
    });
    window.webObj.sig_clearPolylineLayer.connect(function () {
        if (window.polylineLayer) {
            for (i in window.polylineLayer) {
                indow.polylineLayer[i].setMap(null);
            }
            window.polylineLayer.length = 0;
        }
     });
    window.webObj.sig_addMarker.connect(function (lat, lng) {
    window.markerLayer.add({
        position: new TMap.LatLng(lat, lng)
        });
    });
});

定位服务

定位服务主要是ip定位、地名搜索以及轨迹规划

var tencentToken = "你的key";

// http请求
function currentLocation(callback) {
    $.ajax({
        type: "get",//接口规定,只能用get
        async: true,//异步
        url: "https://apis.map.qq.com/ws/location/v1/ip",//接口地址
        data: { "key": tencentToken, "output": "jsonp" },
        dataType: "jsonp",//跨域,必须用到jsonp
        success: function (data) {
            if (typeof callback == "function") {
                callback(data.result.location);
            }
        },

        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log(JSON.stringify(XMLHttpRequest));
        }
    });
}

function keywordSearch(keyword, callback) {
    $.ajax({
        type: "get",//接口规定,只能用get
        async: true,//异步
        url: "https://apis.map.qq.com/ws/place/v1/suggestion",//接口地址
        data: { "key": tencentToken, "output": "jsonp", "keyword": keyword },
        dataType: "jsonp",//跨域,必须用到jsonp
        success: function (result) {
            if (typeof callback == "function") {
                callback(result.data);
            }
        },

        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log(JSON.stringify(XMLHttpRequest));
        }
    });
}

function routePlanning(startPos, endPos, callback) {
    $.ajax({
        type: "get",//接口规定,只能用get
        async: true,//异步
        url: "https://apis.map.qq.com/ws/direction/v1/walking",//接口地址
        data: { "key": tencentToken, "output": "jsonp", "from": startPos, "to": endPos },
        dataType: "jsonp",//跨域,必须用到jsonp
        success: function (data) {
            if (typeof callback == "function") {
                callback(data.result.routes);
            }
        },

        error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log(JSON.stringify(XMLHttpRequest));
        }
    });
}

// 请求函数
function requestCurrtLocation() {
    currentLocation(function (coordinate) {
        window.webObj.slot_currentLocation(coordinate.lat, coordinate.lng);
    });
}

function requestKeywordSearch(keyworkd) {
    keywordSearch(keyworkd, function (data) {
        window.webObj.slot_keywordSearch(data);
    });
}

function displayPolyline(pline){
	//创建 MultiPolyline显示折线
	var polylineLayer = new TMap.MultiPolyline({
		// id: 'polyline-layer', //图层唯一标识
		map: window.map,//绘制到目标地图
		//折线样式定义
		styles: {
			'style_blue': new TMap.PolylineStyle({
				'color': '#3777FF', //线填充色
				'width': 8, //折线宽度
				'borderWidth': 5, //边线宽度
				'borderColor': '#FFF', //边线颜色
				'lineCap': 'round', //线端头方式
			})
		},
		//折线数据定义
		geometries: [
			{
				'id': 'pl_1',//折线唯一标识,删除时使用
				'styleId': 'style_blue',//绑定样式名
				'paths': pline
			}
		]
	});
    window.polylineLayer.push(polylineLayer);
}

function requestRoutePlanning(startPos, endPos) {
    routePlanning(startPos, endPos, function (routes) {
        var coords = routes[0].polyline, pl = [];
        //坐标解压(返回的点串坐标,通过前向差分进行压缩)
        var kr = 1000000;
        for (var i = 2; i < coords.length; i++) {
          coords[i] = Number(coords[i - 2]) + Number(coords[i]) / kr;
        }
        //将解压后的坐标放入点串数组pl中
        for (var i = 0; i < coords.length; i += 2) {
          pl.push(new TMap.LatLng(coords[i], coords[i+1]));
        }
        
        displayPolyline(pl)//显示路线
    });
}

源码下载

Qt源码:https://download.csdn.net/download/weixin_42219627/87321644
Js源码:https://download.csdn.net/download/weixin_42219627/87321577

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Arui丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值