需求
到店扫码:用户扫某区域内商户二维码,定位当前位置,若处于范围内,给权益奖励。
申请类目
设置-基本设置-服务类目
可申请的类目:wx.getLocation(Object object) | 微信开放文档
申请接口
「开发」-「开发管理」-「接口设置」中自助开通该接口权限
注意:最好是业务使用场景描述+设计图,不然容易被打回
绘制区域
location.vue
<template>
<div class="map-demo">
<p>运动轨迹demo</p>
<!-- <button @click="changeAddress(31.295086338153187,120.5656927257101)">金河国际中心(内)</button> -->
<button @click="changeAddress(31.29456431127307, 120.56611554252508,'华福大厦')">华福大厦(内)</button>
<button @click="changeAddress(31.295212348469367, 120.567418833339,'挹翠华庭')">挹翠华庭(外)</button>
<map v-if="location.latitude" class="map" id="map"
:longitude="location.longitude"
:latitude="location.latitude"
scale="17"
:polygons="polygons"
@markertap="markertap"
show-location></map>
</div>
</template>
<script>
import { IsPtInPoly } from '@/modules/utils/point'
export default {
data(){
return{
location:{
accuracy: null,
errMsg: "",
horizontalAccuracy: null,
latitude: null,
longitude: null,
speed: null,
verticalAccuracy: null
},
markers:[{
id:31.294215390611186,
latitude: 31.294215390611186,
longitude: 120.56567126803878
}],
// 参考:https://developers.weixin.qq.com/miniprogram/dev/component/map.html#%E5%9C%B0%E5%9B%BE%E5%9F%BA%E7%A1%80%E5%B1%9E%E6%80%A7
polygons:[{
points:[{
latitude: 31.295164416703983,
longitude: 120.56518388969246
},{
latitude: 31.294412652555245,
longitude: 120.56502295715764
},{
latitude: 31.294192622889625,
longitude: 120.5657096026395
},{
latitude: 31.294385148875147,
longitude: 120.56706143593188
},{
latitude: 31.29492605311089,
longitude: 120.56698633408232
},{
latitude: 31.295411947489562,
longitude: 120.56676102853358
},{
latitude: 31.295402779694275,
longitude: 120.56583834866736
}],
strokeWidth:1,
strokeColor:'#000',
fillColor:'#87cefa80'
}] // 多边形
}
},
onShow() {
const that = this
wx.authorize({
scope: 'scope.userLocation',
success() {
wx.getLocation({
isHighAccuracy: true,
type: 'gcj02',
success (res) {
console.log(res)
that.location = res
const result = IsPtInPoly(res.latitude,res.longitude,that.polygons[0].points)
that.showToast(result,'当前')
},
fail: err => { // 获取定位失败
console.log(err, '定位失败')
}
})
},
fail:err => {
wx.showModal({
title: '您未开启地理位置授权',
content: '请开启地理位置授权',
success: res => {
if (res.confirm) {
wx.openSetting()
}
}
})
}
});
},
methods:{
changeAddress(latitude,longitude,name){
const result = IsPtInPoly(latitude,longitude,this.polygons[0].points)
this.showToast(result,name)
},
showToast(result,name){
wx.showToast({
title: result ? name + '在范围内' : name +'不在范围内!',
icon: result ? 'success' : 'error',
duration: 2000
})
}
}
};
</script>
<style lang="stylus" scoped>
.map-demo
p
text-align center
margin 20px auto
.map
width 100%
height 100vh
</style>>
判断是否在范围内
point.js
function IsPtInPoly (aLat, aLon, pointList) {
/*
:param aLon: double 经度
:param aLat: double 纬度
:param pointList: list [{latitude: 22.22, longitude: 113.113}...] 多边形点的顺序需根据顺时针或逆时针,不能乱
*/
let iSum = 0
let iCount = pointList.length
if (iCount < 3) {
return false
}
// 待判断的点(x, y) 为已知值
let y = aLat
let x = aLon
for (let i = 0; i < iCount; i++) {
let y1 = pointList[i].latitude
let x1 = pointList[i].longitude
let y2 = null
let x2 = null
if (i === iCount - 1) {
y2 = pointList[0].latitude
x2 = pointList[0].longitude
} else {
y2 = pointList[i + 1].latitude
x2 = pointList[i + 1].longitude
}
// 当前边的 2 个端点分别为 已知值(x1, y1), (x2, y2)
if (((y >= y1) && (y < y2)) || ((y >= y2) && (y < y1))) {
// y 界于 y1 和 y2 之间
// 假设过待判断点(x, y)的水平直线和当前边的交点为(x_intersect, y_intersect),有y_intersect = y
// 则有(2个相似三角形,公用顶角,宽/宽 = 高/高):|x1 - x2| / |x1 - x_intersect| = |y1 - y2| / |y1 - y|
if (Math.abs(y1 - y2) > 0) {
let xIntersect = x1 - ((x1 - x2) * (y1 - y)) / (y1 - y2)
if (xIntersect < x) {
iSum += 1
}
}
}
}
if (iSum % 2 !== 0) {
return true
} else {
return false
}
}
module.exports = {
IsPtInPoly
}
效果