前期准备
- 小程序开启定位权限
- 小程序配置普通h5二维码打开小程序的功能
开启小程序定位权限
打开小程序管理后台( 用户隐私保护指引),设置-基本设置-服务内容声明
下图是已经设置好的样子,如果未设置 点击下方增加 位置信息
注意:申请后需要等待审核,审核成功后可能不会立刻成功,需要再等一会儿再行。
配置普通二维码跳转小程序
可参考 链接
配置如下,需要注意的是不同状态下 要对应不同的 状态(开发、体验、线上)。
如图,配置好就可以实现 微信扫描h5二维码 直接跳转小程序内页面的功能。
小程序内新增中转页
本次主要功能是在小程序页面内完成定位签到的功能,但是考虑到后期也有别的功能,因此本次做了一个中转页,用来区分跳到具体哪一个小程序页面,这样就无需每次都去小程序后台去调整配置,本次中转页接受两个参数:
css
{
page:'页面类型,判断跳转到具体哪个小程序页面',
param:'对应页面所需的参数,并用encodeURIComponent进行编码'
}
然后中转页进行目标页面跳转逻辑的处理:
定位&签到页面
www.domain.com/miniprogram... 参数会 可以在 options.q 里取到。
配置好二维码链接的 page 和 param ,经历上一步的 中转页逻辑,可以正常跳到小程序的签到页,如下:
图中 打卡位置可以通过 marker来配置, 打卡范围的圈可以通过 circle来配置,marker的大小不会随着地图大小变化,circle会跟随地图缩放变大变小,所以根据自己的情况进行配置,配置好赋值给 map组件的同名属性即可。
yaml
markers: [
{
id: 1,
callout: {
content: '打卡位置',
padding: 10,
borderRadius: 2,
display: 'ALWAYS',
},
latitude: 0,
longitude: 0,
iconPath: './imgs/adress.png',
width: '34px',
height: '34px',
rotate: 0,
alpha: 1,
},
],
circles: [
{
latitude: 0,
longitude: 0,
radius: 10,
color: '#FE7A06',
fillColor: 'rgba(254, 122, 6, 0.1)',
},
],
进入页面的时候,需要判断用户是否授权定位权限,如果为获取需要弹窗提醒:
javascript
async initLocationAuth() {
const hasLocationAuth = await this.checkLocationAuth();
if (hasLocationAuth) {
this.getLocation();
}
},
async checkLocationAuth() {
return new Promise((resolve, reject) => {
wx.getSetting({
success(res) {
console.log('getSetting', res);
if (res.authSetting['scope.userLocation']) {
resolve(true);
return;
}
// 授权弹窗
wx.authorize({
scope: 'scope.userLocation',
success() {
resolve(true);
},
});
},
});
});
},
getLocation() {
return new Promise((resolve, reject) => {
wx.getLocation({
type: 'gcj02',
isHighAccuracy: true,
success: (res) => {
const { latitude, longitude } = res;
resolve({ latitude, longitude });
},
fail(err) {
reject(err);
},
});
});
},
授权成功后,getLocation就可以正常获取经纬度坐标。
关于坐标转化
在某些特殊场景下,我们跟后端交互的数据并非都是一致的,所以需要坐标转化
-
百度地图:使用的是百度自己的坐标系统,称为BD-09坐标系。这个坐标系是在火星坐标系(GCJ-02)基础上进行了一定的加密转换。
-
高德地图(以及腾讯地图) :主要使用的是GCJ-02坐标系,俗称"火星坐标系"。GCJ-02是中国国家测绘局制定的一种地理坐标系统,主要是为了确保国家地理信息安全,对WGS-84(全球通用的GPS坐标系)进行了加密处理。
转化公式如下:
ini
/**
* 百度BD-09坐标转为高德/腾讯 gcj02 坐标
* @param {*} bd_lon:经度
* @param {*} bd_lat:纬度
* @returns
*/
function bd09togcj02(bd_lon, bd_lat) {
const x_pi = (3.14159265358979324 * 3000.0) / 180.0;
const x = bd_lon - 0.0065;
const y = bd_lat - 0.006;
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
const gg_lon = z * Math.cos(theta);
const gg_lat = z * Math.sin(theta);
return [gg_lon, gg_lat];
}
/**
* 高德/腾讯 gcj02 坐标转为百度BD-09坐标
* @param {*} lon:经度
* @param {*} lat:纬度
* @returns
*/
function gcj02tobd09(lon, lat) {
const x_pi = (3.14159265358979324 * 3000.0) / 180.0;
const z = Math.sqrt(lon * lon + lat * lat) + 0.00002 * Math.sin(lat * x_pi);
const theta = Math.atan2(lat, lon) + 0.000003 * Math.cos(lon * x_pi);
const bd_lon = z * Math.cos(theta) + 0.0065;
const bd_lat = z * Math.sin(theta) + 0.006;
return [bd_lon, bd_lat];
}
遇到的问题
定位后 中心点为当前位置,当地图是可拖动的时候,在位置未发生变化的情况下,再次设置当前经纬度并不会重新 把当前位置重新更新为中心点,点击定位地图无变化
解决方案是,不要直接设置当前的经纬度,而是先设置一个别的经纬度,然后在设置当前位置的经纬度