微信小程序电子围栏-圆心-半径-画圆-判断是否在电子围栏内等

11Java 专栏收录该内容
264 篇文章 1 订阅

1.js

function isPointInPolygon(point, polygon) {

  var pts = polygon;

  var N = pts.length;

  var boundOrVertex = true;

  var intersectCount = 0;

  var precision = 2e-10;

  var p1, p2;

  var p = point;

  p1 = pts[0];

  for (var i = 1; i <= N; ++i) {

    if (p.lat == p1.lat || p.lng == p1.lng) {

      return boundOrVertex

    }

    p2 = pts[i % N];

    if (p.lat < Math.min(p1.lat, p2.lat) || p.lat > Math.max(p1.lat, p2.lat)) {

      p1 = p2;

      continue

    }

    if (p.lat > Math.min(p1.lat, p2.lat) && p.lat < Math.max(p1.lat, p2.lat)) {

      if (p.lng <= Math.max(p1.lng, p2.lng)) {

        if (p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng)) {

          return boundOrVertex

        }

        if (p1.lng == p2.lng) {

          if (p1.lng == p.lng) {

            return boundOrVertex

          } else {

            ++intersectCount

          }

        } else {

          var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng;

          if (Math.abs(p.lng - xinters) < precision) {

            return boundOrVertex

          }

          if (p.lng < xinters) {

            ++intersectCount

          }

        }

      }

    } else {

      if (p.lat == p2.lat && p.lng <= p2.lng) {

        var p3 = pts[(i + 1) % N];

        if (p.lat >= Math.min(p1.lat, p3.lat) && p.lat <= Math.max(p1.lat, p3.lat)) {

          ++intersectCount

        } else {

          intersectCount += 2

        }

      }

    }

    p1 = p2

  }

  if (intersectCount % 2 == 0) {

    return false

  } else {

    return true

  }

}

// t:半径

// e:中心点经纬度坐标[110,40]

// i: 圆上点的个数,默认15个,建议73个

function countCircle(t, e, i) {

  t=300;

  //e=[36.070299,120.370787];

  e=[120.370787,36.070299];

  i=20;

  for(

    var r = t / 6378137,

      n = [e[0], e[1]],

      o = [numberToRadius(n[1]), numberToRadius(n[0])],

      s = ((i = i || 15), []),

      a = 0;

    a < i;

    a++

  ) {

    var u = (2 * Math.PI * a) / i;

    var h = Math.asin(

      Math.sin(o[0]) * Math.cos(r) +

        Math.cos(o[0]) * Math.sin(r) * Math.cos(u)

    );

    var c =

      o[1] +

      Math.atan2(

        Math.sin(u) * Math.sin(r) * Math.cos(o[0]),

        Math.cos(r) - Math.sin(o[0]) * Math.sin(h)

      );

    s.push([numberToDegree(c), numberToDegree(h)]);

  }

  s.push(s[0])

  return [s];

}

function numberToRadius(t) {

  return (t * Math.PI) / 180;

}

function numberToDegree(t) {

  return (180 * t) / Math.PI;

}

 

module.exports = {

  countCircle:countCircle,

  numberToRadius:numberToRadius,

  numberToDegree:numberToDegree,

  isPointInPolygon: isPointInPolygon

};

2.页面

 

import {

  isPointInPolygon,countCircle,numberToRadius,numberToDegree

} from '../utils/isPointInPolygon.js';

let newPoint = {

  // latitude: 80.47951,

  // longitude: 118.08948

  latitude: 36.070553,

  longitude: 120.372574,

};

Page({

    data: {

      latitude: newPoint.latitude,

      longitude: newPoint.longitude,

      markers: [],

      polygons: [],

      paramspolygones: [],

 

    },

    tapHandle() {

      //模拟定位点是否在围栏内

      if (!this.data.polygons.length) {

        return wx.showToast({

          title: '当前没有设置围栏',

          icon: 'none',

          mask: true

        })

      }

      let array = this.data.polygons[0].points;

      let newArray = [];

      for (let j = 0; j < array.length; j++) {

        let obj = {};

        obj.lng = array[j].longitude;

        obj.lat = array[j].latitude;

        newArray.push(obj)

      }

      this.setData({

        paramspolygones: newArray

      })

      let nowPoint = {};

      nowPoint.lat = newPoint.latitude

      nowPoint.lng = newPoint.longitude

      //true表示在围栏内反之围栏外

      let flag = isPointInPolygon(nowPoint, newArray);

      wx.showToast({

        title: flag?'正常:在围栏里面':'异常:在围栏外面',

        icon:'none'

      })

    },

    creatPolygons() { 

      //创建多边形围栏/服务范围

      if (this.data.markers.length < 3){

        debugger

        return wx.showToast({

          title: '请先在地图上标记点,且不少于三个点',

          icon:'none'

        })

      }

      let polygons = this.data.polygons;

      let markers = this.data.markers;

      let newArray = [];

      let params = {

        fillColor: "#1791fc66",

        strokeColor: "#FFF",

        strokeWidth: 2,

        zIndex: 3

      }

      for (let j = 0; j < markers.length; j++) {

        let obj = {

          latitude: markers[j].latitude,

          longitude: markers[j].longitude

        };

        newArray.push(obj);

      }

      polygons[0] = {};

      polygons[0].points = newArray;

      newArray = Object.assign(polygons[0], params);

      this.setData({

        "polygons[0]": newArray

      })

    },

    //画圆

    creatCircle() {

      var array=countCircle('','','');

      var jsons=[]

      array[0].forEach(element => {

        var json={};

        json.latitude=element[1]

        json.longitude=element[0]

        console.log('>>>>>>>>>>json>>>>'+JSON.stringify(json))

       // debugger

       jsons.push(json);

      });

       //this.data.markers=jsons

       debugger

 

       let polygons = this.data.polygons;

       let markers = this.data.markers;

       let newArray = [];

       let params = {

         fillColor: "#1791fc66",

         strokeColor: "#FFF",

         strokeWidth: 2,

         zIndex: 3

       }

       

       polygons[0] = {};

       polygons[0].points = jsons;//newArray;

       newArray = Object.assign(polygons[0], params);

       this.setData({

         "polygons[0]": newArray

       })

     },

    bindtapMap(e) {

      //创建标记点

      let tapPoint = e.detail;

      let markers = this.data.markers

      let newContent = markers.length

      let markerItem = {

        callout: {

          content: ++newContent,

          padding: 5,

          borderRadius: 2,

          // bgColor:'#ffffff96',

          bgColor: '#ffffff',

          display: 'ALWAYS',

          anchorY: -15,

          anchorX: 15,

          zIndex: 2

        },

        id: newContent,

        latitude: null,

        longitude: null,

        iconPath: '/images/Marker1_Activated@3x.png',

        width: '34px',

        height: '34px',

        rotate: 0,

        alpha: 1,

        zIndex: 3

      }

      markerItem.latitude = tapPoint.latitude;

      markerItem.longitude = tapPoint.longitude;

      markers.push(markerItem)

      console.log('markerItem>>>'+JSON.stringify(markerItem))

      this.setData({

        markers

      })

    },

    removeMarker(e) {

      //删除重复点击的标记点

      console.log(e.markerId)

      let markers = this.data.markers;

      markers.splice(e.markerId - 1, 1)

      console.log(markers);

      //重置marker数组的id和content

      for (let j = 0; j < markers.length; j++) {

        markers[j].id = j + 1;

        markers[j].callout.content = j + 1;

      }

      this.setData({

        markers

      })

    },

    removePolygons() {

      //删除围栏和标记

      this.setData({

        markers: [],

        polygons: []

      })

    },

    onLoad(options) {},


 

  }

 

)

3.样式

.intro {

  margin: 30px;

  text-align: center;

}

<map id="map" longitude="{{longitude}}" latitude="{{latitude}}" scale="13" controls="{{controls}}" bindcontroltap="controltap" bindtap="bindtapMap" markers="{{markers}}" polyline="{{polyline}}" bindmarkertap="removeMarker" bindlabeltap="removeMarker"

  polygons="{{polygons.length >0 ? polygons :''}}" bindregiοnchange="regionchange" show-location style="width: 100%; height: 80vh;">

</map>

<button type="primary" bindtap="tapHandle">是否在围栏内</button>

{{polygons[0].length}}

<button type="primary" bindtap="creatCircle">电子围栏画圆</button>

<button type="primary" bindtap="creatPolygons">生成围栏</button>

<button type="primary" bindtap="removePolygons">删除围栏</button>

 

  • 1
    点赞
  • 0
    评论
  • 8
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:书香水墨 设计师:CSDN官方博客 返回首页

打赏作者

小屁孩大帅-杨少平

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值