筛选直线一定范围内的坐标点

绘制直线,我们可以拿到形成直线的点集合数据;那我们只要求坐标点到这个直线的距离是否在范围内就可以解决问题。
那这里用的是坐标点与直线两端形成的夹角,判断两边夹角来判断坐标点出直线什么位置(线内、线外),线内的话算出点到线的垂直距离,线外求点带直线两端的距离

注意:由于我们需要的直线夹角是在180度之内,但在计算时由于形成直线方向的问题,会出现大于180的直线夹角,解决这个问题我们是判断所有大于180度的夹角,用360减去夹角得到想要的直线想成的夹角; 还有如果是多段线形成的直线,最后结果不要忘记筛重

/**
* 求点到直线的距离
* @param latlngs  形成直线的点集合
*/
toLineDistance(latlngs){
   var lineRangeDevice = []
   for(let i = 0;i < latlngs.length-1;i++){
       var startDot = latlngs[i],
           endDot = latlngs[i+1];
       for (let i in this.allMarkers) {
           let marker = this.allMarkers[i];
           // 计算设备-结束点形成的直线 与 起始点-结束点形成直线的夹角
           let endDotAngle = this.getLineAngle({
               x:this.rad(marker.position.lng) - this.rad(endDot.lng),
               y:this.rad(marker.position.lat) - this.rad(endDot.lat)
           },{
               x:this.rad(startDot.lng) - this.rad(endDot.lng),
               y:this.rad(startDot.lat) - this.rad(endDot.lat)
           })
           if(endDotAngle > 180){
               endDotAngle = 360 - endDotAngle
           }
           // 计算设备-起始点形成的直线 与 起始点-结束点形成直线的夹角
           let startDotAngle = this.getLineAngle({
               x:this.rad(marker.position.lng) - this.rad(startDot.lng),
               y:this.rad(marker.position.lat) - this.rad(startDot.lat)
           },{
               x:this.rad(endDot.lng) - this.rad(startDot.lng),
               y:this.rad(endDot.lat) - this.rad(startDot.lat)
           })
           if(startDotAngle > 180){
               startDotAngle = 360 - startDotAngle
           }
           // 夹角小于90度
           if(startDotAngle < 90 && endDotAngle < 90){
               let endDotDistance = this.geoDistance(marker.position.lat, marker.position.lng, endDot.lat, endDot.lng) * 1000
               //获得弧度
               let radian = 2 * Math.PI / 360 * endDotAngle;
               let distance = Math.sin(radian) * endDotDistance    //对边
               if(distance <= this.distanceRange){
                   lineRangeDevice.push(marker.data.data)
               }
           }else{
               let startDotDistance = this.geoDistance(marker.position.lat, marker.position.lng, startDot.lat, startDot.lng) * 1000
               let endDotDistance = this.geoDistance(marker.position.lat, marker.position.lng, endDot.lat, endDot.lng) * 1000
               if(
                   (startDotDistance <= this.distanceRange) || 
                   (endDotDistance <= this.distanceRange)
               ){
                   lineRangeDevice.push(marker.data.data)
               } 
           }
       }
   }
   let devices = Array.from(new Set(lineRangeDevice))
}, 

求直线夹角,参数是另外两点与相交点的坐标差

// 求两条直线角度
getLineAngle: ({ x: x1, y: y1 }, { x: x2, y: y2 }) => {
    const dot = x1 * x2 + y1 * y2
    const det = x1 * y2 - y1 * x2
    const angle = Math.atan2(det, dot) / Math.PI * 180
    return (angle + 360) % 360
},
//经纬度转换成三角函数中度分表形式。
rad:function(d) {
    return d * Math.PI / 180.0;
},

计算两点间的距离,也可以用leaflet提供的distance方法

/**
* 计算两个经纬度间的距离
* @param lat1  纬度
* @param lng1  经度
* @param lat2  纬度
* @param lng2  经度
*/
geoDistance:function(lat1, lng1, lat2, lng2) {
   let radLat1 = this.rad(lat1);
   let radLat2 = this.rad(lat2);
   let a = radLat1 - radLat2;
   let b = this.rad(lng1) - this.rad(lng2);
   let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
   s = s * 6378.137;// EARTH_RADIUS;
   s = Math.round(s * 10000) / 10000; //输出为公里
   return s;
},
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值