[uniapp] package the applet to get the current location coordinates

As shown in the figure, after the jump path selects the address, the currently selected address parameter will be returned to you:


addressMap.vue:

<template>
	<view class="body" :style="{'padding-top': paddingTop + 'rpx'}">
		<view class="navBarBox">
			<view class="status" :style="{'height': statusHeight + 'rpx'}"></view>
			<view class="navBar" :style="{'height': navBarHeight + 'rpx'}">
				<view class="left">
					<image class="backImg" src="../../static/backBlack.png" mode="aspectFit" @click="goBack"></image>
					<text>选择地址</text>
				</view>
			</view>
		</view>
		<view class="search">
			<view class="serch_content">
				<view>
					<icon class="search-icon" type="search" size="14"></icon>
				</view>
				<input type="text" name="search_input" class="search_input" confirm-type="search" placeholder="搜索"
					v-model="InputValue" @confirm="search()" />
				<view v-if="InputValue.length > 0" @click="clearInput">
					<icon type="clear" size="14"></icon>
				</view>
			</view>
			<view class="btn_search" @tap="search()">搜索</view>
		</view>

		<!-- 地图容器 -->
		<map id="myMap" style="width:100%;height:450rpx;" show-location="true" :longitude="longitude"
			:latitude="latitude" scale="15" bindregionchange="regionchange">
			<!-- <view class="map-prompt">您可拖动地图, 标记准确位置</view>
		                        <image class="current-site-icon" src="../../images/address.png"></image> -->
			<cover-view class="reload" @click="reload">
				<cover-view class="center1">
					<cover-view class="center2"></cover-view>
				</cover-view>
			</cover-view>
		</map>
		<!-- 地址列表区 -->
		<scroll-view class="scroll" bindscrolltolower="loadLocation" scroll-y lower-threshold="100">
			<view class="near-item" v-for="(item,index) in nearList" :key="index" @click="chooseCenter(index)">
				<van-icon name="location-o" custom-class="current-site" :color="activeColor"
					v-if="index == selectedId" />
				<van-icon name="location-o" custom-class="current-site" v-else />
				<view class="item-main ellipsis_1">
					<view :class="index == selectedId?'activeTitle':'' ">{
   
   {item.title}}</view>
					<view :class="index == selectedId?'activeAddress':'' ">{
   
   {item.address}}</view>
				</view>
			</view>
		</scroll-view>

	</view>
</template>

<script>
	/* 
	App 端使用地图组件需要向高德或百度等三方服务商申请SDK资质,获取AppKey,打包时需要在manifest文件中勾选相应模块,在SDK配置中填写Appkey。注意申请包名和打包时的包名需匹配一致,证书信息匹配。在manifest可视化界面有详细申请指南。

	H5 端使用地图和定位相关,需要在 manifest.json 内配置腾讯或谷歌等三方地图服务商申请的秘钥(key) 
	 */
	
	import {
		MAP_KEY
	} from "../../utils/constant.js" //企业位置服务key
	
	import QQMapWX from "../../utils/qqmap-wx-jssdk.js"

	var util = require('../../utils/util2.js');

	let qqmapsdk;

	export default {
		data() {
			return {
				statusHeight: 0,
				navBarHeight: 0,
				paddingTop: 0,
				navConfig: {
					title: '地图选点',
					isLeftArrow: true
				},
				cityName: '',
				latitude: '',
				longitude: '',
				centerData: {},
				nearList: [],
				selectedId: 0,
				defaultKeyword: '',
				keyword: '',
				pageIndex: 1,
				pageSize: 20,
				isDone: false,
				MAP_KEY,
				list: [],
				listform: true,
				InputValue: '' //关键词
			}
		},
		onLoad(options) {

			//获取地图 map 实例
			this.mapCtx = wx.createMapContext('myMap');
			// 实例化API核心类
			qqmapsdk = new QQMapWX({
				key: MAP_KEY
			});
			if (options.longitudeLatitude) {
				var arrlocation = JSON.parse(options.longitudeLatitude);
				this.longitude = arrlocation[1] ? arrlocation[1] : '';
				this.latitude = arrlocation[0] ? arrlocation[0] : '';
			}
			// wx.showLoading({
			//     title: '加载中'
			// });

			this.again_getLocation()
				.then(res => {
					wx.hideLoading();
				})
				.catch(rej => {
					wx.navigateBack({
						delta: 1
					});
				});

			// 判断表单是否传了经纬度,如果有则使用表单的,用于在地图里显示刚才选择的位置
			// const longitudeLatitude = options ? options.longitudeLatitude : ""
			// this.listform = !this.listform
			//2022年更新版本 wx.getLocation 存在调用频率限制, 使用 onLocationChange 来代替
			// wx.startLocationUpdate({
			//     success: (res) => {
			//         wx.onLocationChange((location) => {
			//             console.log('location', location)
			//             if (location) {
			//                 wx.hideLoading()
			//                 wx.stopLocationUpdate()
			//                 const latitude = this.latitude
			//                 const longitude = this.longitude
			//                 if (latitude && longitude) return
			//                 this.initLocation(location.latitude, location.longitude)
			//             }
			//         })
			//     },
			// })

		},
		onShow() {
			let that = this;
			this.GetReverseGeocoder(this.latitude, this.longitude, 1, 'policy=2')
				.then(res => {
					console.log(res);
					let lll = [];
					for (let i = 0; i < res.result.pois.length; i++) {
						lll.push({
							title: res.result.pois[i].title,
							id: res.result.pois[i].id,
							address: res.result.pois[i].address,
							province: res.result.address_component.province,
							city: res.result.address_component.city,
							district: res.result.address_component.district,
							latitude: res.result.pois[i].location.lat,
							longitude: res.result.pois[i].location.lng
						});
					}
					that.centerData = lll[0];
					that.longitude = that.centerData.longitude;
					that.latitude = that.centerData.latitude;
					that.nearList = lll;
				});
		},

		onUnload() {
			// 页面卸载时清空插件数据,防止再次进入页面,getCity返回的是上次的结果
			// citySelector.clearCity();
		},
		// 不可在onLoad中获取这些信息
		created() {
			uni.getSystemInfo({
				success: res => {
					// 状态栏高度
					this.statusHeight = res.statusBarHeight * 2; //rpx
					let menuButtonRect = uni.getMenuButtonBoundingClientRect() //获取胶囊
					// 导航栏高度
					this.navBarHeight = ((menuButtonRect.top - this.statusHeight / 2) * 2 + menuButtonRect
						.height) * 2
					// 距离顶部的高度
					this.paddingTop = this.statusHeight + this.navBarHeight
				}
			})
		},
		methods: {
			goBack() {
				uni.navigateBack({
					delta: 1
				})
			},
			GetReverseGeocoder: function(
				lat,
				lng,
				is_get_poi = 0,
				poi_options = 'address_format=short'
			) {
				return new Promise((resolve, reject) => {
					qqmapsdk.reverseGeocoder({
						location: lat && lng ? lat + ',' + lng : '',
						get_poi: is_get_poi,
						poi_options: poi_options,
						success: function(res) {
							resolve(res);
						},
						fail: function(error) {
							reject(error);
						}
					});
				});
			},
			// 关键词搜索
			search() {
				var that = this;
				// 腾讯地图调用接口
				qqmapsdk.search({
					keyword: this.InputValue,
					page_size: 20,
					success: function(res) {
						console.log(res);
						let mysug = [];
						for (let i = 0; i < res.data.length; i++) {
							mysug.push({
								title: res.data[i].title,
								id: res.data[i].id,
								address: res.data[i].address,
								province: res.data[i].ad_info.province,
								city: res.data[i].ad_info.city,
								district: res.data[i].ad_info.district,
								latitude: res.data[i].location.lat,
								longitude: res.data[i].location.lng
							});
						}
						console.log('that.centerDat', that.centerData);
						that.centerData = mysug[0];
						// console.log
						that.longitude = that.centerData.longitude;
						that.latitude = that.centerData.latitude;
						that.nearList = mysug;
					},
					fail: function(res) {
						wx.hideLoading();
					},
					complete: function(res) {
						wx.hideLoading();
					}
				});
			},

			// 清空输入框中的内容
			clearInput() {
				this.InputValue = '';
			},

			toSelectCity() {
				const key = MAP_KEY; // 使用在腾讯位置服务申请的key
				const referer = '微信模板'; // 调用插件的app的名称
				wx.navigateTo({
					url: `plugin://citySelector/index?key=${key}&referer=${referer}`
				});
			},

			//监听拖动地图,拖动结束根据中心点更新页面
			regionchange(e) {
				console.log('mapChange', e);
				if (e.type == 'end' && (e.causedBy == 'scale' || e.causedBy == 'drag')) {
					this.mapCtx.getCenterLocation({
						success: res => {
							this.nearList = [];
							this.latitude = res.latitude;
							this.longitude = res.longitude;
							this.pageIndex = 1;
							this.isDone = false;
							// this.nearby_search.call(this);
							this.nearby_search(this);
						}
					});
				}
			},

			// 重置
			reload: function() {
				// this.nearList = []
				// let pages = getCurrentPages();
				// let curPage = pages[pages.length - 1]; // 当前页面
				// console.log(curPage)
				// curPage.onLoad();
			},

			// 选择地址
			chooseCenter: function(index) {
				// console.log(e.currentTarget.id);
				let id = index;
				for (let i = 0; i < this.nearList.length; i++) {
					if (i == id) {
						this.selectedId = id;
						console.log('this.nearList[i]', this.nearList);
						this.centerData = this.nearList[i];
						// this.latitude = this.nearList[i].latitude
						// this.longitude = this.nearList[i].longitude
						this.selectedOk();
						return;
					}
				}
				for (let i = 0; i < this.list.length; i++) {
					if (i == id) {
						this.selectedId = id;
						console.log('this.list[i]', this.list);
						this.centerData = this.list[i];
						// this.latitude = this.nearList[i].latitude
						// this.longitude = this.nearList[i].longitude
						this.selectedOk();
						return;
					}
				}
			},

			nearby_search: function(e) {
				console.log('nearby_search', e);
				if (e) this.keyword = e.detail;
				wx.hideLoading();
				wx.showLoading({
					title: '加载中'
				});
				qqmapsdk.search({
					keyword: this.keyword,
					location: this.latitude + ',' + this.longitude,
					page_size: this.pageSize,
					page_index: this.pageIndex,
					success: res => {
						console.log('nearby_search', res);
						wx.hideLoading();
						let sug = [];
						for (let i = 0; i < res.data.length; i++) {
							sug.push({
								title: res.data[i].title,
								id: res.data[i].id,
								address: res.data[i].address,
								province: res.data[i].ad_info.province,
								city: res.data[i].ad_info.city,
								district: res.data[i].ad_info.district,
								latitude: res.data[i].location.lat,
								longitude: res.data[i].location.lng
							});
						}
						let pageIndex = this.pageIndex + 1;
						if (sug.length < this.pageSize) {
							this.isDone = true;
							pageIndex = this.pageIndex;
						}
						// this.selectedId = 0
						// this.centerData = sug[0]
						this.nearList = this.nearList.concat(sug);
						this.pageIndex = pageIndex;
					},
					fail: function(res) {
						wx.hideLoading();
					},
					complete: function(res) {
						wx.hideLoading();
					}
				});
			},

			//确认选择地址,返回到上一页面
			selectedOk: function() {
				let pages = getCurrentPages();
				//获取上一个页面的实例
				let prevPage = pages[pages.length - 2];
				const {
					title,
					address,
					province,
					city,
					district,
					location
				} = this.centerData;
				console.log('this.centerData', this.centerData);
				prevPage.data.addressArr = province + city + district;
				prevPage.data.address = address + title;
				prevPage.data.city = city;
				prevPage.data.area = district;
				prevPage.data.province = province;
				prevPage.data.location = {
					latitude: this.centerData.latitude,
					longitude: this.centerData.longitude
				};
				console.log('prevPage', prevPage);
				wx.navigateBack({
					delta: 1
				});
			},

			loadLocation() {
				if (!this.isDone) this.nearby_search();
			},

			again_getLocation() {
				let that = this;
				return new Promise((resolve, reject) => {
					// 获取位置信息
					wx.getSetting({
						success: res => {
							console.log(res, 'res');
							if (
								res.authSetting['scope.userLocation'] != undefined &&
								res.authSetting['scope.userLocation'] != true
							) {
								//非初始化进入该页面,且未授权
								wx.showModal({
									title: '是否授权当前位置',
									content: '需要获取您的地理位置,请确认授权,否则无法获取您所需数据',
									success: function(res) {
										console.log(res);
										if (res.cancel) {
											wx.showToast({
												title: '授权失败',
												icon: 'none',
												duration: 1000
											});
											reject(res.cancel);
										} else if (res.confirm) {
											wx.openSetting({
												success: function(dataAu) {
													console.log(dataAu);
													if (dataAu.authSetting[
															'scope.userLocation'
														] == true) {
														wx.showToast({
															title: '授权成功',
															icon: 'none',
															duration: 1000
														});
														// wx.getLocation({
														// 	type: 'gcj02', // 返回经纬度
														// 	success(
														// 		res) {
														// 		resolve
														// 			(
														// 				res
														// 			);
														// 	}
														// });
													} else {
														wx.showToast({
															title: '授权失败',
															icon: 'none',
															duration: 1000
														});
														reject();
													}
												}
											});
										}
									}
								});
							} else if (res.authSetting['scope.userLocation'] == undefined) {
								//初始化进入
								console.log(2);
								wx.getLocation({
									type: 'gcj02', // 返回经纬度
									success(res) {
										resolve(res);
									}
								});
							} else {
								//授权后默认加载
								console.log(3);
								wx.getLocation({
									type: 'gcj02', // 返回经纬度
									success(res) {
										resolve(res);
									}
								});
							}
						}
					});
				});
			}
		}
	}
</script>

<style lang="scss" scoped>
	.navBarBox {
		width: 100vw;
		position: fixed;
		left: 0;
		top: 0;
		z-index: 99;
		background: #fff;

		.status {
			width: 100%;
		}

		.navBar {
			width: 100%;
			display: flex;
			justify-content: flex-start;
			align-items: center;

			.left {
				font-family: 'Alibaba PuHuiTi';
				font-style: normal;
				font-weight: 400;
				font-size: 30rpx;
				color: #000000;
				text-align: left;
				margin-left: 30rpx;
				display: flex;
				align-items: center;

				text {
					margin-left: 20rpx;
				}
			}
		}
	}

	.search {
		width: 100%;
		box-sizing: border-box;
		height: 84rpx;
		padding: 10rpx 30rpx;
		align-items: center;
		display: flex;
		background-color: #fff;

		.serch_content {
			flex: auto;
			display: flex;
			align-items: center;
			border-radius: 64rpx;
			background: #ededed;
			height: 64rpx;
			padding: 0 30rpx;

			.search-icon {
				position: relative;
				top: 5rpx;
			}

			.search_input {
				font-size: 28rpx;
				width: 100%;
				margin: 0 10rpx;
			}
		}

		.btn_search {
			margin-left: 20rpx;
			font-size: 11pt;
		}
	}

	.cityName {
		height: 100%;
		min-width: 120rpx;
		max-width: 160rpx;
		font-size: 30rpx;
		padding: 0 14rpx;
		box-sizing: border-box;
		border-right: 1rpx solid #eb921d;
		margin-right: 14rpx;
		text-align: center;
	}

	.current-site-icon {
		width: 50rpx;
		height: 50rpx;
		position: absolute;
		top: 50%;
		left: 50%;
		transform: translate(-50%, -50%);
	}

	.near-item {
		display: flex;
		line-height: 40rpx;
		padding: 20rpx 30rpx;
		text-align: left;
		border-bottom: 1px solid #eee;
	}

	.current-site {
		font-size: 40rpx;
		margin-right: 30rpx;
	}

	.item-main {
		flex: 1;
	}

	.near-item .title {
		color: #282828;
		font-size: 32rpx;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.near-item .address {
		color: #707070;
		font-size: 24rpx;
		white-space: nowrap;
		overflow: hidden;
		text-overflow: ellipsis;
	}

	.near-item .activeTitle {
		color: #eb921d;
	}

	.near-item .activeAddress {
		color: #eb921d;
	}

	.map-prompt {
		width: 420rpx;
		height: 60rpx;
		line-height: 60rpx;
		font-size: 24rpx;
		color: #707070;
		text-align: center;
		background: #fff;
		border-radius: 10rpx;
		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
		position: absolute;
		bottom: 40rpx;
		left: 50%;
		transform: translate(-50%, 0);
	}

	.reload {
		width: 80rpx;
		height: 80rpx;
		background: #fff;
		border-radius: 50%;
		box-shadow: 0 0 10rpx rgba(0, 0, 0, 0.1);
		position: absolute;
		bottom: 30rpx;
		right: 30rpx;
	}

	.reload .center1 {
		width: 30rpx;
		height: 30rpx;
		border: 1rpx solid #eb921d;
		border-radius: 50%;
		margin: 24rpx auto;
		display: flex;
		align-items: center;
		justify-content: center;
	}

	.reload .center2 {
		width: 25rpx;
		height: 25rpx;
		background: #eb921d;
		border-radius: 50%;
	}
</style>

Which uses JavaScriptSDK:

Download address:
https://mapapi.qq.com/web/miniprogram/JSSDK/qqmap-wx-jssdk1.2.zip
After the download is complete, put the downloaded js package into the utils package of the mini program:

Or just copy mine if you don't mind the trouble (I don't know if there will be a version problem, anyway, copying the following is definitely no problem):

Put it under utils: file name qqmap-wx-jssdk.js

/**
 * 微信小程序JavaScriptSDK
 * 
 * @version 1.2
 * @date 2019-03-06
 */

var ERROR_CONF = {
    KEY_ERR: 311,
    KEY_ERR_MSG: 'key格式错误',
    PARAM_ERR: 310,
    PARAM_ERR_MSG: '请求参数信息有误',
    SYSTEM_ERR: 600,
    SYSTEM_ERR_MSG: '系统错误',
    WX_ERR_CODE: 1000,
    WX_OK_CODE: 200
};
var BASE_URL = 'https://apis.map.qq.com/ws/';
var URL_SEARCH = BASE_URL + 'place/v1/search';
var URL_SUGGESTION = BASE_URL + 'place/v1/suggestion';
var URL_GET_GEOCODER = BASE_URL + 'geocoder/v1/';
var URL_CITY_LIST = BASE_URL + 'district/v1/list';
var URL_AREA_LIST = BASE_URL + 'district/v1/getchildren';
var URL_DISTANCE = BASE_URL + 'distance/v1/';
var URL_DIRECTION = BASE_URL + 'direction/v1/';
var MODE = {
  driving: 'driving',
  transit: 'transit'
};
var EARTH_RADIUS = 6378136.49;
var Utils = {
  /**
  * md5加密方法
  * 版权所有©2011 Sebastian Tschan,https://blueimp.net
  */
  safeAdd(x, y) {
    var lsw = (x & 0xffff) + (y & 0xffff);
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return (msw << 16) | (lsw & 0xffff);
  },
  bitRotateLeft(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt));
  },
  md5cmn(q, a, b, x, s, t) {
    return this.safeAdd(this.bitRotateLeft(this.safeAdd(this.safeAdd(a, q), this.safeAdd(x, t)), s), b);
  },
  md5ff(a, b, c, d, x, s, t) {
    return this.md5cmn((b & c) | (~b & d), a, b, x, s, t);
  },
  md5gg(a, b, c, d, x, s, t) {
    return this.md5cmn((b & d) | (c & ~d), a, b, x, s, t);
  },
  md5hh(a, b, c, d, x, s, t) {
    return this.md5cmn(b ^ c ^ d, a, b, x, s, t);
  },
  md5ii(a, b, c, d, x, s, t) {
    return this.md5cmn(c ^ (b | ~d), a, b, x, s, t);
  },
  binlMD5(x, len) {
    /* append padding */
    x[len >> 5] |= 0x80 << (len % 32);
    x[((len + 64) >>> 9 << 4) + 14] = len;

    var i;
    var olda;
    var oldb;
    var oldc;
    var oldd;
    var a = 1732584193;
    var b = -271733879;
    var c = -1732584194;
    var d = 271733878;

    for (i = 0; i < x.length; i += 16) {
      olda = a;
      oldb = b;
      oldc = c;
      oldd = d;

      a = this.md5ff(a, b, c, d, x[i], 7, -680876936);
      d = this.md5ff(d, a, b, c, x[i + 1], 12, -389564586);
      c = this.md5ff(c, d, a, b, x[i + 2], 17, 606105819);
      b = this.md5ff(b, c, d, a, x[i + 3], 22, -1044525330);
      a = this.md5ff(a, b, c, d, x[i + 4], 7, -176418897);
      d = this.md5ff(d, a, b, c, x[i + 5], 12, 1200080426);
      c = this.md5ff(c, d, a, b, x[i + 6], 17, -1473231341);
      b = this.md5ff(b, c, d, a, x[i + 7], 22, -45705983);
      a = this.md5ff(a, b, c, d, x[i + 8], 7, 1770035416);
      d = this.md5ff(d, a, b, c, x[i + 9], 12, -1958414417);
      c = this.md5ff(c, d, a, b, x[i + 10], 17, -42063);
      b = this.md5ff(b, c, d, a, x[i + 11], 22, -1990404162);
      a = this.md5ff(a, b, c, d, x[i + 12], 7, 1804603682);
      d = this.md5ff(d, a, b, c, x[i + 13], 12, -40341101);
      c = this.md5ff(c, d, a, b, x[i + 14], 17, -1502002290);
      b = this.md5ff(b, c, d, a, x[i + 15], 22, 1236535329);

      a = this.md5gg(a, b, c, d, x[i + 1], 5, -165796510);
      d = this.md5gg(d, a, b, c, x[i + 6], 9, -1069501632);
      c = this.md5gg(c, d, a, b, x[i + 11], 14, 643717713);
      b = this.md5gg(b, c, d, a, x[i], 20, -373897302);
      a = this.md5gg(a, b, c, d, x[i + 5], 5, -701558691);
      d = this.md5gg(d, a, b, c, x[i + 10], 9, 38016083);
      c = this.md5gg(c, d, a, b, x[i + 15], 14, -660478335);
      b = this.md5gg(b, c, d, a, x[i + 4], 20, -405537848);
      a = this.md5gg(a, b, c, d, x[i + 9], 5, 568446438);
      d = this.md5gg(d, a, b, c, x[i + 14], 9, -1019803690);
      c = this.md5gg(c, d, a, b, x[i + 3], 14, -187363961);
      b = this.md5gg(b, c, d, a, x[i + 8], 20, 1163531501);
      a = this.md5gg(a, b, c, d, x[i + 13], 5, -1444681467);
      d = this.md5gg(d, a, b, c, x[i + 2], 9, -51403784);
      c = this.md5gg(c, d, a, b, x[i + 7], 14, 1735328473);
      b = this.md5gg(b, c, d, a, x[i + 12], 20, -1926607734);

      a = this.md5hh(a, b, c, d, x[i + 5], 4, -378558);
      d = this.md5hh(d, a, b, c, x[i + 8], 11, -2022574463);
      c = this.md5hh(c, d, a, b, x[i + 11], 16, 1839030562);
      b = this.md5hh(b, c, d, a, x[i + 14], 23, -35309556);
      a = this.md5hh(a, b, c, d, x[i + 1], 4, -1530992060);
      d = this.md5hh(d, a, b, c, x[i + 4], 11, 1272893353);
      c = this.md5hh(c, d, a, b, x[i + 7], 16, -155497632);
      b = this.md5hh(b, c, d, a, x[i + 10], 23, -1094730640);
      a = this.md5hh(a, b, c, d, x[i + 13], 4, 681279174);
      d = this.md5hh(d, a, b, c, x[i], 11, -358537222);
      c = this.md5hh(c, d, a, b, x[i + 3], 16, -722521979);
      b = this.md5hh(b, c, d, a, x[i + 6], 23, 76029189);
      a = this.md5hh(a, b, c, d, x[i + 9], 4, -640364487);
      d = this.md5hh(d, a, b, c, x[i + 12], 11, -421815835);
      c = this.md5hh(c, d, a, b, x[i + 15], 16, 530742520);
      b = this.md5hh(b, c, d, a, x[i + 2], 23, -995338651);

      a = this.md5ii(a, b, c, d, x[i], 6, -198630844);
      d = this.md5ii(d, a, b, c, x[i + 7], 10, 1126891415);
      c = this.md5ii(c, d, a, b, x[i + 14], 15, -1416354905);
      b = this.md5ii(b, c, d, a, x[i + 5], 21, -57434055);
      a = this.md5ii(a, b, c, d, x[i + 12], 6, 1700485571);
      d = this.md5ii(d, a, b, c, x[i + 3], 10, -1894986606);
      c = this.md5ii(c, d, a, b, x[i + 10], 15, -1051523);
      b = this.md5ii(b, c, d, a, x[i + 1], 21, -2054922799);
      a = this.md5ii(a, b, c, d, x[i + 8], 6, 1873313359);
      d = this.md5ii(d, a, b, c, x[i + 15], 10, -30611744);
      c = this.md5ii(c, d, a, b, x[i + 6], 15, -1560198380);
      b = this.md5ii(b, c, d, a, x[i + 13], 21, 1309151649);
      a = this.md5ii(a, b, c, d, x[i + 4], 6, -145523070);
      d = this.md5ii(d, a, b, c, x[i + 11], 10, -1120210379);
      c = this.md5ii(c, d, a, b, x[i + 2], 15, 718787259);
      b = this.md5ii(b, c, d, a, x[i + 9], 21, -343485551);

      a = this.safeAdd(a, olda);
      b = this.safeAdd(b, oldb);
      c = this.safeAdd(c, oldc);
      d = this.safeAdd(d, oldd);
    }
    return [a, b, c, d];
  },
  binl2rstr(input) {
    var i;
    var output = '';
    var length32 = input.length * 32;
    for (i = 0; i < length32; i += 8) {
      output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff);
    }
    return output;
  },
  rstr2binl(input) {
    var i;
    var output = [];
    output[(input.length >> 2) - 1] = undefined;
    for (i = 0; i < output.length; i += 1) {
      output[i] = 0;
    }
    var length8 = input.length * 8;
    for (i = 0; i < length8; i += 8) {
      output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32);
    }
    return output;
  },
  rstrMD5(s) {
    return this.binl2rstr(this.binlMD5(this.rstr2binl(s), s.length * 8));
  },
  rstrHMACMD5(key, data) {
    var i;
    var bkey = this.rstr2binl(key);
    var ipad = [];
    var opad = [];
    var hash;
    ipad[15] = opad[15] = undefined;
    if (bkey.length > 16) {
      bkey = this.binlMD5(bkey, key.length * 8);
    }
    for (i = 0; i < 16; i += 1) {
      ipad[i] = bkey[i] ^ 0x36363636;
      opad[i] = bkey[i] ^ 0x5c5c5c5c;
    }
    hash = this.binlMD5(ipad.concat(this.rstr2binl(data)), 512 + data.length * 8);
    return this.binl2rstr(this.binlMD5(opad.concat(hash), 512 + 128));
  },
  rstr2hex(input) {
    var hexTab = '0123456789abcdef';
    var output = '';
    var x;
    var i;
    for (i = 0; i < input.length; i += 1) {
      x = input.charCodeAt(i);
      output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);
    }
    return output;
  },
  str2rstrUTF8(input) {
    return unescape(encodeURIComponent(input));
  },
  rawMD5(s) {
    return this.rstrMD5(this.str2rstrUTF8(s));
  },
  hexMD5(s) {
    return this.rstr2hex(this.rawMD5(s));
  },
  rawHMACMD5(k, d) {
    return this.rstrHMACMD5(this.str2rstrUTF8(k), str2rstrUTF8(d));
  },
  hexHMACMD5(k, d) {
    return this.rstr2hex(this.rawHMACMD5(k, d));
  },

  md5(string, key, raw) {
    if (!key) {
      if (!raw) {
        return this.hexMD5(string);
      }
      return this.rawMD5(string);
    }
    if (!raw) {
      return this.hexHMACMD5(key, string);
    }
    return this.rawHMACMD5(key, string);
  },
  /**
   * 得到md5加密后的sig参数
   * @param {Object} requestParam 接口参数
   * @param {String} sk签名字符串
   * @param {String} featrue 方法名
   * @return 返回加密后的sig参数
   */
  getSig(requestParam, sk, feature, mode) {
    var sig = null;
    var requestArr = [];
    Object.keys(requestParam).sort().forEach(function(key){
      requestArr.push(key + '=' + requestParam[key]);
    });
    if (feature == 'search') {
      sig = '/ws/place/v1/search?' + requestArr.join('&') + sk;
    }
    if (feature == 'suggest') {
      sig = '/ws/place/v1/suggestion?' + requestArr.join('&') + sk;
    }
    if (feature == 'reverseGeocoder') {
      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
    }
    if (feature == 'geocoder') {
      sig = '/ws/geocoder/v1/?' + requestArr.join('&') + sk;
    }
    if (feature == 'getCityList') {
      sig = '/ws/district/v1/list?' + requestArr.join('&') + sk;
    }
    if (feature == 'getDistrictByCityId') {
      sig = '/ws/district/v1/getchildren?' + requestArr.join('&') + sk;
    }
    if (feature == 'calculateDistance') {
      sig = '/ws/distance/v1/?' + requestArr.join('&') + sk;
    }
    if (feature == 'direction') {
      sig = '/ws/direction/v1/' + mode + '?' + requestArr.join('&') + sk;
    }
    sig = this.md5(sig);
    return sig;
  },
    /**
     * 得到终点query字符串
     * @param {Array|String} 检索数据
     */
    location2query(data) {
        if (typeof data == 'string') {
            return data;
        }
        var query = '';
        for (var i = 0; i < data.length; i++) {
            var d = data[i];
            if (!!query) {
                query += ';';
            }
            if (d.location) {
                query = query + d.location.lat + ',' + d.location.lng;
            }
            if (d.latitude && d.longitude) {
                query = query + d.latitude + ',' + d.longitude;
            }
        }
        return query;
    },

    /**
     * 计算角度
     */
    rad(d) {
      return d * Math.PI / 180.0;
    },  
    /**
     * 处理终点location数组
     * @return 返回终点数组
     */
    getEndLocation(location){
      var to = location.split(';');
      var endLocation = [];
      for (var i = 0; i < to.length; i++) {
        endLocation.push({
          lat: parseFloat(to[i].split(',')[0]),
          lng: parseFloat(to[i].split(',')[1])
        })
      }
      return endLocation;
    },

    /**
     * 计算两点间直线距离
     * @param a 表示纬度差
     * @param b 表示经度差
     * @return 返回的是距离,单位m
     */
    getDistance(latFrom, lngFrom, latTo, lngTo) {
      var radLatFrom = this.rad(latFrom);
      var radLatTo = this.rad(latTo);
      var a = radLatFrom - radLatTo;
      var b = this.rad(lngFrom) - this.rad(lngTo);
      var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
      distance = distance * EARTH_RADIUS;
      distance = Math.round(distance * 10000) / 10000;
      return parseFloat(distance.toFixed(0));
    },
    /**
     * 使用微信接口进行定位
     */
    getWXLocation(success, fail, complete) {
        wx.getLocation({
            type: 'gcj02',
            success: success,
            fail: fail,
            complete: complete
        });
    },

    /**
     * 获取location参数
     */
    getLocationParam(location) {
        if (typeof location == 'string') {
            var locationArr = location.split(',');
            if (locationArr.length === 2) {
                location = {
                    latitude: location.split(',')[0],
                    longitude: location.split(',')[1]
                };
            } else {
                location = {};
            }
        }
        return location;
    },

    /**
     * 回调函数默认处理
     */
    polyfillParam(param) {
        param.success = param.success || function () { };
        param.fail = param.fail || function () { };
        param.complete = param.complete || function () { };
    },

    /**
     * 验证param对应的key值是否为空
     * 
     * @param {Object} param 接口参数
     * @param {String} key 对应参数的key
     */
    checkParamKeyEmpty(param, key) {
        if (!param[key]) {
            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + key +'参数格式有误');
            param.fail(errconf);
            param.complete(errconf);
            return true;
        }
        return false;
    },

    /**
     * 验证参数中是否存在检索词keyword
     * 
     * @param {Object} param 接口参数
     */
    checkKeyword(param){
        return !this.checkParamKeyEmpty(param, 'keyword');
    },

    /**
     * 验证location值
     * 
     * @param {Object} param 接口参数
     */
    checkLocation(param) {
        var location = this.getLocationParam(param.location);
        if (!location || !location.latitude || !location.longitude) {
            var errconf = this.buildErrorConfig(ERROR_CONF.PARAM_ERR, ERROR_CONF.PARAM_ERR_MSG + ' location参数格式有误');
            param.fail(errconf);
            param.complete(errconf);
            return false;
        }
        return true;
    },

    /**
     * 构造错误数据结构
     * @param {Number} errCode 错误码
     * @param {Number} errMsg 错误描述
     */
    buildErrorConfig(errCode, errMsg) {
        return {
            status: errCode,
            message: errMsg
        };
    },

    /**
     * 
     * 数据处理函数
     * 根据传入参数不同处理不同数据
     * @param {String} feature 功能名称
     * search 地点搜索
     * suggest关键词提示
     * reverseGeocoder逆地址解析
     * geocoder地址解析
     * getCityList获取城市列表:父集
     * getDistrictByCityId获取区县列表:子集
     * calculateDistance距离计算
     * @param {Object} param 接口参数
     * @param {Object} data 数据
     */
    handleData(param,data,feature){
      if (feature == 'search') {
        var searchResult = data.data;
        var searchSimplify = [];
        for (var i = 0; i < searchResult.length; i++) {
          searchSimplify.push({
            id: searchResult[i].id || null,
            title: searchResult[i].title || null,
            latitude: searchResult[i].location && searchResult[i].location.lat || null,
            longitude: searchResult[i].location && searchResult[i].location.lng || null,
            address: searchResult[i].address || null,
            category: searchResult[i].category || null,
            tel: searchResult[i].tel || null,
            adcode: searchResult[i].ad_info && searchResult[i].ad_info.adcode || null,
            city: searchResult[i].ad_info && searchResult[i].ad_info.city || null,
            district: searchResult[i].ad_info && searchResult[i].ad_info.district || null,
            province: searchResult[i].ad_info && searchResult[i].ad_info.province || null
          })
        }
        param.success(data, {
          searchResult: searchResult,
          searchSimplify: searchSimplify
        })
      } else if (feature == 'suggest') {
        var suggestResult = data.data;
        var suggestSimplify = [];
        for (var i = 0; i < suggestResult.length; i++) {
          suggestSimplify.push({
            adcode: suggestResult[i].adcode || null,
            address: suggestResult[i].address || null,
            category: suggestResult[i].category || null,
            city: suggestResult[i].city || null,
            district: suggestResult[i].district || null,
            id: suggestResult[i].id || null,
            latitude: suggestResult[i].location && suggestResult[i].location.lat || null,
            longitude: suggestResult[i].location && suggestResult[i].location.lng || null,
            province: suggestResult[i].province || null,
            title: suggestResult[i].title || null,
            type: suggestResult[i].type || null
          })
        }
        param.success(data, {
          suggestResult: suggestResult,
          suggestSimplify: suggestSimplify
          })
      } else if (feature == 'reverseGeocoder') {
        var reverseGeocoderResult = data.result;
        var reverseGeocoderSimplify = {
          address: reverseGeocoderResult.address || null,
          latitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lat || null,
          longitude: reverseGeocoderResult.location && reverseGeocoderResult.location.lng || null,
          adcode: reverseGeocoderResult.ad_info && reverseGeocoderResult.ad_info.adcode || null,
          city: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.city || null,
          district: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.district || null,
          nation: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.nation || null,
          province: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.province || null,
          street: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street || null,
          street_number: reverseGeocoderResult.address_component && reverseGeocoderResult.address_component.street_number || null,
          recommend: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.recommend || null,
          rough: reverseGeocoderResult.formatted_addresses && reverseGeocoderResult.formatted_addresses.rough || null
        };
        if (reverseGeocoderResult.pois) {//判断是否返回周边poi
          var pois = reverseGeocoderResult.pois;
          var poisSimplify = [];
          for (var i = 0;i < pois.length;i++) {
            poisSimplify.push({
              id: pois[i].id || null,
              title: pois[i].title || null,
              latitude: pois[i].location && pois[i].location.lat || null,
              longitude: pois[i].location && pois[i].location.lng || null,
              address: pois[i].address || null,
              category: pois[i].category || null,
              adcode: pois[i].ad_info && pois[i].ad_info.adcode || null,
              city: pois[i].ad_info && pois[i].ad_info.city || null,
              district: pois[i].ad_info && pois[i].ad_info.district || null,
              province: pois[i].ad_info && pois[i].ad_info.province || null
            })
          }
          param.success(data,{
            reverseGeocoderResult: reverseGeocoderResult,
            reverseGeocoderSimplify: reverseGeocoderSimplify,
            pois: pois,
            poisSimplify: poisSimplify
          })
        } else {
          param.success(data, {
            reverseGeocoderResult: reverseGeocoderResult,
            reverseGeocoderSimplify: reverseGeocoderSimplify
          })
        }
      } else if (feature == 'geocoder') {
        var geocoderResult = data.result;
        var geocoderSimplify = {
          title: geocoderResult.title || null,
          latitude: geocoderResult.location && geocoderResult.location.lat || null,
          longitude: geocoderResult.location && geocoderResult.location.lng || null,
          adcode: geocoderResult.ad_info && geocoderResult.ad_info.adcode || null,
          province: geocoderResult.address_components && geocoderResult.address_components.province || null,
          city: geocoderResult.address_components && geocoderResult.address_components.city || null,
          district: geocoderResult.address_components && geocoderResult.address_components.district || null,
          street: geocoderResult.address_components && geocoderResult.address_components.street || null,
          street_number: geocoderResult.address_components && geocoderResult.address_components.street_number || null,
          level: geocoderResult.level || null
        };
        param.success(data,{
          geocoderResult: geocoderResult,
          geocoderSimplify: geocoderSimplify
        });
      } else if (feature == 'getCityList') {
        var provinceResult = data.result[0];
        var cityResult = data.result[1];
        var districtResult = data.result[2];
        param.success(data,{
          provinceResult: provinceResult,
          cityResult: cityResult,
          districtResult: districtResult
        });
      } else if (feature == 'getDistrictByCityId') {
        var districtByCity = data.result[0];
        param.success(data, districtByCity);
      } else if (feature == 'calculateDistance') {
        var calculateDistanceResult = data.result.elements;  
        var distance = [];
        for (var i = 0; i < calculateDistanceResult.length; i++){
          distance.push(calculateDistanceResult[i].distance);
        }   
        param.success(data, {
          calculateDistanceResult: calculateDistanceResult,
          distance: distance
          });
      } else if (feature == 'direction') {
        var direction = data.result.routes;
        param.success(data,direction);
      } else {
        param.success(data);
      }
    },

    /**
     * 构造微信请求参数,公共属性处理
     * 
     * @param {Object} param 接口参数
     * @param {Object} param 配置项
     * @param {String} feature 方法名
     */
    buildWxRequestConfig(param, options, feature) {
        var that = this;
        options.header = { "content-type": "application/json" };
        options.method = 'GET';
        options.success = function (res) {
            var data = res.data;
            if (data.status === 0) {
              that.handleData(param, data, feature);
            } else {
                param.fail(data);
            }
        };
        options.fail = function (res) {
            res.statusCode = ERROR_CONF.WX_ERR_CODE;
            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
        };
        options.complete = function (res) {
            var statusCode = +res.statusCode;
            switch(statusCode) {
                case ERROR_CONF.WX_ERR_CODE: {
                    param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
                    break;
                }
                case ERROR_CONF.WX_OK_CODE: {
                    var data = res.data;
                    if (data.status === 0) {
                        param.complete(data);
                    } else {
                        param.complete(that.buildErrorConfig(data.status, data.message));
                    }
                    break;
                }
                default:{
                    param.complete(that.buildErrorConfig(ERROR_CONF.SYSTEM_ERR, ERROR_CONF.SYSTEM_ERR_MSG));
                }

            }
        };
        return options;
    },

    /**
     * 处理用户参数是否传入坐标进行不同的处理
     */
    locationProcess(param, locationsuccess, locationfail, locationcomplete) {
        var that = this;
        locationfail = locationfail || function (res) {
            res.statusCode = ERROR_CONF.WX_ERR_CODE;
            param.fail(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
        };
        locationcomplete = locationcomplete || function (res) {
            if (res.statusCode == ERROR_CONF.WX_ERR_CODE) {
                param.complete(that.buildErrorConfig(ERROR_CONF.WX_ERR_CODE, res.errMsg));
            }
        };
        if (!param.location) {
            that.getWXLocation(locationsuccess, locationfail, locationcomplete);
        } else if (that.checkLocation(param)) {
            var location = Utils.getLocationParam(param.location);
            locationsuccess(location);
        }
    }
};


class QQMapWX {

    /**
     * 构造函数
     * 
     * @param {Object} options 接口参数,key 为必选参数
     */
    constructor(options) {
        if (!options.key) {
            throw Error('key值不能为空');
        }
        this.key = options.key;
    };

    /**
     * POI周边检索
     *
     * @param {Object} options 接口参数对象
     * 
     * 参数对象结构可以参考
     * @see http://lbs.qq.com/webservice_v1/guide-search.html
     */
    search(options) {
        var that = this;
        options = options || {};

        Utils.polyfillParam(options);

        if (!Utils.checkKeyword(options)) {
            return;
        }

        var requestParam = {
            keyword: options.keyword,
            orderby: options.orderby || '_distance',
            page_size: options.page_size || 10,
            page_index: options.page_index || 1,
            output: 'json',
            key: that.key
        };

        if (options.address_format) {
            requestParam.address_format = options.address_format;
        }

        if (options.filter) {
            requestParam.filter = options.filter;
        }

        var distance = options.distance || "1000";
        var auto_extend = options.auto_extend || 1;
        var region = null;
        var rectangle = null;

        //判断城市限定参数
        if (options.region) {
          region = options.region;
        }

        //矩形限定坐标(暂时只支持字符串格式)
        if (options.rectangle) {
          rectangle = options.rectangle;
        }

        var locationsuccess = function (result) {        
          if (region && !rectangle) {
            //城市限定参数拼接
            requestParam.boundary = "region(" + region + "," + auto_extend + "," + result.latitude + "," + result.longitude + ")";
            if (options.sig) {
              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
            }
          } else if (rectangle && !region) {
            //矩形搜索
            requestParam.boundary = "rectangle(" + rectangle + ")";
            if (options.sig) {
              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
            }
            } else {
              requestParam.boundary = "nearby(" + result.latitude + "," + result.longitude + "," + distance + "," + auto_extend + ")";
            if (options.sig) {
              requestParam.sig = Utils.getSig(requestParam, options.sig, 'search');
            }
            }            
            wx.request(Utils.buildWxRequestConfig(options, {
                url: URL_SEARCH,
                data: requestParam
            }, 'search'));
        };
        Utils.locationProcess(options, locationsuccess);
    };

    /**
     * sug模糊检索
     *
     * @param {Object} options 接口参数对象
     * 
     * 参数对象结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-suggestion.html
     */
    getSuggestion(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);

        if (!Utils.checkKeyword(options)) {
            return;
        }

        var requestParam = {
            keyword: options.keyword,
            region: options.region || '全国',
            region_fix: options.region_fix || 0,
            policy: options.policy || 0,
            page_size: options.page_size || 10,//控制显示条数
            page_index: options.page_index || 1,//控制页数
            get_subpois : options.get_subpois || 0,//返回子地点
            output: 'json',
            key: that.key
        };
        //长地址
        if (options.address_format) {
          requestParam.address_format = options.address_format;
        }
        //过滤
        if (options.filter) {
          requestParam.filter = options.filter;
        }
        //排序
        if (options.location) {
          var locationsuccess = function (result) {
            requestParam.location = result.latitude + ',' + result.longitude;
            if (options.sig) {
              requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
            }
            wx.request(Utils.buildWxRequestConfig(options, {
              url: URL_SUGGESTION,
              data: requestParam
            }, "suggest"));      
          };
          Utils.locationProcess(options, locationsuccess);
        } else {
          if (options.sig) {
            requestParam.sig = Utils.getSig(requestParam, options.sig, 'suggest');
          }
          wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_SUGGESTION,
            data: requestParam
          }, "suggest"));      
        }        
    };

    /**
     * 逆地址解析
     *
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-gcoder.html
     */
    reverseGeocoder(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);
        var requestParam = {
            coord_type: options.coord_type || 5,
            get_poi: options.get_poi || 0,
            output: 'json',
            key: that.key
        };
        if (options.poi_options) {
            requestParam.poi_options = options.poi_options
        }

        var locationsuccess = function (result) {
            requestParam.location = result.latitude + ',' + result.longitude;
          if (options.sig) {
            requestParam.sig = Utils.getSig(requestParam, options.sig, 'reverseGeocoder');
          }
            wx.request(Utils.buildWxRequestConfig(options, {
                url: URL_GET_GEOCODER,
                data: requestParam
            }, 'reverseGeocoder'));
        };
        Utils.locationProcess(options, locationsuccess);
    };

    /**
     * 地址解析
     *
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-geocoder.html
     */
    geocoder(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);

        if (Utils.checkParamKeyEmpty(options, 'address')) {
            return;
        }

        var requestParam = {
            address: options.address,
            output: 'json',
            key: that.key
        };

        //城市限定
        if (options.region) {
          requestParam.region = options.region;
        }

        if (options.sig) {
          requestParam.sig = Utils.getSig(requestParam, options.sig, 'geocoder');
        }

        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_GET_GEOCODER,
            data: requestParam
        },'geocoder'));
    };


    /**
     * 获取城市列表
     *
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-region.html
     */
    getCityList(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);
        var requestParam = {
            output: 'json',
            key: that.key
        };

        if (options.sig) {
          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getCityList');
        }

        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_CITY_LIST,
            data: requestParam
        },'getCityList'));
    };

    /**
     * 获取对应城市ID的区县列表
     *
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-region.html
     */
    getDistrictByCityId(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);

        if (Utils.checkParamKeyEmpty(options, 'id')) {
            return;
        }

        var requestParam = {
            id: options.id || '',
            output: 'json',
            key: that.key
        };

        if (options.sig) {
          requestParam.sig = Utils.getSig(requestParam, options.sig, 'getDistrictByCityId');
        }

        wx.request(Utils.buildWxRequestConfig(options, {
            url: URL_AREA_LIST,
            data: requestParam
        },'getDistrictByCityId'));
    };

    /**
     * 用于单起点到多终点的路线距离(非直线距离)计算:
     * 支持两种距离计算方式:步行和驾车。
     * 起点到终点最大限制直线距离10公里。
     *
     * 新增直线距离计算。
     * 
     * @param {Object} options 接口参数对象
     * 
     * 请求参数结构可以参考
     * http://lbs.qq.com/webservice_v1/guide-distance.html
     */
    calculateDistance(options) {
        var that = this;
        options = options || {};
        Utils.polyfillParam(options);

        if (Utils.checkParamKeyEmpty(options, 'to')) {
            return;
        }

        var requestParam = {
            mode: options.mode || 'walking',
            to: Utils.location2query(options.to),
            output: 'json',
            key: that.key
        };

        if (options.from) {
          options.location = options.from;
        }

        //计算直线距离
        if(requestParam.mode == 'straight'){        
          var locationsuccess = function (result) {
            var locationTo = Utils.getEndLocation(requestParam.to);//处理终点坐标
            var data = {
              message:"query ok",
              result:{
                elements:[]
              },
              status:0
            };
            for (var i = 0; i < locationTo.length; i++) {
              data.result.elements.push({//将坐标存入
                distance: Utils.getDistance(result.latitude, result.longitude, locationTo[i].lat, locationTo[i].lng),
                duration:0,
                from:{
                  lat: result.latitude,
                  lng:result.longitude
                },
                to:{
                  lat: locationTo[i].lat,
                  lng: locationTo[i].lng
                }
              });            
            }
            var calculateResult = data.result.elements;
            var distanceResult = [];
            for (var i = 0; i < calculateResult.length; i++) {
              distanceResult.push(calculateResult[i].distance);
            }  
            return options.success(data,{
              calculateResult: calculateResult,
              distanceResult: distanceResult
            });
          };
          
          Utils.locationProcess(options, locationsuccess);
        } else {
          var locationsuccess = function (result) {
            requestParam.from = result.latitude + ',' + result.longitude;
            if (options.sig) {
              requestParam.sig = Utils.getSig(requestParam, options.sig, 'calculateDistance');
            }
            wx.request(Utils.buildWxRequestConfig(options, {
              url: URL_DISTANCE,
              data: requestParam
            },'calculateDistance'));
          };

          Utils.locationProcess(options, locationsuccess);
        }      
    };

  /**
   * 路线规划:
   * 
   * @param {Object} options 接口参数对象
   * 
   * 请求参数结构可以参考
   * https://lbs.qq.com/webservice_v1/guide-road.html
   */
  direction(options) {
    var that = this;
    options = options || {};
    Utils.polyfillParam(options);

    if (Utils.checkParamKeyEmpty(options, 'to')) {
      return;
    }

    var requestParam = {
      output: 'json',
      key: that.key
    };

    //to格式处理
    if (typeof options.to == 'string') {
      requestParam.to = options.to;
    } else {
      requestParam.to = options.to.latitude + ',' + options.to.longitude;
    }
    //初始化局部请求域名
    var SET_URL_DIRECTION = null;
    //设置默认mode属性
    options.mode = options.mode || MODE.driving;

    //设置请求域名
    SET_URL_DIRECTION = URL_DIRECTION + options.mode;

    if (options.from) {
      options.location = options.from;
    }

    if (options.mode == MODE.driving) {
      if (options.from_poi) {
        requestParam.from_poi = options.from_poi;
      }
      if (options.heading) {
        requestParam.heading = options.heading;
      }
      if (options.speed) {
        requestParam.speed = options.speed;
      }
      if (options.accuracy) {
        requestParam.accuracy = options.accuracy;
      }
      if (options.road_type) {
        requestParam.road_type = options.road_type;
      }
      if (options.to_poi) {
        requestParam.to_poi = options.to_poi;
      }
      if (options.from_track) {
        requestParam.from_track = options.from_track;
      }
      if (options.waypoints) {
        requestParam.waypoints = options.waypoints;
      }
      if (options.policy) {
        requestParam.policy = options.policy;
      }
      if (options.plate_number) {
        requestParam.plate_number = options.plate_number;
      }
    }

    if (options.mode == MODE.transit) {
      if (options.departure_time) {
        requestParam.departure_time = options.departure_time;
      }
      if (options.policy) {
        requestParam.policy = options.policy;
      }
    } 

    var locationsuccess = function (result) {
      requestParam.from = result.latitude + ',' + result.longitude;
      if (options.sig) {
        requestParam.sig = Utils.getSig(requestParam, options.sig, 'direction',options.mode);
      }
      wx.request(Utils.buildWxRequestConfig(options, {
        url: SET_URL_DIRECTION,
        data: requestParam
      }, 'direction'));
    };

    Utils.locationProcess(options, locationsuccess);
  }
};

module.exports = QQMapWX;

Two public classes are also used:


Constant.js generally stores some keys and server addresses, which are more important, and the privacy information has been replaced by xxx:

const envUrl = 'https://xxx.cn'; // 测试环境 
// const envUrl = 'https://xxx.cn'; // 正式环境 


export const baseUrl = envUrl;	

// appKey 小程序标识
export const appKey = 'xxx';

// 腾讯位置服务 Key
export const MAP_KEY = 'xxxxx-xxxxx-xxxxx-xxxxx'; // 现在用的是企业的key

// 是否打开Debug信息
export const isDebug = true;

util2.js is as follows: it needs to be copied directly (there are many useless things, only the one that calculates the distance is useful, so delete it yourself), no need to expand.

// 随机生产guid
function GetGuid() {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
  }
  return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4());
};
function getCurrentTime() {
  let keep = ''
  let date = new Date()
  let y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  let h = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  let f = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  keep = y + '' + m + '' + d + '' + h + '' + f + '' + s
  return keep // 20160614134947
}

function fmtTime() {
  let keep = ''
  let date = new Date()
  let y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  let h = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  let f = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  keep = y + '-' + m + '-' + d + ' ' + h + ':' + f + ':' + s
  return keep // 20160614134947
}
function yyTime() {
  let keep = ''
  let date = new Date()
  let y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  let h = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  let f = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  keep = y + '/' + m + '/' + d + '/' + h + '/' + f + '/' + s
  return keep // 20160614134947
}

function formartTime(time) {
  let keep = ''
  let date = new Date(time)
  let y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  let h = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
  let f = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
  let s = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
  keep = y + '-' + m + '-' + d + ' ' + h + ':' + f + ':' + s
  return keep // 20160614134947
}

function getYearMonthDayTime(time) {
  let keep = ''
  let date = time? time: new Date()
  let y = date.getFullYear()
  let m = date.getMonth() + 1
  m = m < 10 ? '0' + m : m
  let d = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
  keep = y + '/' + m + '/' + d + ' 00:00:00'
  return keep
}

function getHourMinutesTime(time) {
  var date = new Date(time);

  var hour = date.getHours()
  hour = hour.toString().length === 2 ? hour : ('0' + hour)
  var minutes = date.getMinutes()
  minutes = minutes.toString().length === 2 ? minutes : ('0' + minutes)

  return hour + ":" + minutes;
}

function addTime(time, year, month, day, hour, minute, second) {
  var v = new Date(time);
  if (year) {
    v.setFullYear(v.getFullYear() + year)
  }
  if (month) {
    v.setMonth(v.getMonth() + month)
  }
  if (day) {
    v.setDate(v.getDate() + day)
  }
  if (hour) {
    v.setHours(v.getHours() + hour)
  }
  if (minute) {
    v.setMinutes(v.getMinutes() + minute)
  }
  if (second) {
    v.setSeconds(v.getSeconds() + second)
  }

  return v;
}

function getWeekDate(t) {
  var time = new Date(t);
  var day = time.getDay();
  var weeks = new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");
  var week = weeks[day];
  return week;
}

function objLength(input) {
  let type = toString(input)
  let length = 0
  if (type !== '[object Object]') {
    // throw '输入必须为对象{}!'
  } else {
    for (let key in input) {
      if (key !== 'number') {
        length++
      }
    }
  }
  return length
}
// 验证是否是手机号码
function vailPhone(number) {
  let flag = true
  let myreg = /^(((13[0-9]{1})|(14[0-9]{1})|(17[0]{1})|(15[0-3]{1})|(15[5-9]{1})|(18[0-9]{1}))+\d{8})$/
  if (number.length !== 11 || !myreg.test(number)) {
    flag = false
  }
  return flag
}
// 验证是否西班牙手机(6开头 9位数)
function ifSpanish(number) {
  let flag = true
  let myreg = /^([6|7|9]{1}(\d+){8})$/
  if (number.length !== 9 || !myreg.test(number)) {
    flag = false
  }
  return flag
}
// 浮点型除法
function div(a, b) {
  let c, d, e, f
  try {
    e = a.toString().split('.')[1].length
  } catch (g) { }
  try {
    f = b.toString().split('.')[1].length
  } catch (g) { }
  // [eslint] Return statement should not contain assignment. (no-return-assign)
  c = Number(a.toString().replace('.', ''))
  d = Number(b.toString().replace('.', ''))
  return mul(c / d, Math.pow(10, f - e))
}
// 浮点型加法函数
function accAdd(arg1, arg2) {
  let r1, r2, m
  try {
    r1 = arg1.toString().split('.')[1].length
  } catch (e) {
    r1 = 0
  }
  try {
    r2 = arg2.toString().split('.')[1].length
  } catch (e) {
    r2 = 0
  }
  m = Math.pow(10, Math.max(r1, r2))
  return ((arg1 * m + arg2 * m) / m).toFixed(2)
}
// 浮点型乘法
function mul(a, b) {
  let c = 0
  let d = a.toString()
  let e = b.toString()
  try {
    c += a.toString().split('.')[1].length
  } catch (f) { }
  try {
    c += b.toString().split('.')[1].length
  } catch (f) { }
  return Number(d.replace('.', '')) * Number(e.replace('.', '')) / Math.pow(10, c)
}

//  遍历对象属性和值
function displayProp(obj) {
  let names = ''
  for (let name in obj) {
    names += name + obj[name]
  }
  return names
}
//  去除字符串所有空格
function sTrim(text) {
  return text.replace(/\s/g, '')
}
// 去除所有:,英文冒号
function replaceColon(txt) {
  return txt.replace(/:/g, '')
}
// 转换星星分数
function convertStarArray(score) {
  // 1 全星,0 空星,2半星
  let arr = []
  for (let i = 1; i <= 5; i++) {
    if (score >= i) {
      arr.push(1)
    } else if (score > i - 1 && score < i + 1) {
      arr.push(2)
    } else {
      arr.push(0)
    }
  }
  return arr
}
// 获取包含上限,但不包含下限的随机数
function random(min, max) {
  return Math.floor(Math.random() * (max - min)) + min;
}

// 格式化金额
function parseMoney(money) {
  money = +money;
  var
    c = 2, // 小数点后面保留几位
    s = money < 0 ? "-" : "", // 正负符号
    i = String(parseInt(money = Math.abs(Number(money) || 0).toFixed(c))),
    j = (j = i.length) > 3 ? j % 3 : 0;
  return s + (j ? i.substr(0, j) + "" : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + ',') + (c ? "." + Math.abs(money - i).toFixed(c).slice(2) : "");
}
//小数乘100
function AmountToFenValue(je) {
  if (!Number(je))
    return 0;
  var value;
  if (je.toString().indexOf('.') > 0) {
    var yuan = je.toString().split('.')[0];
    var fen = je.toString().split('.')[1];
    fen = fen.substring(0, 2);
    value = Number(yuan + fen);
    if (fen.length == 1)
      value = value * 10;
    else if (fen.length == 0)
      value = value * 100;
  } else {
    value = Number(je) * 100;
  }
  return value;
}
/**
 * 将距离格式化
 * <1000m时 取整,没有小数点
 * >1000m时 单位取km,一位小数点 
 */
function formatDistance(num) {
  if (num < 1000) {
    return num.toFixed(0) + 'm';
  } else if (num > 1000) {
    return (num / 1000).toFixed(1) + 'km';
  }
}
/**
 * 计算角度
 */
function rad(d) {
  return d * Math.PI / 180.0;
}
/**
 * 计算两点间直线距离
 * @param a 表示纬度差
 * @param b 表示经度差
 * @return 返回的是距离,单位m
 */
var EARTH_RADIUS = 6371002.19;

function getDistance(latFrom, lngFrom, latTo, lngTo) {
  var radLatFrom = rad(latFrom);
  var radLatTo = rad(latTo);
  var a = radLatFrom - radLatTo;
  var b = rad(lngFrom) - rad(lngTo);
  var distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLatFrom) * Math.cos(radLatTo) * Math.pow(Math.sin(b / 2), 2)));
  distance = distance * EARTH_RADIUS;
  distance = Math.round(distance * 10000) / 10000;
  return parseFloat(distance.toFixed(0));
}

function getParamsValueFromUrlByKey(url, key) {
  if (!url || !key) {
    return '';
  }

  let v = '';
  let k = '?' + key + '=';
  let i = url.indexOf(k);
  if (i >= 0) {
    let s = url.substring(i + k.length);
    let ii = s.indexOf('&');
    if (ii >= 0) {
      v = s.substring(0, ii);
    } else {
      v = s;
    }
  }

  if (v.length > 0) {
    return v;
  }

  k = '&' + key + '=';
  i = url.indexOf(k);
  if (i >= 0) {
    let s = url.substring(i + k.length);
    let ii = s.indexOf('&');
    if (ii >= 0) {
      v = s.substring(0, ii);
    } else {
      v = s;
    }
  }

  return v;
}

// 计算时间差,天数,小时数,余数
function chaDate(date,date1) {
  // var date = new Date(date); // Tue Dec 07 2021 14:44:22 GMT+0800 (中国标准时间) 
  // var date1 = new Date(date1);
  
  let x = Math.abs(date - date1)
  // console.log(x) // 时间差的毫秒数
  
  let days = Math.floor(x/(1000*60*60*24)) // 相差的天数
  
  let leave1 = x%(1000*60*60*24) // 计算天数后剩余的毫秒数
  let hours = Math.floor(leave1/(1000*60*60)) // 相差的小时数
  
  let leave2 = leave1%(1000*60*60) // 计算小时后剩余的毫秒数
  let minutes = Math.floor(leave2/(1000*60)) // 相差的分钟数
  
  let leave3 = leave2%(60*1000) // 计算分钟数后剩余的毫秒数
  let seconds = Math.round(leave3/1000)

  // console.log(days,hours,minutes,seconds)
  let a = (days?(days + '天'):'') + (hours?(hours + '小时'):'') + (minutes?(minutes + '分钟'):'') + (seconds + '秒')
  return a
}
// 两个时间比较大小 参数格式 (new Date() 或者 2021/11/22 16:47:02 或者 2021-11-22 16:47:02)
function bjDate(d, d1) {
  let date = new Date(d);
  let date1 = new Date(d1);	
  let shengyuTime = chaDate(date,date1)
  if (date.getTime() - date1.getTime() < 0) {
    return '未超时,还有' + shengyuTime ;
  } else if(date.getTime() - date1.getTime() == 0){
    return '即将超时';
  } else {
    return '已超时' + shengyuTime;
  }
}

function todayOrTomorrow(val) {
  if(!val || val=='') return
  let aa = parseTime(val,'{y}{m}{d}{h}{i}{s}')
  let bb = parseTime(new Date(),'{y}{m}{d}{h}{i}{s}')
  // console.log(val)
  let cc = val.split(' ')[1]
  let num1 = aa.slice(0,8) // 参数年月日 20211231
  let num2 = bb.slice(0,8) // 当前年月日 20220101
  if(num1 == num2){
    return '今天' + cc
  }else if(num1 - num2 > 0){
    return '明天' + cc
  }else {
    return val
  }
}

/**
 * ? 格式化时间
 * @param {time} 传入的时间,为字符串或者标准时间格式
 * @param {cFormat} 输出的时间格式,默认格式为 '{y}-{m}-{d} {h}:{i}:{s}'
 */
function parseTime(time, cFormat) {
  if (arguments.length === 0) {
    return null
  }
  const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
  let date
  if (typeof time === 'object') {
    date = time
  } else {
    if (time.indexOf('T') > -1) {
      time = time.replace('T', ' ')
      if (time.indexOf('.') > -1) time = time.substring(0, time.indexOf('.'))
    }
    if (('' + time).length === 10) time = parseInt(time) * 1000
    time = time.split(/[- : \/]/)
    date = new Date(time[0], time[1] - 1, time[2], time[3], time[4], time[5])
  }
  const formatObj = {
    y: date.getFullYear(),
    m: date.getMonth() + 1,
    d: date.getDate(),
    h: date.getHours(),
    i: date.getMinutes(),
    s: date.getSeconds(),
    S: date.getMilliseconds(),
    a: date.getDay()
  }
  const time_str = format.replace(/{(y|m|d|h|i|s|S|a)+}/g, (result, key) => {
    let value = formatObj[key]
    if (key === 'a') return ['一', '二', '三', '四', '五', '六', '日'][value - 1]
    if (result.length > 0 && value < 10) {
      value = '0' + value
    }
    return value || 0
  })
  return time_str
}


/**
 * 处理字符串为*格式, 中间显示自定义*号
 * str 需要处理的字符串
 * startLength 前面显示的字符串长度
 * endLength后面显示的字符串长度
 */
 
let sub = function(str, startLength, endLength) {
  if(str.length == 0 || str == undefined) {
    return "";
  }
  let length = str.length;
  if(length >= startLength + endLength) {
    // 判断当字符串长度为二时, 隐藏末尾
    if(length === 2) {
      return str.substring(0, 1) + '*';
    }
    else if(3 <= length && length <= 10) {
      return str.substring(0, 1) + '**';
    }
    // 判断字符串长度大于首尾字符串长度之和时, 隐藏中间部分
    else if(length >= 11) {
      return str.substring(0, startLength) + '****' + str.substring(length - endLength, length);
    } else {
      return str
    }
  }
}

module.exports = {
  getCurrentTime: getCurrentTime,
  objLength: objLength,
  displayProp: displayProp,
  sTrim: sTrim,
  replaceColon: replaceColon,
  vailPhone: vailPhone,
  ifSpanish: ifSpanish,
  div: div,
  mul: mul,
  accAdd: accAdd,
  convertStarArray: convertStarArray,
  random,
  parseMoney,
  AmountToFenValue,
  formatDistance,
  getDistance,
  rad,
  fmtTime,
  yyTime,
  getHourMinutesTime,
  getYearMonthDayTime,
  addTime,
  formartTime,
  getWeekDate,
  getParamsValueFromUrlByKey,
  GetGuid,
  chaDate,
  bjDate,
  todayOrTomorrow,
  parseTime,
  sub
}

The scene when used:

When using it, it can be regarded as a normal page, jump directly ---> return the page stack through the getCurrentPages method, and then get the selected location information, and finally render it to the page. (How to use getCurrentPages is introduced in this blog)

[WeChat applet] About the use of getCurrentPages()_Grapefruit can only ctrl c+v blog-CSDN blog_WeChat applet getcurrentpage getCurrentPages() function https://blog.csdn.net/qq_58620659/article/details/125993243

Write a demo, the following is the sample code:

<template>
	<view @click="goAddress_map">

<text> 选择地址 </text>

选择的地址为:

<text>{
   
   {mainAddress}}</text>
<text>{
   
   {addressDetails}}</text>

    </view>
</template>

<script>
	export default {

		data() {
			return {
				addressMsg: {}, //修改地址时传过来的地址信息
				addressList: [],
				addressId: '',

				mainAddress: '', //province + city + district;
				province: '', //省
				city: '', //市
				area: '', //区
				addressDetails: '', //详细地址
				location: {}, // 当前经纬度

			};
		},
		onShow() {
			/*  获取地址页面传过来的参数id */
			let pages = getCurrentPages()
			let currPage = pages[pages.length - 1]
			console.log(currPage.data, 'curr.data');
			// 地图页面返回数据后才可以赋值
			if (currPage.data.addressArr) {
				this.mainAddress = currPage.data.addressArr //上海市上海市黄浦区
				this.province = currPage.data.province
				this.city = currPage.data.city
				this.area = currPage.data.area
				this.location = currPage.data.location
				this.addressDetails = currPage.data.address
			}
		},
		methods: {
		
			// 获取地图
			goAddress_map() {

            //addressMap.vue
				uni.navigateTo({
					url: '/pages/addressMap/addressMap'
				})
			},
			
			
		}

	}
</script>

Recorded.

Guess you like

Origin blog.csdn.net/ONLYSRY/article/details/127637021