当前位置:   article > 正文

uniapp 微信小程序 选择地图位置并返回经纬度及详细地址(uni.chooseLocation和高德地图api两种方式实现)

uni.chooselocation

uniapp 微信小程序实现选择地图位置功能

最近在做商家小程序,就是用于给实体店老板进行网上开店的小程序。
其中有一项功能就是获取商店的位置,要求支持:获取当前定位/检索到指定位置/地图选点等功能,并返回选择地点的regionId和经纬度以及详细的地址等信息。

获取地理信息的授权功能

在这里插入图片描述

1. manifest.json中写入授权地理位置的描述

在这里插入图片描述
代码如下:

"permission" : {
   "scope.userLocation" : {
        "desc" : "您的位置将用于绑定您的区域"
    }
},
  • 1
  • 2
  • 3
  • 4
  • 5

2. 点击地图图标时,调用下面的代码实现授权(uni.chooseLocation方式)

注意:调取授权地理位置,需要用到uni的api,下面的三个方法都是可以的。
uni.getLocation uni.chooseLocation uni.openLocation

在这里插入图片描述

getMapLocation(){
	uni.chooseLocation({
		success:(res)=> {
			console.log(res);
			// this.getRegionFn(res);
		},
		fail:()=>{
			// 如果用uni.chooseLocation没有获取到地理位置,则需要获取当前的授权信息,判断是否有地理授权信息
			uni.getSetting({
				success: (res) => {
					console.log(res);
					var status = res.authSetting;
					if(!status['scope.userLocation']){
					// 如果授权信息中没有地理位置的授权,则需要弹窗提示用户需要授权地理信息
						uni.showModal({
							title:"是否授权当前位置",
							content:"需要获取您的地理位置,请确认授权,否则地图功能将无法使用",
							success:(tip)=>{
								if(tip.confirm){
								// 如果用户同意授权地理信息,则打开授权设置页面,判断用户的操作
									uni.openSetting({
										success:(data)=>{
										// 如果用户授权了地理信息在,则提示授权成功
											if(data.authSetting['scope.userLocation']===true){
												uni.showToast({
													title:"授权成功",
													icon:"success",
													duration:1000
												})
												// 授权成功后,然后再次chooseLocation获取信息
												uni.chooseLocation({
													success: (res) => {
														console.log("详细地址",res);
														// this.getRegionFn(res);
													}
												})
											}else{
												uni.showToast({
													title:"授权失败",
													icon:"none",
													duration:1000
												})
											}
										}
									})
								}
							}
						})
					}
				},
				fail: (res) => {
					uni.showToast({
						title:"调用授权窗口失败",
						icon:"none",
						duration:1000
					})
				}
			})
		}
	});
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

在这里插入图片描述
授权成功后,就可以进入到uniapp自带的选择地点的页面了,可以直接选取/拖动地图选取/搜索地点选取等多种方式实现地点的选择,页面真的是很好看啊。完全长在了我的审美点上。哈哈。

唯一的缺点就是,这个默认使用的腾讯地图,但是腾讯地图检索不是很精确,不如高德。

下面介绍高德地图的使用方式

3. 使用高德地图api调取地图并实现选取地点的功能

代码如下:

getMapLocation0(){
	uni.getLocation({
	    type: 'wgs84',
	    success: (res)=>{
			if(this.formData2.longitude && this.formData2.latitude){
				uni.navigateTo({
					url:"/pages/user/map?lng="+this.formData2.longitude+"&lat="+this.formData2.latitude
				})
			}else{
				uni.navigateTo({
					url:"/pages/user/map?lng="+res.longitude+"&lat="+res.latitude
				})
			}
	    },
		fail:()=>{
			uni.getSetting({
				success: (res) => {
					console.log(res);
					var status = res.authSetting;
					if(!status['scope.userLocation']){
						uni.showModal({
							title:"是否授权当前位置",
							content:"需要获取您的地理位置,请确认授权,否则地图功能将无法使用",
							success:(tip)=>{
								if(tip.confirm){
									uni.openSetting({
										success:(data)=>{
											if(data.authSetting['scope.userLocation']===true){
												uni.showToast({
													title:"授权成功",
													icon:"success",
													duration:1000
												})
												uni.getLocation({
												    type: 'wgs84',
												    success: (res)=>{
												        console.log('当前位置的经度:' + res.longitude);
												        console.log('当前位置的纬度:' + res.latitude);
														uni.navigateTo({
															url:"/pages/user/map?lng="+res.longitude+"&lat="+res.latitude
														})
												    }
												})
											}else{
												uni.showToast({
													title:"授权失败",
													icon:"none",
													duration:1000
												})
											}
										}
									})
								}
							}
						})
					}else{
						uni.getLocation({
						    type: 'wgs84',
						    success: (res)=>{
						        console.log('当前位置的经度:' + res.longitude);
						        console.log('当前位置的纬度:' + res.latitude);
								uni.navigateTo({
									url:"/pages/user/map?lng="+res.longitude+"&lat="+res.latitude
								})
						    }
						})
					}
				},
				fail: (res) => {
					uni.showToast({
						title:"调用授权窗口失败",
						icon:"none",
						duration:1000
					})
				}
			})
		}
	})
},
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79

/pages/user/map页面布局及代码如下:

<template>
	<view class="content">
		<view class="btns"> // 选取地点后的确定和取消按钮
			<view @click="back">取消</view>
			<view @click="checkAdd">确定</view>
		</view>
		// 地图部分
		 <map style="width: 100%; height: 60vh;" :latitude="latitude" :longitude="longitude" :markers="markers" @tap="tap" :include-points="markers" :scale="10"/>
		 <!-- <view id="container"></view> -->
		 // 搜索框
		 <view class="inputCon">
			 <view class="searchView">
				 <text class="iconfont icon-sousuo"></text>
				 <input type="text" placeholder="搜索地点" v-model="searchWords" confirm-type="search" @confirm="searchFn"/>
				 <text @click="cancel">取消</text>
			 </view>
		 </view>
		 // 地点列表部分
		 <view class="list">
			 <view class="item" v-for="(add,index) in dataTips" :key="add.id" @click="select(add,index)"
			 :class="selectIndex==index?'active':''">
				 <view class="name">{{add.name}}</view>
				 <view class="address">{{add.district || ''}}{{add.address || ''}}</view>
			 </view>
		 </view>
	</view>
</template>

<script>
// 引入高德地图api提供的微信小程序的接口
	var amapFile = require('@/utils/ossutil/amap-wx.js');//如:..­/..­/libs/amap-wx.js
	// 创建地图
	var myAmapFun = new amapFile.AMapWX({key: 'e4ee780c241c1874496e21efa14c2562'});
	console.log("创建了高德地图");
	export default{
		data(){
			return{
				selectIndex:undefined,
				selectAddr:{},
				searchWords:"",
				id:0, // 使用 marker点击事件 需要填写id
				title: 'map',
				latitude: 39.909,
				longitude: 116.39742,
				markers: [{
					latitude: 39.909,
					longitude: 116.39742,
					width:30,
					height:30,
					iconPath: '../../static/ditu.png'
				}],
				dataTips:[]
			}
		},
		onLoad(options) {
			if(options && options.lng){
				this.longitude = options.lng;
				this.markers[0].longitude = this.longitude;
			}
			if(options && options.lat){
				this.latitude = options.lat;
				this.markers[0].latitude = this.latitude;
			}
			// 获取当前位置的地点列表
			myAmapFun.getPoiAround({
			  success: (data)=>{
				console.log("获取当前的列表",data);
				this.dataTips = data.poisData;
			  },
			  fail: (info)=>{
				console.log(info)
			  }
			})
		},
		methods:{
			// 选择地点后,将选取的地点传递到前一个页面中
			checkAdd(){
				console.log(this.markers);
				uni.setStorageSync('address', this.markers[0]);
				var pages = getCurrentPages();// 获取所有的页面栈
				var prevPage = pages[pages.length - 2]; // 找到上一个页面,注意是页面,如果是页面中有组件,则需要通过页面接受到数据后,再次往组件中传递
				prevPage.$vm.addressObj = this.selectAddr;//在上一个页面中就可以用addressObj进行接收
				uni.navigateBack();
			},
			back(){
				uni.navigateBack();
			},
			cancel(){
				if(this.searchWords){
					this.searchWords = "";
					myAmapFun.getPoiAround({
					  location: this.markers[0].longitude+','+this.markers[0].latitude,
					  success: (data)=>{
						console.log("获取当前的列表",data);
						this.dataTips = data.poisData;
					  },
					  fail: (info)=>{
						console.log(info)
					  }
					})
				}
			},
			reserGeo(){
				myAmapFun.getRegeo({
				  success: (data)=>{
					console.log("获取当前定位信息",data);
				  },
				  fail: (info)=>{
					console.log(info)
				  }
				})
			},
			// 根据地址列表中选择某一个地点
			select(add,index){
				console.log(add);
				if(!add){
					return;
				}
				this.selectIndex = index;
				var location = add.location.split(",");
				console.log(location);
				this.selectAddr = {
					address:add.pname?(add.pname+add.cityname+add.adname+add.address):(add.district+add.address),
					latitude:location[1],
					longitude:location[0]
				};
				this.markers[0].latitude = +location[1];
				this.markers[0].longitude = +location[0];
			},
			// 在地图上点击进行选点,这个选点在地图缩放比例较大时无效,因为精读的问题。
			tap(e){
				console.log(e);
				var location = e.detail.longitude +','+e.detail.latitude
				myAmapFun.getRegeo({
				  location: location,
				  success: (data)=>{
					console.log("获取指定定位信息",data);
					this.selectAddr = {
						address:data[0].regeocodeData.formatted_address,
						latitude:e.detail.latitude,
						longitude:e.detail.longitude
					};
					this.markers[0].latitude = data[0].latitude;
					this.markers[0].longitude = data[0].longitude;
					myAmapFun.getPoiAround({
					  location: data[0].longitude+','+data[0].latitude,
					  success: (data)=>{
						console.log("获取当前的列表",data);
						this.dataTips = data.poisData;
					  },
					  fail: (info)=>{
						console.log(info)
					  }
					})
				  },
				  fail: (info)=>{
					console.log(info);
				  }
				})
			},
			// 根据内容进行检索
			searchFn(){
				console.log("根据地址检索",this.searchWords);
				myAmapFun.getInputtips({
				  keywords: this.searchWords,
				  location: '',
				  success: (data) => {
					  console.log(111,data);
					if(data && data.tips){
					  this.dataTips = data.tips;
					}
				  },
				  fail:data=>{
					  console.log(222,data);
				  }
				})
			}
		}
	}
</script>

<style lang="scss" scoped>
	.btns{
		position: fixed;
		top:0;
		left:0;
		height:260upx;
		width:100%;
		background:linear-gradient(to bottom,rgba(0,0,0,0.4),rgba(0,0,0,0));
		display: flex;
		align-items: center;
		justify-content: space-between;
		z-index:10 !important;
		view{
			margin:100upx 24upx 0;
			font-size:30upx;
			&:first-child{
				color:#fff;
			}
			&:last-child{
				width:100upx;
				height:60upx;
				line-height: 60upx;
				text-align: center;
				border-radius: 10upx;
				background:#E13500;
				color:#fff;
			}
		}
	}
	.content{
		.list{
			height:calc(40vh - 100upx);
			overflow-y: auto;
			width:702upx;
			margin:-40upx auto 0;
			padding-bottom:20upx;
			.item{
				border-bottom:2upx solid #f3f3f3;
				&:last-child{
					border:none;
				}
				.address{
					font-size:22upx;
					color:#666;
					margin:10upx 0;
				}
				.name{
					font-size:30upx;
					color:#333;
					margin-top:10upx;
				}
				&.active{
					.name{
						font-weight: bold;
						color:#E13500;
					}
					.address{
						color:#E13500;
					}
				}
			}
		}
		.inputCon{
			width:100%;
			background:#fff;
			top:-60upx;
			position: relative;
			z-index:20;
			height:100upx;
			display: flex;
			align-items: center;
			justify-content: center;
			.searchView{
				width:702upx;
				height:60upx;
				display: flex;
				align-items: center;
				line-height: 60upx;
				border-radius: 40upx;
				padding:0 30upx;
				box-sizing: border-box;
				background:#f3f3f3;
				font-size:26upx;
				.iconfont{
					color:#666;
					margin-right:20upx;
				}
				input{
					flex:1;
				}
				view{
					flex-shrink: 0;
				}
			}
		}
		
	}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280

最终实现效果页面如下:
在这里插入图片描述
uniapp 中的map组件,在微信小程序中,右下角是自带腾讯地图几个字的,为了能够去掉,我想到了一个办法,就是将下面的搜索框和地址列表上移动,盖住腾讯地图几个字。完成。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/828776
推荐阅读
相关标签
  

闽ICP备14008679号