判断给定坐标点是否规定区域内

之前一个项目涉及到GIS方面,使用的是leaflet;要求功能:是在地图上可以动态绘制图形,并筛选展示该图形区域内的标记点;

首先,绘制图形的功能使用了leaflet.draw http://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
调用地图监听事件

// 监听绘制完成
	map.on(L.Draw.Event.CREATED, function (e) {
        var type = e.layerType,
			layer = e.layer;
			console.log(layer)
		drawnItems.addLayer(layer);  // 添加图层
		for (var i in markers) {
			var marker = markers[i];
			// console.log(marker)
			if(layer._mRadius){   // 判断绘制图形是否为圆形
				// 调用函数  得出点到圆心的距离
				var distance = geoDistance(marker.position.lat,marker.position.lng, layer._latlng.lat,layer._latlng.lng)
				// 判断距离是否小于半径
				if (distance*1000 <= layer._mRadius){
					console.log(i)
				}
			}else{
				if (polygonFilter(marker.position, layer._latlngs[0])){    // 判断是否在区域内
					console.log(i)
				}
			}
        }
	});

看了上面的代码就知道,我对绘制图形做了下判断;
因为当时有多边形、矩形、圆形选择绘制,矩形属于特殊多边形,可以共用下面的多边形的判断方式;但圆形判断不适用

/**
	 * 区域筛选 => 多边形
	 * @param checkPoint 点坐标(经纬度)
	 * @param polygonPoints  区域组成坐标(经纬度)
	 * 
	 */
	function polygonFilter(checkPoint, polygonPoints) {
        var counter = 0;
        var i;
        var xinters;
        var p1, p2;
        var pointCount = polygonPoints.length;
        p1 = polygonPoints[0];

        for (i = 1; i <= pointCount; i++) {
            p2 = polygonPoints[i % pointCount];
            if (
                checkPoint.lat > Math.min(p1.lat, p2.lat) &&
                checkPoint.lat <= Math.max(p1.lat, p2.lat)
            ) {
                if (checkPoint.lng <= Math.max(p1.lng, p2.lng)) {
                    if (p1.lat != p2.lat) {
                        xinters =
                            (checkPoint.lat - p1.lat) *
                            (p2.lng - p1.lng) /
                            (p2.lat - p1.lat) + p1.lng;
                        if (p1.lng == p2.lng || checkPoint.lng <= xinters) {
                            counter++;
                        }
                    }
                }
            }
            p1 = p2;
        }
        if (counter % 2 == 0) {
            return false;
        } else {
            return true;
        }
	}

有了上面的方法,多边形的筛选已经可以了;但该方法不适用于圆形区域的筛选,那圆形区域该怎么筛选呢?






灵光一闪,可以判断点到圆心的距离,然后再跟半径比较大小,不就可以判断点是否在圆内吗

//经纬度转换成三角函数中度分表形式。
	function rad(d) {
		return d * Math.PI / 180.0;
	}
	/**
	 * 计算两个经纬度间的距离
	 * @param lat1  纬度
	 * @param lng1  经度
	 * @param lat2  纬度
	 * @param lng2  经度
	 */
	function geoDistance(lat1, lng1, lat2, lng2) {
		let radLat1 = rad(lat1);
		let radLat2 = rad(lat2);
		let a = radLat1 - radLat2;
		let b = rad(lng1) - 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;
	}

上面的方法可以得出两个经纬度之间的距离
得出距离了现在可以跟半径比较了,圆半径可以在上面的监听回调得到数据,但这里要注意的是我们需要的是距离半径,不是绘制图形的半径

还有一个注意点:距离单位的换算,上面算经纬度间距离的返回单位是km

你可能感兴趣的:(leaflet,vue,leaflet)