uniapp使用腾讯地图实现定位,选点,距离计算和导航功能

HelloWorld

以下为官方文档指引:

  1. 申请开发者密钥(key):申请密钥

  2. 开通webserviceAPI服务:控制台 ->应用管理 -> 我的应用 ->添加key-> 勾选WebServiceAPI -> 保存

    (小程序SDK需要用到webserviceAPI的部分服务,所以使用该功能的KEY需要具备相应的权限)

  3. 下载微信小程序JavaScriptSDK,微信小程序JavaScriptSDK v1.1   JavaScriptSDK v1.2

  4. 安全域名设置,在小程序管理后台 -> 开发 -> 开发管理 -> 开发设置 -> “服务器域名” 中设置request合法域名,添加https://apis.map.qq.com

  5. 小程序示例

// 引入SDK核心类,js文件根据自己业务,位置可自行放置
var QQMapWX = require('../../libs/qqmap-wx-jssdk.js');//引入下载好的sdk
var qqmapsdk;
Page({
 
    onLoad: function () {
        // 实例化API核心类
        qqmapsdk = new QQMapWX({
            key: '申请的key'
        });
    },
    onShow: function () {
        // 调用接口
        qqmapsdk.search({
            keyword: '酒店',
            success: function (res) {
                console.log(res);
            },
            fail: function (res) {
                console.log(res);
            },
        complete: function (res) {
            console.log(res);
        }
     });
  }
})

代码展示

总体代码
<template>
	<view>
		<view class="page-body">
			<view class="page-section page-section-gap map">
				<map @tap="getMapLocation" style="width: 100%; height: 426rpx;" :latitude="reportInfo.lttd"
					:longitude="reportInfo.lgtd" :markers="covers">
				</map>
			</view>
			<view class="item">
				<view class="content">
					<view class="desc solid-bottom row-info">
						<view class="text-black margin-top-sm overflow-2 item-title"><text
								class="cuIcon-location text-green text-xxl"></text>您当前所在位置: <text
								class="text-green">{{ plot.rough }}</text></view>
						<view class="text-black text-sm margin-top-sm overflow-2 item-content">
							系统已为您匹配到智能垃圾桶
						</view>
						<view class="item-content">
							编号:<text class="text-red">JN00405</text>
							<text style="margin-left: 58rpx;">距您:</text> <text class="text-red">{{distance}}</text>KM
						</view>
						<view class="uni-button-group">
							<button class="uni-button" @click="markertap"
								:styles="{'borderColor':'#678D5D'}">导航</button>
						</view>
					</view>
				</view>
			</view>
			<view class="m-footer">
					<view>
						<image src="../../static/img/garbage/xiao.png" class="sider-img" @click="showRules"></image>
					</view>
					<view class="img-footer">
						点我了解丢垃圾规则
					</view>
			</view>

		</view>
	</view>
</template>

<script>
	import QQMapWX from '../../utils/qqmap-wx-jssdk.js'
	const tMap = new QQMapWX({
		key: 'your key'
	})
	export default {
		data() {
			return {
				content:'(一)将回收价值高的可回收物率先分类投放,如报纸杂志、纸板箱、包装盒、PET塑料瓶、易拉罐等,确保这一类可回收物不被混合垃圾污染。(二)不要将已被污染、潮湿、污渍无法清除的物品投入可回收物收集容器,如被油渍污染的餐盒、食品包装盒等。瓶罐投放前倒空瓶内液体并简单清洗,有瓶盖的不需将瓶盖与瓶体分开投放,确保可回收物收集容器中的其他废品不被污染,尊重和维护他人分类的成果。(三)不确定是否可以回收(或本指引中未明确说明)的废纸、废塑料,在未被污染的情况下,请先投放至可回收物收集容器',
				// 默认坐标北京
				reportInfo: {
					lgtd: 116.39742,
					lttd: 39.909,
				},
				id: 0, // 使用 marker点击事件 需要填写id
				title: 'map',
				latitude: 39.909,
				longitude: 116.39742,
				//第一组为匹配的垃圾桶
				covers: [], //存放标记点数组
				isLocated: false,
				//小区
				plot: {},
				//详细地址
				address: '',
				//地址组成
				addressComponent: {
					city: "",
					district: "",
					nation: "",
					province: "",
					street: "",
					street_number: "",
				},
				distance:0.1,

			}
		},
		methods: {
			// 弹出垃圾规则提示框
			showRules(){
				uni.showModal({
					title: '请阅读以下规则',
					content: this.content,
					showCancel: false,
					confirmText: '我已了解',
					success: function(res) {
					}
				})
				
			},
			/**
			 * 获取经纬度并触发回调函数
			 * @param {Function} successCb 获取成功回调
			 * @param {Function} authDenyCb 获取失败回调
			 */
			getLocation(successCb, authDenyCb) {
				const self = this
				uni.getLocation({
					type: 'gcj02', // 'wgs84'默认gps 坐标 'gcj02'国测
					altitude: false, // 是否返回高度
					accuracy: 'best', // 精度值为20m
					geocode: true,
					success(res) {
						console.log(res)
						successCb && successCb(res)
						self.isLocated = true
						//获取经纬度
						self.reportInfo.lttd = res.latitude;
						self.reportInfo.lgtd = res.longitude;
						//标记地点
						var obj = {
							width: 30,
							height: 30,
							latitude: Number(self.reportInfo.lttd),
							longitude: Number(self.reportInfo.lgtd),
							iconPath: '../../static/img/garbage/loc.png'
						};
						//垃圾桶
						var bin = {
							id: "0",
							latitude: Number(30.89204),
							longitude: Number(120.086678),
							width: 20,
							height: 20,
							iconPath: '../../static/img/garbage/trash.png',
							title: "垃圾桶"
						};
						
						var bin2 = {
							id: "1",
							latitude: Number(32.097269),
							longitude: Number(118.91422),
							width: 20,
							height: 20,
							iconPath: '../../static/img/garbage/trash.png',
							title: "垃圾桶"
						}
						self.distance = self.getMapDistance(self.reportInfo.lttd,self.reportInfo.lgtd
						,32.097269,118.91422
						)
						var arr = [];
						arr.push(obj);
						arr.push(bin);
						arr.push(bin2);
						//标记点
						self.covers = arr;
					},
					fail(err) {
						if (
							err.errMsg ===
							'getLocation:fail 频繁调用会增加电量损耗,可考虑使用 wx.onLocationChange 监听地理位置变化'
						) {
							uni.showToast({
								title: '请勿频繁定位',
								icon: 'none'
							})
						}
						if (err.errMsg === 'getLocation:fail auth deny') {
							// 未授权
							uni.showToast({
								title: '无法定位,请重新获取位置信息',
								icon: 'none'
							})
							authDenyCb && authDenyCb()
							self.isLocated = false
						}
						if (err.errMsg === 'getLocation:fail:ERROR_NOCELL&WIFI_LOCATIONSWITCHOFF') {
							uni.showModal({
								content: '请开启手机定位服务',
								showCancel: false
							})
						}
					},
					complete() {
						console.log(self.reportInfo)
						tMap.reverseGeocoder({
							location: {
								latitude: self.reportInfo.lttd,
								longitude: self.reportInfo.lgtd
							},
							success: function(res) {
								console.log('解析地址成功');
								console.log(res);
								self.plot = res.result.formatted_addresses;
								self.address = res.result.address;
								self.addressComponent = res.result.address_component;
								// 省
								// let province = res.result.ad_info.province;
								// 市
								let city = res.result.ad_info.city;
								// console.log(province);
							},
							fail: function(res) {
								uni.showToast({
									title: '定位失败',
									duration: 2000,
									icon: 'none'
								});
								console.log(res);
							},
							complete: function(res) { //无论成功失败都会执行
								console.log(res);
							}
						});
					}
				})
			},
			/**
			 * 重新授权并调用定位方法
			 * @param {Function} successCb 授权成功回调
			 * @param {Function} authDenyCb 授权失败回调
			 */
			getAuthorize(successCb, authDenyCb) {
				uni.authorize({
					scope: 'scope.userLocation',
					success: () => {
						this.getLocation(successCb, authDenyCb)
					},
					fail: (err) => {
						err = err['errMsg']
						uni.showModal({
								content: '需要授权位置信息',
								confirmText: '确认授权'
							})
							.then((res) => {
								if (res[1]['confirm']) {
									uni.openSetting({
										success: (res) => {
											if (res.authSetting['scope.userLocation']) {
												// 授权成功
												uni.showToast({
													title: '授权成功',
													icon: 'none'
												})
											} else {
												// 未授权
												uni.showToast({
													title: '授权失败',
													icon: 'none'
												})
											}
											this.getLocation(successCb, authDenyCb)
										}
									})
								}
								if (res[1]['cancel']) {
									// 取消授权
									console.log('取消')
									this.getLocation(successCb, authDenyCb)
								}
							})
					}
				})
			},
			//手动动获取定位
			getMapLocation() {
				var that = this;
				uni.chooseLocation({
					success: (res) => {
						console.log(res)
						that.reportInfo.lttd = res.latitude;
						that.reportInfo.lgtd = res.longitude;
						var obj = {
							width: 30,
							height: 30,
							latitude: that.reportInfo.lttd,
							longitude: that.reportInfo.lgtd,
							iconPath: '../../static/img/garbage/loc.png'
						};
						var arr = [];
						arr.push(obj);
						that.covers = arr;
						console.log(that.covers, "that.covers")
					},
					complete() {
						console.log(that.reportInfo)
						tMap.reverseGeocoder({
							location: {
								latitude: that.reportInfo.lttd,
								longitude: that.reportInfo.lgtd
							},
							success: function(res) {
								console.log('解析地址成功');
								console.log(res);
								that.plot = res.result.formatted_addresses;
								that.address = res.result.address;
								that.addressComponent = res.result.address_component;
								// 省
								// let province = res.result.ad_info.province;
								// 市
								let city = res.result.ad_info.city;
								// console.log(province);
							},
							fail: function(res) {
								uni.showToast({
									title: '定位失败',
									duration: 2000,
									icon: 'none'
								});
								console.log(res);
							},
							complete: function(res) { //无论成功失败都会执行
								console.log(res);
							}
						});
					}
				})
			},
			//导航到指定位置 ltt lgt
			markertap() {
				let that = this
				//调出地图传入目的地 ltt lgt
				uni.getLocation({
					success: (res) => {
						uni.openLocation({
							latitude: Number(30.89204),
							longitude: Number(120.086678),
							name: 'JN00405号垃圾桶',
							address: '垃圾桶',
							success: function() {
								console.log('success');
							},
							fail: function() {
								uni.showModal({
									title: '错误',
									content: '请检查定位是否打开',
									showCancel: false,
									success: function(res) {
										if (res.confirm) {
											console.log('用户点击确定');
										} else if (res.cancel) {
											console.log('用户点击取消');
										}
									}
								})
							}
						});
					}
				})

			},
			//进行经纬度转换为距离的计算
			Rad(d) {
				return d * Math.PI / 180.0; //经纬度转换成三角函数中度分表形式。
			},

			/*
			 计算距离,参数分别为第一点的纬度,经度;第二点的纬度,经度
			 默认单位km
			*/
			getMapDistance(lat1, lng1, lat2, lng2) {
				console.log("in getMap")
				console.log(lat1)
				var radLat1 = this.Rad(lat1);
				var radLat2 = this.Rad(lat2);
				var a = radLat1 - radLat2;
				var b = this.Rad(lng1) - this.Rad(lng2);
				var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
					Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
				s = s * 6378.137; // EARTH_RADIUS;
				s = Math.round(s * 10000) / 10000; //输出为公里
				//s=s.toFixed(2);
				return s;
			},

		},
		components: {

		},
		onLoad() {
			console.log("in onload")
			this.getAuthorize()
		},
		onShow() {

		},
	}
</script>

<style>
	.map {
		border: 9rpx solid #678D5D;
		/* border-radius: 14rpx; */
	}

	.content {
		margin-top: 100rpx;
		width: 100%;
		height: 307rpx;
		border: 11rpx solid #;
		border-radius: 17rpx;
		/* color: white; */
		background-color: #ffffff;
	}

	.item {
		margin-top: 84rpx;
		border: 5px none #9E9E9E;
		border-radius: 25rpx;
		/* 		margin-left: 25rpx;
		margin-right: 25rpx; */
		box-shadow: 4px 4px 5px #999;
		padding-bottom: 30rpx;
		display: block;
		background-color: var(--white);
		overflow: hidden;
		font-weight: 700;
	}


	.item-title {
		height: 73rpx;
		/* border-bottom: 9rpx solid #678D5D; */
		margin-left: 30rpx;
		margin-right: 30rpx;
		font-size: 28rpx;
		margin-top: -48rpx;
	}

	.item-content {
		height: 62rpx;
		/* border: 3rpx solid #9E9E9E; */
		margin-left: 40rpx;
		margin-right: 40rpx;
		font-size: 34rpx;
		/* text-justify: initial; */
		/* font-style: solid; */
	}

	.uni-button-group {
		/* 		margin-top: 50px; */
		/* #ifndef APP-NVUE */
		display: flex;
		/* #endif */
		justify-content: center;
	}

	.uni-button {
		width: 228rpx;
		padding: 12px 20px;
		font-size: 14px;
		border-radius: 12px;
		line-height: 1;
		margin: 0;
		background-color: #678D5D;
		color: white;
	}

	.sider-img {
		width: 254rpx;
		height: 306rpx;
	}

	.m-footer {
		margin-top: 162rpx;
		margin-left: 482rpx;
	}

	.img-footer {
		margin-top: -50rpx;
		border-bottom: 9rpx solid #678D5D;
		width: 300rpx;
		font-weight: 700;
	}
</style>

1. 引入腾旭地图
import QQMapWX from '../../utils/qqmap-wx-jssdk.js'
//创建实列
const tMap = new QQMapWX({
key: 'your key'
})	
2. 实现用户定位功能
1. 获取用户地址
/**
 * 获取经纬度并触发回调函数
 * @param {Function} successCb 获取成功回调
 * @param {Function} authDenyCb 获取失败回调
 */
getLocation(successCb, authDenyCb) {
    const self = this uni.getLocation({
        type: 'gcj02',
        // 'wgs84'默认gps 坐标 'gcj02'国测
        altitude: false,
        // 是否返回高度
        accuracy: 'best',
        // 精度值为20m
        geocode: true,
		//是否解析地址默认为false
        success(res) {
            console.log(res) successCb && successCb(res) self.isLocated = true
            //获取经纬度
            self.reportInfo.lttd = res.latitude;
            self.reportInfo.lgtd = res.longitude;
            //标记地点
            var obj = {
                width: 30,
                height: 30,
                latitude: Number(self.reportInfo.lttd),
                longitude: Number(self.reportInfo.lgtd),
                iconPath: '../../static/img/garbage/loc.png'
            };
            var arr = [];
            arr.push(obj);
            arr.push(bin);
            arr.push(bin2);
            //标记点
            self.covers = arr;
        },
		//出错时执行的函数
        fail(err) {
            if (err.errMsg === 'getLocation:fail 频繁调用会增加电量损耗,可考虑使用 wx.onLocationChange 监听地理位置变化') {
                uni.showToast({
                    title: '请勿频繁定位',
                    icon: 'none'
                })
            }
            if (err.errMsg === 'getLocation:fail auth deny') {
                // 未授权
                uni.showToast({
                    title: '无法定位,请重新获取位置信息',
                    icon: 'none'
                }) authDenyCb && authDenyCb() self.isLocated = false
            }
            if (err.errMsg === 'getLocation:fail:ERROR_NOCELL&WIFI_LOCATIONSWITCHOFF') {
                uni.showModal({
                    content: '请开启手机定位服务',
                    showCancel: false
                })
            }
        },
		//完成时执行的函数
        complete() {
            //传入经纬度解析地址 
			tMap.reverseGeocoder({
                location: {
                    latitude: self.reportInfo.lttd,
                    longitude: self.reportInfo.lgtd
                },
                success: function(res) {
                    console.log('解析地址成功');
                    console.log(res);
                    self.plot = res.result.formatted_addresses;
                    self.address = res.result.address;
                    self.addressComponent = res.result.address_component;
                    // 省
                    // let province = res.result.ad_info.province;
                    // 市
                    let city = res.result.ad_info.city;
                    // console.log(province);
                },
                fail: function(res) {
                    uni.showToast({
                        title: '定位失败',
                        duration: 2000,
                        icon: 'none'
                    });
                    console.log(res);
                },
                complete: function(res) { //无论成功失败都会执行
                    console.log(res);
                }
            });
        }
    })
},


2.用户授权访问位置信息
/**
 * 重新授权并调用定位方法
 * @param {Function} successCb 授权成功回调
 * @param {Function} authDenyCb 授权失败回调
*/
getAuthorize(successCb, authDenyCb) {
	//获取用户授权
    uni.authorize({
		//需要获取权限的scope表
        scope: 'scope.userLocation',
        success: () = >{
            this.getLocation(successCb, authDenyCb)
        },
        fail: (err) = >{
            err = err['errMsg'] uni.showModal({
                content: '需要授权位置信息',
                confirmText: '确认授权'
            }).then((res) = >{
                if (res[1]['confirm']) {
                    uni.openSetting({
                        success: (res) = >{
                            if (res.authSetting['scope.userLocation']) {
                                // 授权成功
                                uni.showToast({
                                    title: '授权成功',
                                    icon: 'none'
                                })
                            } else {
                                // 未授权
                                uni.showToast({
                                    title: '授权失败',
                                    icon: 'none'
                                })
                            }
                            this.getLocation(successCb, authDenyCb)
                        }
                    })
                }
                if (res[1]['cancel']) {
                    // 取消授权
                    console.log('取消') 
					this.getLocation(successCb, authDenyCb)
                }
            })
        }
    })
},

3.用户手动选取位置
//手动动获取定位
getMapLocation() {
    var that = this;
    uni.chooseLocation({
        success: (res) = >{
            console.log(res) that.reportInfo.lttd = res.latitude;
            that.reportInfo.lgtd = res.longitude;
            var obj = {
                width: 30,
                height: 30,
                latitude: that.reportInfo.lttd,
                longitude: that.reportInfo.lgtd,
                iconPath: '../../static/img/garbage/loc.png'
            };
            var arr = [];
            arr.push(obj);
            that.covers = arr;
            console.log(that.covers, "that.covers")
        },
        complete() {
            console.log(that.reportInfo)
			tMap.reverseGeocoder({
                location: {
                    latitude: that.reportInfo.lttd,
                    longitude: that.reportInfo.lgtd
                },
                success: function(res) {
                    console.log('解析地址成功');
                    console.log(res);
                    that.plot = res.result.formatted_addresses;
                    that.address = res.result.address;
                    that.addressComponent = res.result.address_component;
                },
                fail: function(res) {
                    uni.showToast({
                        title: '定位失败',
                        duration: 2000,
                        icon: 'none'
                    });
                    console.log(res);
                },
                complete: function(res) { //无论成功失败都会执行
                    console.log(res);
                }
            });
        }
    })
},

4.调起导航到指定位置
//导航到指定位置 ltt lgt
markertap() {
    let that = this
    //调出地图传入目的地 ltt lgt
	//获取当前位置
    uni.getLocation({
        success: (res) = >{
			//成功后打开导航
            uni.openLocation({
                latitude: Number(30.89204),
                longitude: Number(120.086678),
                name: 'JN00405号垃圾桶',
                address: '垃圾桶',
                success: function() {
                    console.log('success');
                },
                fail: function() {
                    uni.showModal({
                        title: '错误',
                        content: '请检查定位是否打开',
                        showCancel: false,
                        success: function(res) {
                            if (res.confirm) {
                                console.log('用户点击确定');
                            } else if (res.cancel) {
                                console.log('用户点击取消');
                            }
                        }
                    })
                }
            });
        }
    })

},
5.计算目的地距离
//进行经纬度转换为距离的计算
Rad(d) {
	return d * Math.PI / 180.0; //经纬度转换成三角函数中度分表形式。
},

/*
 计算距离,参数分别为第一点的纬度,经度;第二点的纬度,经度
 默认单位km
*/
getMapDistance(lat1, lng1, lat2, lng2) {
	console.log("in getMap")
	console.log(lat1)
	var radLat1 = this.Rad(lat1);
	var radLat2 = this.Rad(lat2);
	var a = radLat1 - radLat2;
	var b = this.Rad(lng1) - this.Rad(lng2);
	var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) +
		Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
	s = s * 6378.137; // EARTH_RADIUS;
	s = Math.round(s * 10000) / 10000; //输出为公里
	//s=s.toFixed(2);
	return s;
},
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值