最近在开发微信公众号的小项目时候,遇到了一个需求。就是下发奖励时候要限制业务区域,比如说我是在北京搞业务,那么我的一些用户必须定位在北京,达到奖励下发条件的时候才能下发奖励,业务区域之外的不能下发奖励,这样才能得到本业务区域中的精准流量。
思路分析
一想到地图的业务,第一反应是需要对接高德地图的经纬度解析的接口。大体思路是,公众号中通过jssdk授权获取用户的经纬度信息。将经纬度信息存储到用户个人信息中。当用户需要下发奖励时候,通过用户个人信息的经纬度,请求高德地图的经纬度转换,获取到的具体省份信息进行业务判断即可。但是就这么一个小项目,还得对接高德,申请key创建应用啥的。作为开发者肯定是不愿自己去倒腾的,所以对客户那边肯定是直接说,地图业务太复杂,搞不了这个。(不愿搞就是搞不了)
但是老板那边给予压力,说这是客户的最基本要求,必须搞。(不搞就扣你工资)
无奈必须得整的需求,那就想想简单的实现方法。在地图上圈出一组经纬度的区域,然后用一个坐标通过计算,判断当前坐标是否在区域内即可。就完美避开了对接高德的这个问题。
实现方法
- 公众号通过jsskd下发经纬度
javascript
jssdk_config(window.location.href)
.then(res=>{
let _this = this
jWeixin.error((err) => {console.error(err);});
jWeixin.config(res.data);
jWeixin.ready(function(){
wx.getLocation({
type: 'wgs84', // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
success: function (res1) {
var latitude = res1.latitude; // 纬度,浮点数,范围为90 ~ -90
var longitude = res1.longitude; // 经度,浮点数,范围为180 ~ -180。
var speed = res1.speed; // 速度,以米/每秒计
var accuracy = res1.accuracy; // 位置精度
//后续业务
},
fail:function(e){
console.log('location_err',e)
uni.showToast({
icon:'none',
title:'获取位置失败,请确定是否开启手机位置开关'
})
}
});
})
})
其中 jssdk_config方法是从服务端下发jsskd配置信息的接口,参数是当前页面的url。jWeixin是uniapp中模块化的jssdk。此时在公众号中就能获取用户的位置信息
- 在地图中圈出业务区域的坐标 在地图圈点中查找业务的坐标区域即可。
- 通过php的方法,计算当前坐标是否在上方的划定的区域中。
bash
//使用射线法或点在多边形内部判断方法
function pointInPolygon($lng,$lat, $polygon) {
$count = count($polygon);
$inPolygon = false;
for ($i = 0, $j = $count - 1; $i < $count; $j = $i++) {
$polyLngI = $polygon[$i][0];
$polyLatI = $polygon[$i][1];
$polyLngJ = $polygon[$j][0];
$polyLatJ = $polygon[$j][1];
if (((($polyLngI <= $lng) && ($lng < $polyLngJ)) || (($polyLngJ <= $lng) && ($lng < $polyLngI))) && ($lat < ($polyLatJ - $polyLatI) * ($lng - $polyLngI) / ($polyLngJ - $polyLngI) + $polyLatI)) {
$inPolygon = !$inPolygon;
}
}
return $inPolygon;
}
这样就通过一个简单的方法,实现了区域的计算逻辑。