uniapp使用map组件-腾讯地图,拖拽时如何判断是否在多边形内--解决区域间空隙(水区)判断错误问题

遇到的问题

  • 背景:uni-app开发小程序,使用map组件实现地图功能;用户拖拽时需要判断是否在本市内;原先使用本市内所有区域的覆盖物进行判断,拖拽过程取中心点,但如果区域之间存在空隙(江河-如下图),中心点在江中间时,我并没有画这个区域,会判断为不在本市内;所以最终改成直接查本市整体的覆盖物进行判断
  • 解决:需要判断位置坐标点是否在多边形内–采用射线法判断
    在这里插入图片描述

解决

  • 实现代码

    <!-- .vue页面文件 -->
    <template>
    	<!-- map组件,此处省略了其他属性配置,核心是在regionchange事件上 -->
    	<map id="map" style="..." :latitude="..." :longitude="..." subkey="你的地图key" :show-location="true" show-scale :markers="[]" :scale="scaleNum" :polyline="..." :circles="..." :polygons="..."  @regionchange="regionchange"></map>
    	...
    </template>
    
    <script>
      export default {
      	data(){
            bordersOfShangHai: [[120.856125, 31.874025],[121.99159, 31.874025],[121.99159, 30.691927],[120.856125, 30.691927]] // 本市边界覆盖物
      	},
      	...
      	methods: {
      		//regionchange:map组件内置函数--视野发生变化时触发
      		regionchange (e) {
      			var self = this
      			// 用户拖拽时-解析当前位置
      			if (e.type === 'end' && e.causedBy === 'drag'){
                    self.getUserPos(e.target.centerLocation) //调用判断是否在本市内的函数
      			}
      		},
      		
      		//封装判断是否在本市内的函数
      		getUserPos(centerLocation) {
    			const self = this
    			if(!centerLocation) return false
    			self.isinSh = self.isInPolygon([centerLocation.longitude,centerLocation.latitude], self.bordersOfShangHai)
    			//bordersOfShangHai四个点是本市最大最小的经纬度,判断是否在本市,经度是否在最大最小内,纬度是否在最大最小纬度内
    		},
    		
    		//判断位置坐标是否在多边形内的函数提取--核心实现方法
    			//具体采用:判断一个点是否在多边形内--射线法
    		isInPolygon(dot, polygons) {
                let counter = 0
                let i
                let yinters
                let p1, p2
                let pointCount = polygons.length
                p1 = polygons[0]
                // 临界值控制-dot不在polygons中
                if(polygons.some(it => it[0] == dot[0] && it[1] == dot[1])) return true
                for (i = 1; i <= pointCount; i++) {
                    p2 = polygons[i % pointCount]
                    if (dot[0] > Math.min(p1[0], p2[0]) && dot[0] <= Math.max(p1[0], p2[0])) {
                        if (dot[1] <= Math.max(p1[1], p2[1])) {
                            if (p1[0] != p2[0]) {
                                yinters = (dot[0] - p1[0]) * (p2[1] - p1[1]) / (p2[0] - p1[0]) + p1[1]
                                if (p1[1] == p2[1] || dot[1] <= yinters) {
                                    counter++
                                }
                            }
                        }
                    }
                    p1 = p2
                }
                return counter % 2 !== 0
            }
      	}
      }
    
  • 射线法原理:一个点向一个方向发送射线,射线与多边形各个边相交的交点如果是奇数说明点在多边形范围内
    图片引自:https://blog.csdn.net/qq_27161673/article/details/52973866
    (图片引自:https://blog.csdn.net/qq_27161673/article/details/52973866)

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值