确定一个点是不是位于传单多边形内

Posted

技术标签:

【中文标题】确定一个点是不是位于传单多边形内【英文标题】:Determine if a point reside inside a leaflet polygon确定一个点是否位于传单多边形内 【发布时间】:2015-10-25 17:46:02 【问题描述】:

假设我在下面的演示中使用传单绘制一个多边形: http://leaflet.github.io/Leaflet.draw/

我的问题是如何确定给定点是否位于多边形内。

【问题讨论】:

如果多边形是闭合的,那么您可以定位每个线段(内部/外部)。从任意点到无穷远绘制一条半线最终会产生奇数或偶数个线段交叉点(每个方向总是奇数或总是偶数):偶数个交叉点是多边形外的点,奇数个是多边形内的点。因此,您可以选择任何方向,例如x 轴:检查[pt.x,pt.y]-[inf, pt.y] 上的相交段(您也可以将半线绑定到多边形的边界框)。当然有更有效的方法:en.wikipedia.org/wiki/Point_location 请问有没有方法可以让我确定一个多边形的经纬度,然后用javascript判断点是否在多边形内 【参考方案1】:

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

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://***.com/a/41138512/287948

【讨论】:

虽然 poly.getLatLngs() 返回一个数组数组,所以第一行必须是 var polyPoints = poly.getLatLngs()[0]; 如果你想支持甜甜圈形状的多边形,你需要另一个包装循环。【参考方案2】:

这是对我有用的@gusper 答案的修改版(带有@Sumit 提示):(我有甜甜圈)

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;
;

【讨论】:

【参考方案3】:

我发现上述答案都不适用于计算非连续多边形内的标记。这是一个示例多边形,其中上述函数在内部返回 0 个标记:

对于任何需要这样做的人,Leaflet.PointInPolygon 包对我有用:https://github.com/hayeswise/Leaflet.PointInPolygon

速度有点慢,但似乎准确。

【讨论】:

以上是关于确定一个点是不是位于传单多边形内的主要内容,如果未能解决你的问题,请参考以下文章

如何确定一个点是不是在二维凸多边形内?

如何在 N 时间内确定一个点是不是在 2D 凸多边形内

确定点是不是在多边形内

是否可以使用 JavaScript 确定 GeoJSON 点是否在 GeoJSON 多边形内?

已知一个多边形的所有顶点坐标,如果确定一点是不是在这个多边形内?

从空间点数据创建边界多边形,以便在传单中绘图