如何使用谷歌地图检测一个点在多边形内?

Posted

技术标签:

【中文标题】如何使用谷歌地图检测一个点在多边形内?【英文标题】:How to detect that a point is inside a Polygon using Google Maps? 【发布时间】:2011-03-03 11:01:29 【问题描述】:

我想检测google.maps.LatLnggoogle.maps.Polygon 内。

我该怎么做?

干杯,

【问题讨论】:

【参考方案1】:

您可以在 google map V3 中使用它:-

google.maps.geometry.poly.containsLocation(google.maps.LatLng(latitude, longitude),polygons);

polygons 是 polygoncomplete 之后函数返回的对象。

var polygons=null;
google.maps.event.addDomListener(drawingManager, "polygoncomplete", function(polygon) 
        polygons=polygon;
);

https://developers.google.com/maps/documentation/javascript/reference参考

【讨论】:

【参考方案2】:

其他解决方案:Google-Maps-Point-in-Polygon

Polygon 类的 Javascript Google Maps v3 扩展,用于检测点是否位于其中...

【讨论】:

出于某种奇怪的原因,这可行,但我无法让 Google 的 containsLocation() 函数正常工作..... @WildBill - 你需要几何库才能让它工作。示例:?sensor=false&libraries=drawing,geometry 我从 Google 添加了几何库,但它仍然不适合我【参考方案3】:

Google 在几何库中提供了他们自己的实现,我没有检查过,但大概涵盖了其他答案中讨论的边缘情况。

参见 containsLocation 方法described here。请注意,您必须import the geometry library explicitly, as it is not in the base map API

【讨论】:

【参考方案4】:

我使用这个算法来检测点在多边形内:http://alienryderflex.com/polygon/

我在 Polygon 中添加了一个新方法 contains

// Add a function contains(point) to the Google Maps API v.3

google.maps.Polygon.prototype.contains = function(point) 
  var j=0;
  var oddNodes = false;
  var x = point.lng();
  var y = point.lat();

  var paths = this.getPath();

  for (var i=0; i < paths.getLength(); i++) 
    j++;
    if (j == paths.getLength()) j = 0;
    if (((paths.getAt(i).lat() < y) && (paths.getAt(j).lat() >= y))
    || ((paths.getAt(j).lat() < y) && (paths.getAt(i).lat() >= y))) 
      if ( paths.getAt(i).lng() + (y - paths.getAt(i).lat())
      /  (paths.getAt(j).lat()-paths.getAt(i).lat())
      *  (paths.getAt(j).lng() - paths.getAt(i).lng())<x ) 
        oddNodes = !oddNodes
      
    
  
  return oddNodes;


google.maps.Polyline.prototype.contains = google.maps.Polygon.prototype.contains;

【讨论】:

非常好,它工作。只需更改 var x = point.getPosition().lng();var y = point.getPosition().lat();【参考方案5】:

这里描述的每个方法都以某种方式失败。

Andrei I 和 Natim 给出的方法考虑具有测地线边缘的多边形。这些方法也没有意识到谷歌地图中的非测地线边缘仅在墨卡托投影内是直线的。这些方法假设顶点位于等距离的纬度/经度网格上,其中一度纬度等于一度经度。由于此错误,这些方法将指示一个点位于多边形外部,而在某些情况下显示在多边形内部。对于长的非垂直/非水平边缘,这很容易观察到。 要解决这个问题,必须首先将所有点从纬度、经度转换为墨卡托投影中的 X、Y 坐标。 Here is the method to convert the coordinates from lat/lon to x/y in Mercator.(缺乏准确性)Rhumb line navigation can be used as a basis for an alternative method.谷歌地图实验版3.10实现了这个方法。

Paul Gibbs、swapnil udare 和 Adi Lester 提到的方法确实考虑了测地线边缘,但从 Google Maps v3.9 开始,它使用上述相同的方法对于非测地线多边形。因此,它也遭受上述相同的问题。

更新 - 谷歌地图的问题已在谷歌地图 v3.10 的当前实验版本中得到纠正。

【讨论】:

【参考方案6】:

不需要复杂的算法,我可以使用 html canvas 的 isPointInPath() 方法来实现。

http://www.w3schools.com/tags/canvas_ispointinpath.asp

创建一个画布元素。 使用 moveTo(),lineTo() 方法绘制具有多个端点的多边形。 使用 isPointInPath() 方法验证点(x,y) 是否位于多边形内。

<canvas id="canvas"></canvas>

//x,y are coordinate of the point that needs to be tested
//coordinates contains all endpoint of a polygon in format of x1,y1,x2,y2,x3,y3....
function isPointInPolygon(x, y, coordinates) 
var ctx = canvas.getContext("2d");
var coords = coordinates.split(',');

if (coords != null && coords.length > 4) 
    ctx.beginPath();
    ctx.moveTo(coords[0], coords[1]);
    for (j = 2; j < coords.length; j++) 
        ctx.lineTo(coords[j], coords[j + 1]);
        j++;
    
    ctx.closePath();
    if (ctx.isPointInPath(x, y))
        return true;
    else
        return false;

return false;

【讨论】:

发帖者在谷歌地图上询问多边形。并非所有浏览器都支持画布,并且上述方法假定标准 X、Y 网格。如果在画布上绘图,上述方法是完美的,否则只是浪费。上面提到的其他方法可以计算这一点,而无需在画布上绘图。从 Google maps v3.10 开始,最好的方法是 google.maps.geometry.poly.containsLocation(),因为它可以处理测地线多边形和墨卡托多边形。 我同意。它并不能完全回答这个问题,但可以帮助在 html5 环境中工作并最终在这篇文章中检测多边形中的点的人。我来到这篇文章并尝试实现所有算法,但没有一个能完美运行。我基本上使用画布在平面图图像上实现了自定义地图。我必须在图像的不同部分显示工具提示并模仿 html 图像映射功能。

以上是关于如何使用谷歌地图检测一个点在多边形内?的主要内容,如果未能解决你的问题,请参考以下文章

如何判断一个点在多边形内

谷歌地图颤动检查多边形内的点

获取位于谷歌地图多边形内的所有点

如何使用坐标数组在谷歌地图 API 中绘制多边形?

如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域

如何判断点在一个区域内?用户绘制区域(射线法)判断点在多边形区域,报警区域