腾讯地图 算法 判断一个不规则区域是否在另一个不规则区域的内部(可用)

腾讯的地图polygon.getBounds().contains方法有BUG,点位不在区域内部也会返回true,需要自定义一套算法,核心算法如下:

核心算法:

function isPointInsidePolygon(point, vertices) {
	const x = point[0], y = point[1];

	let inside = false;
	for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
		const xi = vertices[i][0], yi = vertices[i][1];
		const xj = vertices[j][0], yj = vertices[j][1];

		const intersect = ((yi > y) != (yj > y))
		  && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
		if (intersect) inside = !inside;
	}
	
	console.log(inside)
	return inside;
}

以上,定义了2个数组,第一个数组是单个点位坐标,第二个数组是区域坐标集合。

全部代码如下:有一些变量需要自行变更一下,

<script>
    // 创建地图容器
    var mapContainer = document.getElementById('mapContainer');
    
    var emapdata = JSON.parse('[{"lat":26.07953876638003,"lng":119.37317170117186},{"lat":22.84004277988032,"lng":115.38782013867186},{"lat":22.799537101140757,"lng":110.47961701367186},{"lat":27.351970759039688,"lng":108.01867951367186},{"lat":29.34039231723766,"lng":112.06164826367186},{"lat":29.517413502747424,"lng":103.91357697460938},{"lat":34.16760239879295,"lng":101.56628693554687},{"lat":32.524920428780476,"lng":117.08655060742188},{"lat":30.8987961595119,"lng":120.30969513867186},{"lat":28.339548154213812,"lng":120.82336701367186}]'); // 地图
    var jsonIconPath0 = emapdata[0];
    
    console.log(emapdata);

    var initCenter = new qq.maps.LatLng(jsonIconPath0.lat, jsonIconPath0.lng);
    
    // 初始化地图
    var map = new qq.maps.Map(mapContainer, {
        center: initCenter,
        zoom: 8
    });
    
    // 多边形
    var polygon_emap = new qq.maps.Polygon({
        editable: false, // 开启编辑模式
        path: [ ],
        map: map,
        fillColor: qq.maps.Color.fromHex('#FF6600', 0.4),
        strokeColor: qq.maps.Color.fromHex('#FF6600')
    });

    // 多边形的顶点
    var pathNull = [];
    for (var i = 0; i < emapdata.length; i++) {
        pathNull.push(new qq.maps.LatLng(emapdata[i].lat, emapdata[i].lng));   
    }
    
    polygon_emap.setPath(pathNull);  // 设置多边形 

    // cut标记点
    var marker = new qq.maps.Marker({
        position: new qq.maps.LatLng(jsonIconPath0.lat, jsonIconPath0.lng),  // 可能有多个标记点
        draggable: true,//标注点是否可移动
        map: map,
        icon: 'http://mike888.top/images/recycle/static/others/emapcut100.png'
    });
    
    var polygon_cut = new qq.maps.Polygon({
        editable: true, // 开启编辑模式
        path: [ 
            new qq.maps.LatLng(24.591394658762617, 118.92959870312498),
            new qq.maps.LatLng(24.561421513697372, 117.23758210156248),
            new qq.maps.LatLng(25.742271770221414, 117.46280182812498),
            new qq.maps.LatLng(25.534274184809814, 118.65494049999998)
        ],
        map: map,
        fillColor: qq.maps.Color.fromHex('#0000FF', 0.4),
        strokeColor: qq.maps.Color.fromHex('#0000FF')
    });
    
    function isPointInsidePolygon(point, vertices) {
		const x = point[0], y = point[1];

		let inside = false;
		for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
			const xi = vertices[i][0], yi = vertices[i][1];
			const xj = vertices[j][0], yj = vertices[j][1];

			const intersect = ((yi > y) != (yj > y))
			  && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
			if (intersect) inside = !inside;
		}
		
		console.log(inside)
		return inside;
	}
    
    // 标注点click事件
    qq.maps.event.addListener(marker, 'click', function(event) {
        latIcon = event.latLng.getLat(); //纬度
        lngIcon = event.latLng.getLng(); //经度   
        
        jsonIcon = '{"lat":"' + latIcon + '", "lng":"' + lngIcon + '"}';
        var jsonEmapData = polygon_cut.getPath().elems;
		
		// 获取大区域的所有点位, push到数组中pointEmap
		var pointEmp = [];
		for (var c=0;c<polygon_emap.getPath().elems.length;c++) {
			var arrPointEmap = [];
			arrPointEmap.push(polygon_emap.getPath().elems[c].lat);
			arrPointEmap.push(polygon_emap.getPath().elems[c].lng);
			
			pointEmp.push(arrPointEmap);
		}
		
		// 小区域的单个点位,循环判断是否在大区域内部
		for (var j=0;j<polygon_cut.getPath().elems.length;j++) {
			var arrPoint = [];
			arrPoint.push(polygon_cut.getPath().elems[j].lat);
			arrPoint.push(polygon_cut.getPath().elems[j].lng);
			
			isPointInsidePolygon(arrPoint, pointEmp)
		}

        document.getElementById('iconpath').value = jsonIcon;
        document.getElementById('emapdata').value = jsonEmapData;
    });
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_42436080

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值