检查点是否在多边形(地图)

时间:2012-01-30 15:51:34

标签: google-maps coordinates bing-maps point

我正在尝试检查点是否为多边形。
目前我尝试使用此功能

pointInPolygon:function (point,polygon){
    var i;
    var j=polygon.length-1;
    var inPoly=false;
    var lon = point.longitude;
    var lat = point.latitude;
    for (i=0; i<polygon.length; i++)
    {
        if (polygon[i][0]<lon && polygon[j][0]>=lon|| polygon[j][0]<lon && polygon[i][0]>=lon){
            if (polygon[i][0]+(lon-polygon[i][0])/(polygon[j][0]-polygon[i][0])*(polygon[j][1]-polygon[i][1])<lat){
                inPoly=!inPoly;
            }
        }
        j=i;
    }
    return inPoly;
}

...这个函数似乎适用于简单的多边形(http://jsfiddle.net/zTmr7/3/),但它对我不起作用...... 这是多边形的样本数据:

polygon: Array[14]
Array[2]
        0: "-120.190625"
        1: "29.6614549946937"
Array[2]
        0: "-116.87275390625"
        1: "32.6320990313992"
Array[2]
        0: "-116.60908203125"
        1: "34.0363970332393"
Array[2]
        0: "-120.89375"
        1: "41.9203747676428"
Array[2]
        0: "-114.74140625"
        1: "45.784484644005"
Array[2]
        0: "-115.971875"
        1: "48.6489780115889"
Array[2]
        0: "-132.758984375"
        1: "59.9891712248332"
Array[2]
        0: "-162.5099609375"
        1: "68.919753529737"
Array[2]
        0: "-168.6623046875"
        1: "68.9828872543805"
Array[2]
        0: "-168.4865234375"
        1: "64.2551601036027"
Array[2]
        0: "-179.874356794357"
        1: "51.0915874974707"
Array[2]
        0: "-179.999916362762"
        1: "13.1823178795562"
Array[2]
        0: "-143.8771484375"
        1: "19.9962034117847"
Array[2]
        0: "-120.190625"
        1: "29.6614549946937"  

也许你可以提前帮助

PS。解决方案必须特别适用于Bing地图或通用解决方案...

4 个答案:

答案 0 :(得分:3)

Google Maps API尚未提供检查多边形中的点的方法。在研究了一下之后,我偶然发现了光线投射算法,该算法将确定X-Y坐标是否在绘制的形状内。这将转换为纬度和经度。以下内容扩展了google.maps.polygon.prototype以使用此算法。只需在google.maps加载后的代码中包含此代码:

google.maps.Polygon.prototype.Contains = function(point) {
  var crossings = 0, path = this.getPath();

  // for each edge
  for (var i=0; i < path.getLength(); i++) {
      var a = path.getAt(i),
          j = i + 1;
      if (j >= path.getLength()) {
          j = 0;
      }
      var b = path.getAt(j);
      if (rayCrossesSegment(point, a, b)) {
        crossings++;
      }
  }

  // odd number of crossings?
  return (crossings % 2 == 1);

  function rayCrossesSegment(point, a, b) {
    var px = point.lng(),
        py = point.lat(),
        ax = a.lng(),
        ay = a.lat(),
        bx = b.lng(),
        by = b.lat();
    if (ay > by) {
        ax = b.lng();
        ay = b.lat();
        bx = a.lng();
        by = a.lat();
    }
    // alter longitude to cater for 180 degree crossings
    if (px < 0) { px += 360 };
    if (ax < 0) { ax += 360 };
    if (bx < 0) { bx += 360 };

    if (py == ay || py == by) py += 0.00000001;
    if ((py > by || py < ay) || (px > Math.max(ax, bx))) return false;
    if (px < Math.min(ax, bx)) return true;

    var red = (ax != bx) ? ((by - ay) / (bx - ax)) : Infinity;
    var blue = (ax != px) ? ((py - ay) / (px - ax)) : Infinity;
    return (blue >= red);
  }
};

这里我们通过定义名为'Contains'的函数扩展了google.maps.Polygon的功能,该函数可用于确定函数参数中提供的纬度经度是否在多边形内。这里我们利用Ray-casting算法并开发了一个使用相同的函数。在做了这么多练习之后,我们可以检查一下如下:

var point = new google.maps.LatLng(52.05249047600099,-0.6097412109375); var polygon = new google.maps.Polygon({path:[INSERT_PATH_ARRAY_HERE]}); if(polygon.Contains(point)){// point is polygon}}

有关完整的代码和演示,请访问:http://counsellingbyabhi.blogspot.in/2013/01/google-map-check-whether-point-latlong.html

答案 1 :(得分:1)

第一个if语句看起来很好 - 你要检查点的经度是否在多边形段的经度范围内。

第二个if应该用该点的精确经度插值段的截距,并确定该截距是高于还是低于该点。由于一个简单的拼写错误,我认为这不是它正在做的事情。

if (polygon[i][1]+(lon-polygon[i][0])/(polygon[j][0]-polygon[i][0])*(polygon[j][1]-polygon[i][1])<lat){
               ^

您还应该在polygon[i][0]==polygon[j][0]时添加一个单独的案例,这样就不会出现被零除错误。

答案 2 :(得分:0)

您可以使用我在github中镜像的libkml变体的克隆:https://github.com/gumdal/libkml-pointinpolygon

在此开源作者的帮助下,设计了一个模块,用于指示给定点是否在KML多边形内。确保检查分支“libkml-git”而不是git源的“master”分支。您感兴趣的课程是“pointinpolygon.cc”。它是C ++源代码,您可以将其包含在项目中,并与项目一起构建。

编辑 - 多边形点问题的解决方案与其重叠的地图无关。

答案 3 :(得分:0)

true | false = google.maps.geometry.poly.containsLocation(googlePoint,googlePoly);