微信小程序定位-判断在某个区域内

需求

到店扫码:用户扫某区域内商户二维码,定位当前位置,若处于范围内,给权益奖励。

申请类目

设置-基本设置-服务类目

可申请的类目: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
}

效果 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值