腾讯地图JavaScript API的应用
目录
前言
随着社会的高速发展,手机地图已经成为了生活中不可或缺的一部分,他出现在各种app中,比如外卖app需要展示配送的路线和距离,导航的app需要路线规划和显示路线拥挤情况,社交app需要显示自己所在的位置和附近用户的位置。基本上只要你做的产品涉及到地图板块,你都需要引进相关地图api。那么对于开发者来说,怎么使用地图的api来完成我们的功能点就变的至关重要啦,这篇博客就讲解下腾讯地图JavaScript API的应用。
正文
注册腾讯位置服务账号
点击上面的链接,填写注册信息,点击注册按钮进行注册即可
完成开发者验证,即可进行注册key
设置秘钥
获取秘钥
腾讯地图的开发文档
针对不同的平台,腾讯地图的api还是很全的
腾讯地图的JavaScript API
这里具体看下JavaScript API ,这是一个官方给的demo,如何创建地图,并设置地图初始化的参数,我们在源代码编辑器里去随意改变下参数,点击运行就出现代码运行的效果,很方便开发者理解这个功能的参数的作用和效果,而且贴心的还写了备注。
腾讯地图demo
一、使用场景,查询出发地到目的地路线规划,我们先看下路线规划的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="https://map.qq.com/api/gljs?v=1.exp&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"></script>
<style>
html,
body {
height: 100%;
margin: 0px;
padding: 0px;
}
#mapContainer {
width: 100%;
height: 100%;
}
</style>
<body onload="initMap()">
<div id="mapContainer"></div>
</body>
</html>
<script>
//注:本例仅为说明流程,不保证严谨
var map;
function initMap(){
//初始化地图
map = new TMap.Map('mapContainer', {
center: new TMap.LatLng(39.980619,116.321277),//地图显示中心点
zoom:14 //缩放级别
});
//WebServiceAPI请求URL(驾车路线规划默认会参考实时路况进行计算)
var url="https://apis.map.qq.com/ws/direction/v1/driving/"; //请求路径
url+="?from=39.984039,116.307630"; //起点坐标
url+="&to=39.977263,116.337063"; //终点坐标
url+="&output=jsonp&callback=cb" ; //指定JSONP回调函数名,本例为cb
url+="&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77"; //开发key,可在控制台自助创建
//发起JSONP请求,获取路线规划结果
jsonp_request(url);
}
//浏览器调用WebServiceAPI需要通过Jsonp的方式,此处定义了发送JOSNP请求的函数
function jsonp_request(url){
var script=document.createElement('script');
script.src=url;
document.body.appendChild(script);
}
//定义请求回调函数,在此拿到计算得到的路线,并进行绘制
function cb(ret){
var coords = ret.result.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]));
}
display_polyline(pl)//显示路线
//标记起终点marker
var marker = new TMap.MultiMarker({
id: 'marker-layer',
map: map,
styles: {
"start": new TMap.MarkerStyle({
"width": 25,
"height": 35,
"anchor": { x: 16, y: 32 },
"src": 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/start.png'
}),
"end": new TMap.MarkerStyle({
"width": 25,
"height": 35,
"anchor": { x: 16, y: 32 },
"src": 'https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/end.png'
})
},
geometries: [{
"id": 'start',
"styleId": 'start',
"position": new TMap.LatLng(39.984039,116.307630307503)
}, {
"id": 'end',
"styleId": 'end',
"position": new TMap.LatLng(39.977263,116.337063)
}]
});
}
function display_polyline(pl){
//创建 MultiPolyline显示折线
var polylineLayer = new TMap.MultiPolyline({
id: 'polyline-layer', //图层唯一标识
map: 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': pl
}
]
});
}
</script>
二、具体的demo的代码
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>腾讯地图</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<style type="text/css">
* {
margin: 0;
padding: 0;
}
#container {
/*地图(容器)显示大小*/
width: 100%;
height: 100%;
z-index: 1;
}
.searchWrap {
position: absolute;
top: 30px;
left: 30px;
z-index: 2;
}
#list-group,
#list-group2,
.searchEnd {
display: none;
}
#closeBtn {
position: absolute;
top: -10px;
right: -14px;
}
.dropdown-menu .list-group-item.active{
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
</style>
<!--引入Javascript API GL,参数说明参见下文-->
<script src="https://map.qq.com/api/gljs?v=1.exp&key=HMQBZ-XC7KD-WZ64J-PFOQM-CFMT6-HUBOX"></script>
</head>
<!-- 页面载入后,调用init函数 -->
<body>
<!-- 定义地图显示容器 -->
<div id="container"></div>
<div class="searchWrap">
<div class="searchStart">
<div class="input-group mb-3">
<input type="text" autocomplete="off" id="search" class="form-control strtSiteIpt" placeholder="请输入地点"
aria-describedby="basic-addon1">
<div class="input-group-append">
<span class="input-group-text" id="basic-addon1">搜索</span>
</div>
</div>
<ul class="list-group" id="list-group">
<li class="list-group-item"></li>
</ul>
</div>
<div class="searchEndWrap">
<div class="searchEnd">
<div class="input-group mb-3">
<input type="text" autocomplete="off" id="search2" class="form-control strtSiteIpt" placeholder="请输入地点"
aria-describedby="basic-addon2">
<div class="input-group-append">
<span class="input-group-text" id="basic-addon2" style="position: relative;">搜索<button class="close" id="closeBtn"><span aria-hidden="true">×</span></button></span>
</div>
</div>
<ul class="list-group" id="list-group2">
<li class="list-group-item"></li>
</ul>
</div>
</div>
<div class="btn-group">
<button type="button" id="pathLineSearch" class="btn btn-primary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
路线
</button>
<!-- <div class="dropdown-menu">
<span data-val="driving" class="pathLineBtn list-group-item active">驾车</span>
<span data-val="walking" class="pathLineBtn list-group-item ">步行</span>
<span data-val="bicycling" class="pathLineBtn list-group-item ">骑行</span>
<span data-val="transit" class="pathLineBtn list-group-item ">公交</span>
</div> -->
</div>
</div>
</body>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns"
crossorigin="anonymous"></script>
<script>
$(function () {
//定义地图中心点坐标
var center = new TMap.LatLng(39.984120, 116.307484)
//定义map变量,调用 TMap.Map() 构造函数创建地图
var map = new TMap.Map(document.getElementById('container'), {
center: center,//设置地图中心点坐标
zoom: 4, //设置地图缩放级别
// pitch: 43.5, //设置俯仰角
// rotation: 45 //设置地图旋转角度
});
let markerLayer = new TMap.MultiMarker({
id: 'marker-layer',
map: map
});
function addMarker(latLng, id) {
markerLayer.add({
id: id,
position: latLng
});
var lng = latLng.lng
var lat = latLng.lat
// map.newLatLngZoom(new TMap.LatLng(lng,lat), 14);
}
//移除marker事件
function removeMarker(id) {
if (id) {
markerLayer.remove(id)
}
}
function display_polyline(pl) {
//创建 MultiPolyline显示折线
let polylineLayer = new TMap.MultiPolyline({
id: 'polyline-layer', //图层唯一标识
map: 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': pl
}
]
});
}
// 添加路线
function addlineLayer(res) {
var coords = res.result.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]));
}
display_polyline(pl)//显示路线
}
let searchStartArr = [] // 开始地点数据
let searchStartVal = null
let searchEndArr = [] // 结束地点数据
let searchEndVal = null
let pathLineWay = 'driving' // 路线默认方式
// 搜索开始点
$('body').on('input', '#search',
function (e) {
var search = $('#search').val()
clearTimeout(window.setTimeOutSearch1)
window.setTimeOutSearch1 = setTimeout(() => {
searchStartArr = []
if (search === "") {
$('#list-group').hide()
} else {
$('#list-group').show()
}
$('#list-group').html(`<li class="list-group-item" id="0">
<span class="lleft">正在努力查找中<span>
<span class="lright"><span>
</li>`)
$.ajax({
type: "get",
url: "https://apis.map.qq.com/ws/place/v1/suggestion",
data: {
'keyword': search,
'key': 'HMQBZ-XC7KD-WZ64J-PFOQM-CFMT6-HUBOX',
'output': 'jsonp'
},
//key换成自己的
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "TXmap",
headers: {
'Content-Type': 'application/json'
},
success: function (response) {
if (response.status !== 0) {
console.log('请求失败')
return
}
searchStartArr = response.data
let html = ''
response.data.forEach(item => {
html += `
<li class="list-group-item" id="${item.id}">
<span class="lleft">${item.title}<span>
<span class="lright">${item.address}<span>
</li>
`
});
$('#list-group').html(html)
}
});
}, 200)
}
)
$('.searchStart').on('click', '.list-group-item', function (e) {
if (searchStartVal !== null) {
removeMarker([searchStartVal.id])
}
let target = null
if ($(e.target).attr('class') === "list-group-item") {
target = $(e.target)
} else {
target = $(e.target).parents('.list-group-item')
}
searchStartVal = searchStartArr.find(item => {
return item.id == target.attr('id')
})
$('#search').val(searchStartVal.title)
$('#list-group').hide()
addMarker(searchStartVal.location, searchStartVal.id)
})
$('#basic-addon1').click(function() {
addMarker(searchStartVal.location, searchStartVal.id)
})
// 搜索结束点
$('body').on('input', '#search2',
function (e) {
let search = $('#search2').val()
clearTimeout(window.setTimeOutSearch2)
window.setTimeOutSearch2 = setTimeout(() => {
searchEndArr = []
if (search === "") {
$('#list-group2').hide()
} else {
$('#list-group2').show()
}
$('#list-group2').html(`<li class="list-group-item" id="0">
<span class="lleft">正在努力查找中<span>
<span class="lright"><span>
</li>`)
$.ajax({
type: "get",
url: "https://apis.map.qq.com/ws/place/v1/suggestion",
data: {
'keyword': search,
'key': 'HMQBZ-XC7KD-WZ64J-PFOQM-CFMT6-HUBOX',
'output': 'jsonp'
},
//key换成自己的
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "TXmap",
headers: {
'Content-Type': 'application/json'
},
success: function (response) {
if (response.status !== 0) {
console.log('请求失败')
return
}
searchEndArr = response.data
let html = ''
response.data.forEach(item => {
html += `
<li class="list-group-item" id="${item.id}">
<span class="lleft">${item.title}<span>
<span class="lright">${item.address}<span>
</li>
`
});
$('#list-group2').html(html)
}
});
}, 200)
}
)
$('.searchEndWrap').on('click', '.list-group-item', function (e) {
if (searchEndVal !== null) {
removeMarker([searchEndVal.id])
}
let target = null
if ($(e.target).attr('class') === "list-group-item") {
target = $(e.target)
} else {
target = $(e.target).parents('.list-group-item')
}
searchEndVal = searchEndArr.find(item => {
return item.id == target.attr('id')
})
$('#search2').val(searchEndVal.title)
$('#list-group2').hide()
addMarker(searchEndVal.location, searchEndVal.id)
})
$('#basic-addon2').click(function() {
addMarker(searchEndVal.location, searchEndVal.id)
})
// 路径搜索
$('#pathLineSearch').click((e) => {
if($(".searchEnd").is(":hidden")) {
$('.searchEnd').show()
return
}
if (searchStartVal === null) {
alert('请输入结束出发地')
return
}
if (searchEndVal === null) {
alert('请输入结束目的地')
return
}
$.ajax({
type: "get",
url: "https://apis.map.qq.com/ws/direction/v1/" + pathLineWay + "/",
data: {
"from": searchStartVal.location.lat + ',' + searchStartVal.location.lng,
"from_poi": searchStartVal.id,
"to": searchEndVal.location.lat + ',' + searchEndVal.location.lng,
"to_poi": searchEndVal.id,
'key': 'HMQBZ-XC7KD-WZ64J-PFOQM-CFMT6-HUBOX',
'output': 'jsonp'
},
//key换成自己的
dataType: "jsonp",
jsonp: "callback",
jsonpCallback: "TXmap",
headers: {
'Content-Type': 'application/json'
},
success: function (response) {
addlineLayer(response)
}
});
})
$('.pathLineBtn').click(function() {
$('.pathLineBtn').removeClass('active')
$(this).addClass('active')
pathLineWay = $(this).attr('data-val')
})
$('#closeBtn').click(function() {
if (searchEndVal !== null) {
removeMarker([searchEndVal.id])
}
$('.searchEnd').hide()
searchEndArr = []
searchEndVal = null
})
});
</script>
</html>
总结
这里我就抛转引玉下,总体感觉腾讯位置服务上手还是很快的,api还是很完善的,示例的注解也相对完善,注册简便这块我是真的喜欢,毕竟对于程序员来说,最喜欢简单,简单的界面,简洁的代码,都让开发者心情无比舒畅。
感兴趣的小伙伴,或者做自己项目用到地图的小伙伴们赶紧注册用用吧!有问题大家还能一起讨论!
我是阿达,一名喜欢分享知识的程序员,时不时的也会荒腔走板的聊一聊电影、电视剧、音乐、漫画,这里已经有16496位小伙伴在等你们啦,感兴趣的就赶紧来点击关注我把,哪里有不明白或有不同观点的地方欢迎留言!