本人所在的公司最近在做共享电动车的项目,打开该应用看到的就是一副地图,可以获取附近共享电动车的地址、状态等信息,开发这个应用程序还需要在地图上规划路线、动态显示轨迹、轨迹回放等功能。共享开发的项目功能总会用到LBS(Location Based Service),即基于位置的服务,国内提供地图服务的有百度地图、高德地图、腾讯地图,本文选取的是腾讯位置服务来进行地图功能的开发。
二、使用步骤
1.uniapp开发map说明
使用uniapp是因为它是一个使用vue.js开发所有前端应用的框架,开发者编写一套代码,可以发布到ios,android,web以及各种小程序,快应用等多个平台。
使用map地图组件开发,地图组件用于展示地图(使用的时腾讯地图),说一下它的属性有:
longitude(类型为Number,没有默认值,表示中心经度)
latitude(类型为Number,没有默认值,表示中心纬度)
scale(类型为Number,默认值为16,缩放级别取值范围为5-18)
markers(类型为Array数组,类型为数组即表示地图上可以有多个,没有默认值,表示标记点)
polyline(类型为Array数组,没有默认值,表示路线,数组上的所有点连成线)
circles(类型Array数组,表示圆)
controls(类型Array数组,表示控件)
include-points(类型Array数组,表示缩放视野已包含所有给定的坐标点)
enable-3D(类型为Boolean,默认值为false,表示是否显示3D搂块)
show-compass(类型为Boolean,默认值为false,表示为是否显示指南针)
enable-overlooking(类型为Boolean,默认值为false,表示为是否开启俯视)
enable-satellite(类型为Boolean,默认值为false,表示为是否开启卫星图)
enable-traffic(类型为Boolean,默认值为false,表示为是否开启实时路况)
show-location(类型为Boolean,表示显示带有方向的当前定位点)
polygons(类型Array,表示为多边形)
点击属性
- @markertap-表示点击标记点时触发,e.detail={markerId}
- @labeltap-表示点击label时触发,e.detail = {markerId}
- @callouttap-表示点击标记点对应的气泡时触发,e.detail = {markerId}
- @controltap-表示点击控件时触发,e.detail = {controlId}
- @regionchange-表示视野发生变化时触发
- @tap-表示点击地图时触发; App-nuve、微信小程序2.9支持返回经纬度
- @updated-表示在地图渲染更新完成时触发
我们在写map组件时,组件的宽/高推荐写直接量,比如说是 750rpx,不要设置百分比值,在uni-app中只支持gcj02坐标。
介绍markers属性-类型为数组Array
由之前描述可知,markers属性类型为Array,表示标记点用于在地图上显示标记的位置。这个数组属性,它里面有它的对象配置属性,分别是:
- id,表示标记点id,类型为Number,必填项,marker点击事件回调会返回此id,建议为每个marker设置上Number类型id,保证更新marker时有更好的性能。
- latitude,纬度,类型Number,必填项,浮点数,范围 -90 ~ 90
- longitude,经度,类型Number,必填项,浮点数,范围 -180 ~ 180
- title,标注点名,类型String,不是必填,点击时显示,callout存在时将被忽略
- iconPath,显示的图标,类型String,必填项,项目目录下的图片路径
- rotate,旋转角度,类型Number,不是必填,顺时针旋转的角度,范围 0 ~ 360,默认为 0
- alpha,标注的透明度,类型Number,不是必填,默认1,无透明,范围 0 ~ 1
- width,标注图标宽度,类型Number,不是必填,默认为图片实际宽度
- height,标注图标高度,类型Number,不是必填,默认为图片实际高度
- callout,自定义标记点上方的气泡窗口,类型Object,不是必填 – 可识别换行符
- label,为标记点旁边增加标签,类型Object,不是必填 – 可识别换行符
- anchor,经纬度在标注图标的锚点,默认底边中点,不是必填,{x, y},x表示横向(0-1),y表示竖向(0-1)。{x: .5, y: 1} 表示底边中点
marker 上的气泡 callout(Object类型)
marker数组 上属性 callout 对象使用属性:
- content,文本,String
- color,文本颜色,String
- fontSize,文字大小,Number
- borderRadius,callout边框圆角,Number
- bgColor,背景色,String
- padding,文本边缘留白,Number
- display,‘BYCLICK’:点击显示; ‘ALWAYS’:常显,String
- textAlign,文本对齐方式。有效值: left, right, center,String
marker 上的标签 label(Object类型)
- content,文本,String
- color,文本颜色,String
- fontSize,文字大小,Number
- x,label的坐标,原点是 marker 对应的经纬度,Number
- y,label的坐标,原点是 marker 对应的经纬度,Number
- borderWidth,边框宽度,Number
- borderColor,边框颜色,String
- borderRadius,边框圆角,Number
- bgColor,背景色,String
- padding,文本边缘留白,Number
- textAlign,文本对齐方式。有效值: left, right, center,String
polyline
polyline表示指定一系列坐标点,从数组第一项连线至最后一项
- points,经纬度数组,类型为Array,必填,如:[{latitude: 0, longitude: 0}]
- color,线的颜色,类型为String,不必填,如:#0000AA
- width,线的宽度,类型为Number,不必填
- dottedLine,是否虚线,类型为Boolean,不必填,默认值false
- arrowLine,带箭头的线,类型为Boolean,不必填,默认值为false
- arrowIconPath,更换箭头图标,类型为String,不必填,在arrowLine为true时,默认带箭头的线时生效
- borderColor,线的边框颜色,类型为String,不必填
- borderWidth,线的厚度,类型为Number,不必填
polygon
polygon指定一系列坐标点,根据points坐标数据生成闭合多边形 - points,经纬度数组,array,必填,如:[{latitude: 0, longitude: 0}]
- strokeWidth,描边的宽度,Number,否
- strokeColor 描边的颜色,String,否
- fillColor,填充颜色,String,否
- zIndex,设置多边形 Z 轴数值,Number,否
circles
circles在地图上显示圆
- latitude,纬度,Number,必填,浮点数,范围 -90 ~ 90
- longitude,经度,Number,必填,浮点数,范围-180 ~ 180
- color,描边的颜色,String,不必填,如:#0000AA
- fillColor,填充颜色,String,不必填,如:#0000AA
- radius,半径,Number,必填
- strokeWidth,描边的宽度,Number,不必填
controls
controls在地图上显示控件,控件不随着地图移动 - id,控件id,Number,不必填,在控件点击事件回调会返回此id
- position,控件在地图的位置,Object,必填,控件相对地图位置
- iconPath,显示的图标,String,必填,项目目录下的图片路径,支持相对路径写法,以’/'开头则表示相对项目根目录;也支持临时路径
- clickable,是否可点击,Boolean,不必填,默认不可点击
position - left,距离地图的左边界多远,Number,不必填,默认为0
- top,距离地图的上边界多远,Number,不必填,默认为0
- width,控件宽度,Number,不必填,默认为图片宽度
- height,控件高度,Number,不必填,默认为图片高度
注意在uniapp中地图组件的经纬度必填,如果不填,经纬度则默认值是北京的经纬度。
2.uniapp使用map组件
基本使用方法
使用uniapp开发中的map组件,基本使用方法:
代码如下(示例):
<map :scale="scale" style="width: 100%; height: 100%;"
enable-3D="false" show-compass="false" enable-overlooking="false"
:enable-satellite="false" :enable-traffic="false" show-location="false"
:latitude="latitude" :longitude="longitude" :markers="covers">
</map>
markers属性的使用,代码如下(示例):
markers: [{id: 1, // Numbertitle: '1', // String-标注点名rotate: 180, // Number - 顺时针旋转的角度,范围 0 ~ 360,默认为 0alpha: 0.5, // 默认1,无透明,范围 0 ~ 1latitude: 39.899,longitude: 116.39742,width: 30,height: 30,// callout: {// display: "BYCLICK",// padding: 10,// borderRadius: 5,// content: '',// },// anchor: {},iconPath: '../../../static/location.png', // 显示的图标
}, {id: 2,title: '2', // Stringlatitude: 39.90,longitude: 116.39,callout: {color: '#007AFF', // 文本颜色bgColor: '#563BFF', // 背景色display: "ALWAYS", // 'BYCLICK':点击显示; 'ALWAYS':常显fontSize: 15,textAlign: 'left', // 文本对齐方式。有效值: left, right, centerpadding: 10, // 文本边缘留白borderRadius: 5,content: '腾讯地图',},label: {content: 'Jeskson',color: '#000000',fontSize: 12,borderWidth: 12,borderColor: '#007AFF',borderRadius: 5,padding: 5,textAlign: 'center',bgColor: '#563BFF',},iconPath: '../../../static/location.png'
}]
controls:[{// 在地图上显示控件,控件不随着地图移动id: 1, // 控件idiconPath:'../../static/icon.png', // 显示的图标position:{// 控件在地图的位置left: 15,top: 15,width: 50,height: 50},
}],
地址搜索
uni-app 只支持 gcj02 坐标
uni.getLocation(OBJECT)中的object参数
获取当前的地理位置、速度。 在微信小程序中,当用户离开应用后,此接口无法调用,除非申请后台持续定位权限;当用户点击“显示在聊天顶部”时,此接口可继续调用。
OBJECT参数说明
- type,String,不必填,默认为 wgs84 返回 gps 坐标,gcj02 返回国测局坐标,可用于
uni.openLocation 的坐标,app平台高德SDK仅支持返回gcj02 - altitude,Boolean,不必填,传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度
- geocode,Boolean,不必填,默认false,是否解析地址信息
- success,Function,必填,接口调用成功的回调函数,返回内容详见返回参数说明
- fail,Function,不必填,接口调用失败的回调函数
- complete,Function,不必填,接口调用结束的回调函数(调用成功、失败都会执行)
对于success返回参数说明:
- latitude,纬度,浮点数,范围为-90~90,负数表示南纬
- longitude,经度,浮点数,范围为-180~180,负数表示西经
- speed,速度,浮点数,单位m/s
- accuracy,位置的精确度
- altitude,高度,单位 m
- verticalAccuracy,垂直精度,单位 m(Android 无法获取,返回 0)
- horizontalAccuracy,水平精度,单位 m
- address,地址信息(仅App端支持,需配置geocode为true)
address 地址信息说明
- country,String,国家 如“中国”,没有则返回undefined
- province,String,省份名称 如“北京市”,没有则返回undefined
- city,String,城市名称,如“北京市”,没有则返回undefined
- district,String,区,县名称 如“朝阳区”,没有则返回undefined
- street,String,街道信息,如“酒仙桥路”,没有则返回undefined
- streetNum,String,获取街道门牌号信息,如“3号”,没有则返回undefined
- poiName,String POI信息,如“电子城.国际电子总部”,没有则返回undefined
- postalCode,String,邮政编码,如“100016”,没有则返回undefined
- cityCode,String,城市代码,如“010”,没有则返回undefined
uni.chooseLocation(OBJECT)打开地图选择位置。
- latitude,String,不必填,目标地纬度
- longitude,String,不必填,目标地经度
- keyword,String,不必填,搜索关键字,仅App平台支持
- success,Function,必填
- fail,Function,不必填
- complete,Function,不必填
success返回参数说明:
- name,位置名称
- address,详细地址
- latitude,纬度,浮点数,范围为-90~90,负数表示南纬,使用 gcj02 国测局坐标系。
- longitude,经度,浮点数,范围为-180~180,负数表示西经,使用 gcj02 国测局坐标系。
代码如下(示例):
chooseLocation(e) { //打开地图选择位置uni.chooseLocation({success: res => {console.log('位置名称:' + res.name);console.log('详细地址:' + res.address);console.log('纬度:' + res.latitude);console.log('经度:' + res.longitude);uni.getLocation({type: 'gcj02',altitude:true,geocode:true,success: function(res) {console.log('当前位置的经度:' + res.longitude);console.log('当前位置的纬度:' + res.latitude);}});console.log('省:' + res.address.slice(0, res.address.indexOf('省') + 1));console.log('市:' + res.address.slice(res.address.indexOf('省') + 1, res.address.indexOf('市') + 1));console.log('区:' + res.address.slice(res.address.indexOf('市') + 1, res.address.indexOf('区') + 1));this.query.address = res.address;this.query.latitude = res.latitude;this.query.longitude = res.longitude;this.query.province = res.address.slice(0, res.address.indexOf('省') + 1)this.query.city = res.address.slice(res.address.indexOf('省') + 1, res.address.indexOf('市') + 1)this.query.district = res.address.slice(res.address.indexOf('市') + 1, res.address.indexOf('区') + 1)}});
},
获取附近的动态,点聚合
uni.getNetworkType(OBJECT)获取网络类型。
uni.createMapContext(mapId,this)创建并返回 map 上下文 mapContext 对象。在自定义组件下,第二个参数传入组件实例this,以操作组件内 组件。
mapContext-mapContext 通过 mapId 跟一个 组件绑定,通过它可以操作对应的 组件。
该对象得方法列表:
- getCenterLocation OBJECT 获取当前地图中心的经纬度,返回的是 gcj02 坐标系,可以用于 uni.openLocation
- moveToLocation OBJECT 将地图中心移动到当前定位点,需要配合map组件的show-location使用
- translateMarker OBJECT 平移marker,带动画
- includePoints OBJECT 缩放视野展示所有经纬度
- getRegion OBJECT 获取当前地图的视野范围
- getScale OBJECT 获取当前地图的缩放级别
- $getAppMap 获取原生地图对象 plus.maps.Map
getCenterLocation 的 OBJECT 参数列表
success Function 不必填,接口调用成功的回调函数 ,res = { longitude: “经度”, latitude: “纬度”}
moveToLocation 的 OBJECT 参数列表 – 可不必填
translateMarker 的 OBJECT 参数列表
-
markerId Number 必填 指定 marker
-
destination Object 必填 指定 marker 移动到的目标点
-
autoRotate Boolean 不必填 移动过程中是否自动旋转 marker
-
rotate Number 不必填 marker 的旋转角度
-
duration Number 不必填 动画持续时长,默认值1000ms,平移与旋转分别计算
-
animationEnd Function 不必填 动画结束回调函数
-
fail Function 不必填 接口调用失败的回调函数
代码如下(示例):
地图上标注附近的人
代码如下(示例):
list: [{id: 1264640,user_id: 335187,place: "Jeskson市",text: "dadaqianduan.cn",latitude: "27.267520",longitude: "111.727120",status: "normal",nickname: "dada",avatar: "https://image.aishencn.com/2020/10/20/002207441_40845724-user.jpg",distance: 13419,
}, {id: 1272720,user_id: 36950,place: "dadaqianduan市",text: "dadaqianduan.cn",latitude: "27.257640",longitude: "111.747910",deletetime: null,status: "normal",nickname: "dadaqianduan",avatar: "https://image.aishencn.com/2020/04/09/004135379_37869100-user.jpg",distance: 27070,
}, {id: 1316740,user_id: 366172,place: "dadaqianduan.cn",text: "dadaqianduan.cn",images: "https://image.aishencn.com/2020/11/04/215134979_98197351-bbs.jpg",latitude: "27.257430",longitude: "111.732960",status: "normal",nickname: "dada",avatar: "https://image.aishencn.com/2020/11/04/182622730_98197351-user.venus/cache/ext/crop/1604518314542_jpg",distance: 27190,images_arr: ["https://image.aishencn.com/2020/11/04/215134979_98197351-bbs.jpg"]
}],
定位附近门店
代码如下(示例):
// 两点间距离
distance(la1, lo1, la2, lo2) {var La1 = (la1 * Math.PI) / 180.0var La2 = (la2 * Math.PI) / 180.0var La3 = La1 - La2var Lb3 = (lo1 * Math.PI) / 180.0 - (lo2 * Math.PI) / 180.0var s =2 *Math.asin(Math.sqrt(Math.pow(Math.sin(La3 / 2), 2) +Math.cos(La1) * Math.cos(La2) * Math.pow(Math.sin(Lb3 / 2), 2)))s = s * 6378.137 //地球半径s = Math.round(s * 10000) / 10000return s
},
// 计算最近的距离
nearDistance(array, centerLatitude, centerLongitude) {let temp = []for (let i = 0, l = array.length; i < l; i++) {const element = array[i]let d = this.distance(element.latitude,element.longitude,centerLatitude,centerLongitude)temp.push(d)}this.distanceL = Math.min.apply(null, temp)
}
滑动轨迹
代码如下(示例):
<map :polyline="polyline" :scale="scale" id="maps" :markers="markers" :latitude="center.latitude"
:longitude="center.longitude">
</map>// 播放标记点
playMarkars() {if (this.polyline.length == 0) {uni.showModal({content: '当前时间范围内没有轨迹,无法播放!',})this.isPlay = false // 无this.playIndex = 0 // 第一个return}this.playIndex = Math.min(this.points.length - 1, this.playIndex)this.markers = [this.formatMarker(this.points[this.playIndex++], 'ALWAYS')]this.timer = setInterval(_ => {var i = this.playIndex++this.nextAdaress(i);if (i >= this.points.length) {clearInterval(this.timer)this.isPlay = falsethis.playIndex = 0this.initMarkers()return}this.markers = [this.formatMarker(this.points[i], 'ALWAYS')]}, 1000)
},formatMarker(point, display = "BYCLICK") {let content = ["时间:" + parseTime(point.create_time),"运动状态:" + (point.sport == 1 ? '运动' : '静止'),"地址:" + point.address || '']return {id: point.id,iconPath: '/static/dada.png',width: 35,height: 35,latitude: point.latitude,longitude: point.longitude,callout: {display: display,padding: 10,borderRadius: 5,content: content.join("
")}}
},
nextAdaress(index) {const len = 10;if (this.isGetAddress) {return}for (let i = 0; i < len; i++) {if (!this.points[i + index]) {break}if (this.points[i + index].address === undefined) {this.isGetAddress = truethis.getAddress(i + index, len * 2, _ => {this.isGetAddress = false});break}}
},
vue接入腾讯地图接口
腾讯(推荐)
https://apis.map.qq.com/ws/location/v1/ip={$ip}&key={$key}
需要申请key,速度快,有基本信息
首页点击可以进行注册,申请一个获取key:
key管理,创建新密钥,填写相应信息即可
1.创建地图预览效果图如下:
<script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=申请的key"></script><script type="text/javascript">function initMap() {var center = new TMap.LatLng(39.984104, 116.307503);//初始化地图var map = new TMap.Map("container", {rotation: 20,//设置地图旋转角度pitch:30, //设置俯仰角度(0~45)zoom:12,//设置地图缩放级别center: center//设置地图中心点坐标});}
</script>
<script>function initMap() {//初始化地图var map = new TMap.Map("container", {center: new TMap.LatLng(39.984104, 116.307503)});//监听地图瓦片加载完成事件map.on("tilesloaded", function () {document.getElementById("tip").innerHTML = "地图瓦片已加载完成"})}
</script>
3.异步加载地图
<script>function initMap() {var map = new TMap.Map("container", {pitch: 45,zoom: 12,center: new TMap.LatLng(39.984104, 116.307503)});}function loadScript() {//创建script标签,并设置src属性添加到body中var script = document.createElement("script");script.type = "text/javascript";script.src = "https://map.qq.com/api/gljs?v=1.exp&key=申请key";document.body.appendChild(script);}window.onload = loadScript;</script>
<script>function initMap() {//初始化地图一var mapOne = new TMap.Map("containerOne", {pitch:45,center: new TMap.LatLng(39.984104, 116.307503)});//初始化地图二var mapTwo = new TMap.Map("containerTwo", {center: new TMap.LatLng(39.984104, 116.307503)});}
</script>
<script>var centerInfo = document.getElementById("center-info");var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标//初始化地图var map = new TMap.Map("container", {center: center});//获取地图中心点事件function getCenter() { var mapCenter = map.getCenter(); //获取地图中心点坐标centerInfo.innerHTML = "当前地图中心为: " + mapCenter.getLat().toFixed(6) + "," + mapCenter.getLng().toFixed(6);}//设置地图中心点事件function setCenter() {map.setCenter(new TMap.LatLng(39.908802,116.397502));//坐标为天安门centerInfo.innerHTML = "当前地图中心为: 39.908802,116.397502";}
</script>
<script>function initMap() {var position = document.getElementById("position");var txt = document.getElementById("txt");var center = new TMap.LatLng(39.984104, 116.307503);//设置中心点坐标//初始化地图var map = new TMap.Map("container", {center: center});location.innerHTML = map.getCenter().toString();//监听地图开始平移map.on("panstart", function () {txt.innerHTML = "地图开始平移"})//监听地图平移map.on("pan",function(){txt.innerHTML = "地图正在平移";position.innerHTML = map.getCenter().toString();//获取地图中心点})//监听地图平移结束map.on("panend",function(){txt.innerHTML = "地图结束平移";})}
</script>
3.vue接入腾讯地图
<template><div><div id="map" style="width:500px;height:500px;"></div></div>
</template><script>
export default {data() {return {longitude: "",latitude: ""};},methods: {init() {let address = "";let that = this;var center = new qq.maps.LatLng(34.754152, 113.667636);var map = new qq.maps.Map(document.getElementById('map'), {center: center,zoom: 13,disableDefaultUI: true});var marker = new qq.maps.Marker({position: center,map: map});var infoWin = new qq.maps.InfoWindow({map: map});var geocoder = new qq.maps.Geocoder({complete: function(res) {console.log(res);address = res.detail.nearPois[0].name;}});qq.maps.event.addListener(map, "click", function(event) {this.longitude = event.latLng.getLat();this.latitude = event.latLng.getLng();console.log(event);let lat = new qq.maps.LatLng(this.longitude, this.latitude);geocoder.getAddress(lat);setTimeout(() => {infoWin.open();infoWin.setContent('<div style="text-align:center;white-space:nowrap;">' +address +"</div>");infoWin.setPosition(event.latLng);}, 200);});}},mounted() {this.init();}
};
</script>
<style scoped>
</style>
使用前需要在index.html里引入才可以使用地图。
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=yourkey"></script>
<template><div><div id="container" style="width:500px;height:500px;"></div></div>
</template><script>export default{data() {return {longitude:39.956987, // 经度latitude:116.235128 // 纬度}},mounted () {this.init();},methods:{init() {var myLatlng = new qq.maps.LatLng(39.945687,116.3976968);var myOptions = {zoom: 8, // 设置地图缩放级别center: myLatlng, // 设置中心点样式mapTypeId: qq.maps.MapTypeId.ROADMAP }var map = new qq.maps.Map(document.getElementById("container"), myOptions);}}}
</script>
创建地图实例
var map=new qq.maps.Map(document.getElement('container'),{
center,//坐标,即最初显示的地图中心
zoom //缩放级别,即显示的比例
})
给地图添加事件
qq.maps.event.addListener(map,'click',function(res){
// res即点击后的位置信息
})
添加标记
var marker=new qq.maps.Marker({
position, // 标记点的位置,也可以是通过IP获取到的坐标
map, // 标记在哪个地图上
animation, // 标记显示时的动画效果
title, // 鼠标悬浮到标记上时的标题
draggable // 是否可拖拽
})
创建信息窗口
var info=new qq.maps.InfoWindow({
map, // 标记在哪个地图上
content // 信息窗口的内容
})
覆盖物
var polyline=new qq.maps.Polyline({
map, // 标记在哪个地图上
path, // 一个坐标数组,折线、多边形就是依靠这些坐标数组来成形的
strokeColor, // 折线颜色
strokeDashStyle, // 折线样式
strokeWeight, // 折线宽度
editable, // 折线是否可编辑
clickable // 是否可点击
})
单个标注点
在mounted生命周期或者从后台接口获得信息后调用初始化地图方法
initMap (latitude, longitude, message) {var center = new qq.maps.LatLng(latitude, longitude);var map = new qq.maps.Map(document.getElementById("container"),{center: center,zoom: 13});var marker = new qq.maps.Marker({position: center,map: map});var info = new qq.maps.InfoWindow({map: map});// 悬浮标记显示信息qq.maps.event.addListener(marker, 'mouseover', function() { info.open();info.setContent(`<div style="margin:10px;">${message}</div>`);info.setPosition(center);});qq.maps.event.addListener(marker, 'mouseout', function() {info.close();});
},
多个标注点
markers: [ ]; // 标记点数组mounted () {this.initMap(this.markers)
},initMap (arr) {// 默认以数组第一项为中心var center = new qq.maps.LatLng(arr[0].latitude, arr[0].longitude);var map = new qq.maps.Map(document.getElementById("container"),{center: center,zoom: 13});// 提示窗var info = new qq.maps.InfoWindow({map: map});for (var i = 0; i < arr.length; i++) {var data = arr[i];var marker = new qq.maps.Marker({ position: new qq.maps.LatLng(data.latitude, data.longitude), map: map });marker.id = data.id;marker.name = data.name;// 点击事件qq.maps.event.addListener(marker, 'mouseover', function() {info.open();// 设置提示窗内容info.setContent(`<div><p>${this.name}</p></div>`);// 提示窗位置 info.setPosition(new qq.maps.LatLng(this.position.lat, this.position.lng));});qq.maps.event.addListener(marker, 'mouseout', function() {info.close(); });}
}
4.个性化地图样式
为什么要用个性化地图,提高不同场景下地图的展现效果和用户体验。
为什么选择腾讯位置服务个性化地图:
- 全平台通用
- 开发成本极小
- 个性化样式支持动态更新
- 支持全局配置和分级配置
- 编辑平台UI控件全面优化
- 每个元素可配置的属性全部开放
- 能够支持自定义的地图元素扩充为52种
5.腾讯位置入门步骤
2.验证手机 与 邮箱
3.申请开发密钥(Key)
4.选择您需要的产品
三.微信小程序JavaScript SDK
1.我申请了开发者密钥key
2.开通webserviceAPI服务:控制台 -> key管理 -> 设置(使用该功能的key)-> 勾选webserviceAPI -> 保存
(小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需要具备相应的权限)
日调用量:1万次 / Key—-并发数:5次 / key / 秒 。
onLoad() {console.log('页面加载了')// 实例化API核心类qqmapsdk = new QQMapWX({// key: '申请的key'});
},
onShow() {console.log('页面显示了')// 调用接口dadaqianduanqqmapsdk.search({keyword: '酒店',success: (res) => {console.log(res);},fail: (err) => {console.log(err);},complete: (cres) => {console.log(cres);}})
},
我返回的数据如图:
QQMapWX – 小程序JavaScriptSDK核心类 – new QQMapWX(options:Object)
// 引入SDK核心类
var QQMapWX = require('xxx/qqmap-wx.js');// 实例化API核心类
var demo = new QQMapWX({key: '开发密钥(key)' // 必填
});
地点搜索:
// 地点搜索
nearbySearchBtn() {qqmapsdk.search({keyword: 'kfc', //搜索关键词location: '39.980014,116.313972', //设置周边搜索中心点success: (res) => {var mks = []for (var i = 0; i < res.data.length; i++) {mks.push({ // 获取返回结果,放到mks数组中title: res.data[i].title,id: res.data[i].id,latitude: res.data[i].location.lat,longitude: res.data[i].location.lng,iconPath: "/location.png", //图标路径width: 20,height: 20})}this.markers = mks},fail: (res) => {console.log(res);},complete: (res) => {console.log(res);}});
},
<script>// 引入SDK核心类,js文件根据自己业务,位置可自行放置// var QQMapWX = require('../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js');import QQMapWX from '../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js';var qqmapsdk;export default {components: {},data() {return {backfill: '',markers: [],suggestion: [],}},onLoad() {console.log('页面加载了') // 实例化API核心类qqmapsdk = new QQMapWX({ // key: '申请的key'key: '自己申请,我的就不放出来了'});},onShow() {console.log('页面显示了') // 调用接口dadaqianduanqqmapsdk.search({keyword: '酒店',success: (res) => {console.log(res);},fail: (err) => {console.log(err);},complete: (cres) => {console.log(cres);}})},onReady() {console.log('页面初次渲染完成了')},methods: {getsuggest(e) {console.log(e.detail.value)qqmapsdk.getSuggestion({keyword: e.detail.value, //用户输入的关键词,可设置固定值,如keyword:'KFC'//region:'北京', //设置城市名,限制关键词所示的地域范围,非必填参数success: (res) => {//搜索成功后的回调console.log(res);var sug = [];for (var i = 0; i < res.data.length; i++) {sug.push({ // 获取返回结果,放到sug数组中title: res.data[i].title,id: res.data[i].id,addr: res.data[i].address,city: res.data[i].city,district: res.data[i].district,latitude: res.data[i].location.lat,longitude: res.data[i].location.lng});}this.suggestion = sug},fail: (error)=> {console.error(error);},complete: (res)=> {console.log(res);}});},backfillBtn(e) {var id = e.currentTarget.id;for (var i = 0; i < this.suggestion.length; i++) {if (i == id) {this.backfill = this.suggestion[i].title}}},// 地点搜索nearbySearchBtn() {qqmapsdk.search({keyword: 'kfc', //搜索关键词location: '39.980014,116.313972', //设置周边搜索中心点success: (res) => {var mks = []for (var i = 0; i < res.data.length; i++) {mks.push({ // 获取返回结果,放到mks数组中title: res.data[i].title,id: res.data[i].id,latitude: res.data[i].location.lat,longitude: res.data[i].location.lng,iconPath: "/static/location.png", //图标路径width: 20,height: 20})}this.markers = mks},fail: (res) => {console.log(res);},complete: (res) => {console.log(res);}});},},onHide() {console.log('页面隐藏了')},}
</script>
<script>import QQMapWX from '../../js_sdk/wxmp-qqmap/qqmap-wx-jssdk.js';var qqmapsdk;export default {components: {},data() {return {backfill: '',markers: [],poi: {latitude: 39.984060,longitude: 16.307520},}},onLoad() {console.log('页面加载了') // 实例化API核心类qqmapsdk = new QQMapWX({ // key: '申请的key'key: ''});},onShow() {console.log('页面显示了')},onReady() {console.log('页面初次渲染完成了')},methods: {formSubmit(e) {qqmapsdk.reverseGeocoder({location: e.detail.value.reverseGeo || '',//获取表单传入的位置坐标,不填默认当前位置,示例为string格式//get_poi: 1, //是否返回周边POI列表:1.返回;0不返回(默认),非必须参数success: (res) => {console.log(res);var res = res.result;var mks = [];/*** 当get_poi为1时,检索当前位置或者location周边poi数据并在地图显示,可根据需求是否使用*for (var i = 0; i < result.pois.length; i++) {mks.push({ // 获取返回结果,放到mks数组中title: result.pois[i].title,id: result.pois[i].id,latitude: result.pois[i].location.lat,longitude: result.pois[i].location.lng,iconPath: './resources/placeholder.png', //图标路径width: 20,height: 20})}***///当get_poi为0时或者为不填默认值时,检索目标位置,按需使用mks.push({ // 获取返回结果,放到mks数组中title: res.address,id: 0,latitude: res.location.lat,longitude: res.location.lng,iconPath: '/static/location.png', //图标路径width: 20,height: 20,callout: { //在markers上展示地址名称,根据需求是否需要content: res.address,color: '#000',display: 'ALWAYS'}});this.markers = mks;// this.poi = {// latitude: res.location.lat,// longitude: res.location.lng// }},fail: (error) => {console.error(error);},complete: (res) => {console.log(res);}})}},onHide() {console.log('页面隐藏了')},}
</script>
geocoder – 提供由地址描述到所述位置坐标的转换,与逆地址解析reverseGeocoder()的过程正好相反。
预览效果如图:
formSubmit(e) {//调用地址解析接口qqmapsdk.geocoder({//获取表单传入地址 e.detail.value.geocoderaddress: e.detail.value, //地址参数,例:固定地址,address: '北京市海淀区彩和坊路海淀西大街74号'success: (res)=> {//成功后的回调console.log(res);var res = res.result;var latitude = res.location.lat;var longitude = res.location.lng;//根据地址解析在地图上标记解析地址位置this.markers = [{id: 0,title: res.title,latitude: latitude,longitude: longitude,iconPath: '/static/location.png',//图标路径width: 20,height: 20,callout: { //可根据需求是否展示经纬度content: latitude + ',' + longitude,color: '#000',display: 'ALWAYS'}}],this.poi= { //根据自己data数据设置相应的地图中心坐标变量名称latitude: Number(latitude),longitude: Number(longitude),}},fail: (error)=> {console.error(error);},complete: (res)=> {console.log(res);}})
}
formSubmit(e){//调用距离计算接口console.log(this.start,'dadaqianduan')qqmapsdk.calculateDistance({//mode: 'driving',//可选值:'driving'(驾车)、'walking'(步行),不填默认:'walking',可不填//from参数不填默认当前地址//获取表单提交的经纬度并设置from和to参数(示例为string格式)// from: e.detail.value.start || '', //若起点有数据则采用起点坐标,若为空默认当前地址from: this.start || '',to: this.end,// to: e.detail.value.dest, //终点坐标success: (res)=> {//成功后的回调console.log(res);var res = res.result;var dis = [];for (var i = 0; i < res.elements.length; i++) {dis.push(res.elements[i].distance); //将返回数据存入dis数组,}this.distance=dis},fail: (error)=> {console.error(error);},complete: (res)=> {console.log(res);}});}
},
onShow() {console.log('页面显示了')//调用获取城市列表接口qqmapsdk.getCityList({success: (res) => { //成功后的回调console.log(res);console.log('省份数据:', res.result[0]); //打印省份数据this.a = res.result[0]console.log('城市数据:', res.result[1]); //打印城市数据this.b = res.result[1]console.log('区县数据:', res.result[2]); //打印区县数据this.c = res.result[2]},fail: (error) => {console.error(error);},complete: (res) => {console.log(res);}});
},
onShow() {console.log('页面显示了')//调用获取城市列表接口qqmapsdk.getCityList({success: (res) => { //成功后的回调console.log(res);console.log('省份数据:', res.result[0])var city = res.result[0];//根据对应接口getCityList返回数据的Id获取区县数据(以北京为例)qqmapsdk.getDistrictByCityId({// 传入对应省份ID获得城市数据,传入城市ID获得区县数据,依次类推id: city[0].id, //对应接口getCityList返回数据的Id,如:北京是'110000'success: (res) => { //成功后的回调console.log(res);console.log('对应城市ID下的区县数据(以北京为例):', res.result[0]);},fail: (error) => {console.error(error);},complete: (res) => {console.log(res);}});},fail: (error) => {console.error(error);},complete: (res) => {console.log(res);}});
},
腾讯位置服务为微信小程序提供了基础的标点能力、线和圆的绘制接口等地图组件和位置展示、地图选点等地图API位置服务能力支持,使得开发者可以自由地实现自己的微信小程序产品。 在此基础上,腾讯位置服务微信小程序JavaScript SDK是专为小程序开发者提供的LBS数据服务工具包,可以在小程序中调用腾讯位置服务的POI检索、关键词输入提示、地址解析、逆地址解析、行政区划和距离计算等数据服务,让您的小程序更强大!