如何使用Google Maps检测点是否在多边形内?

13
我希望检测一个 google.maps.LatLng 是否在一个 google.maps.Polygon 内。如何实现呢?谢谢!
6个回答

22

您可以在Google地图 V3中使用以下方式:

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

多边形是一个由函数返回的对象,该函数在多边形完成后被调用。

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

引用自https://developers.google.com/maps/documentation/javascript/reference


11

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

这是一个用于Polygon类的Javascript Google Maps v3扩展,用于检测点是否在其内部...


由于某种奇怪的原因,这个方法可以工作,但我从未能够让谷歌的containsLocation()函数正常工作...... - WildBill
@WildBill - 你需要使用几何库才能让它正常工作。 示例:?sensor=false&libraries=drawing,geometry - jjwdesign
我已经从Google添加了几何库,但它对我仍然无效。 - AllJs

5

4

我使用这个算法来检测点是否在多边形内:http://alienryderflex.com/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(); - Marios Fakiolas

2

无需复杂算法,我使用html画布的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;
}

海报在询问Google地图上的多边形。并非所有浏览器都支持画布,上述方法假定标准的X、Y网格。如果在画布上绘制,则上述方法是完美的,否则就是浪费的。上面提到的其他方法可以在不需要在画布上绘制的情况下计算出这个问题。截至Google地图v3.10,最佳方法是google.maps.geometry.poly.containsLocation(),因为它可以处理大圆多边形和墨卡托多边形。 - deAtog
我同意。虽然它并没有完全回答这个问题,但对于那些在html5环境中工作并最终进入此帖子以检测多边形点的人可能会有所帮助。我来到这篇文章并尝试实现所有算法,但没有一种方法能够完美地工作。我基本上使用画布在楼层平面图上实现了自定义地图。我必须在图像的不同部分显示工具提示,并模仿html图像映射功能。 - love kumar

2
这里提到的每种方法都有其失败之处。
Andrei I和Natim提供的方法没有考虑到具有测地线边缘的多边形。这些方法还未意识到Google Maps中的非测地线边缘仅在Mercator投影中是直线。这些方法假定顶点位于等距离纬度/经度网格上,其中一度纬度等于一度经度。由于这个错误,这些方法将指示某些情况下的一个点在多边形外部,但在内部显示。长非垂直/非水平边缘很容易观察到这一点。为了解决这个问题,所有点必须首先从纬度、经度转换为Mercator投影中的X、Y坐标。这是将坐标从lat/lon转换为Mercator中x/y的方法。(缺乏准确性)航向线导航可用作替代方法的基础。 Google Maps实验版本3.10实现了这种方法。
Paul Gibbs、swapnil udare和Adi Lester提到的方法考虑了测地线边缘,但在Google Maps v3.9中,它使用了上述非测地线多边形的相同方法。因此,它也受到上述相同问题的影响。 更新 - Google Maps的问题已在当前实验版本的Google Maps v3.10中得到纠正。

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