确定一个点是否在leaflet多边形内部。

31

如果多边形是封闭的,则可以确定每个线段的方向(内部/外部)。从任意点绘制半条线到无限远处将以奇数或偶数个线段交点结束(对于每个方向始终为奇数或始终为偶数):偶数个交点是多边形外部的点,奇数个交点是内部的点。因此,您可以选择任何方向,例如x轴:检查[pt.x,pt.y]-[inf,pt.y]上的相交线段(您还可以将半线限制在多边形的边界框内)。当然,有更有效的方法来实现这一点:https://en.wikipedia.org/wiki/Point_location - BeyelerStudios
我想问是否有一种方法可以让我确定一个多边形的纬度和经度,然后使用JavaScript确定点是否在多边形内。 - Majdi Taleb
3个回答

56

使用射线投射算法检查点(标记)是否位于多边形内:

function isMarkerInsidePolygon(marker, poly) {
    var polyPoints = poly.getLatLngs();       
    var x = marker.getLatLng().lat, y = marker.getLatLng().lng;

    var inside = false;
    for (var i = 0, j = polyPoints.length - 1; i < polyPoints.length; j = i++) {
        var xi = polyPoints[i].lat, yi = polyPoints[i].lng;
        var xj = polyPoints[j].lat, yj = polyPoints[j].lng;

        var intersect = ((yi > y) != (yj > y))
            && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
        if (intersect) inside = !inside;
    }

    return inside;
};

请参考这个例子:jsfiddle

代码原始来源:https://github.com/substack/point-in-polygon/blob/master/index.js


还可以查看2014年类似的答案:https://dev59.com/iVgR5IYBdhLWcg3wm-K6#41138512


6
尽管 poly.getLatLngs() 返回一个数组的数组,所以第一行必须是 var polyPoints = poly.getLatLngs()[0];,这样才能正常工作。如果您想支持环状多边形,则需要添加另一个循环包装。 - ProblemsOfSumit

20

这是经过@Sumit提示修改的@gusper答案,对我有效(我吃了甜甜圈)。

function isMarkerInsidePolygon(marker, poly) {
    var inside = false;
    var x = marker.getLatLng().lat, y = marker.getLatLng().lng;
    for (var ii=0;ii<poly.getLatLngs().length;ii++){
        var polyPoints = poly.getLatLngs()[ii];
        for (var i = 0, j = polyPoints.length - 1; i < polyPoints.length; j = i++) {
            var xi = polyPoints[i].lat, yi = polyPoints[i].lng;
            var xj = polyPoints[j].lat, yj = polyPoints[j].lng;

            var intersect = ((yi > y) != (yj > y))
                && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
            if (intersect) inside = !inside;
        }
    }

    return inside;
};

1
这对于任意形状的多边形对我来说都有效。谢谢。 - Abdul Salam

8
我发现以上答案都不能准确计算非连续多边形内的标记数量。以下是一个多边形示例,以上函数返回0个标记:

Non-contiguous Polygon

如果有人需要这样做,可以尝试使用Leaflet.PointInPolygon包: https://github.com/hayeswise/Leaflet.PointInPolygon 虽然速度有点慢,但似乎很准确。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接