代码之家  ›  专栏  ›  技术社区  ›  Natim

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

  •  12
  • Natim  · 技术社区  · 14 年前

    我想检测一下 google.maps.LatLng 在里面 google.maps.Polygon .

    我该怎么做?

    干杯,

    6 回复  |  直到 8 年前
        1
  •  11
  •   gnat Nat Poor    8 年前

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

    一个javascript google为polygon类映射v3扩展,以检测一个点是否在其中…

        2
  •  22
  •   Adi Lester    12 年前

    你可以用这个 谷歌地图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

        3
  •  5
  •   Paul Gibbs    12 年前

    谷歌在几何学库中提供了自己的实现,我还没有检查过,但可能涵盖了其他答案中讨论的边缘案例。

    见包含位置法 described here . 注意你必须 import the geometry library explicitly, as it is not in the base map API

        4
  •  4
  •   Natim    14 年前

    我使用此算法检测点在多边形内: 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;
    
        5
  •  2
  •   deAtog    12 年前

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

    安德烈一世和纳蒂姆给出的方法 考虑具有测地线边缘的多边形。这些方法也没有意识到谷歌地图中的非测地线边缘只是墨卡托投影中的直线。这些方法假设顶点位于等距离纬度/经度网格上,其中一个纬度等于一个经度。由于这个错误,这些方法将指示一个点在多边形外部,而在某些情况下显示在多边形内部。这对于长的非垂直/非水平边缘很容易观察到。 为了解决这个问题,所有的点必须首先在墨卡托投影从纬度,经度到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实现了这种方法。

    保罗·吉布斯、斯瓦普尼尔·乌达尔和阿迪·莱斯特提到的方法 考虑测地线边缘,但从Google Maps v3.9开始,它对非测地线多边形使用上面提到的相同方法。因此,它也受到上述相同问题的困扰。

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

        6
  •  2
  •   love kumar    10 年前

    不需要复杂的算法,我可以使用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;
    }