2011-06-29 104 views
27

我期待找到一种方法来检查一个点是否存在于Google Maps v3(JavaScript)的多边形内。我到处搜索过,到目前为止我发现的唯一解决方案是获取多边形的边界,但所显示的代码似乎只是创建一个矩形并不断扩大其表面积以包含所有相关点。谷歌地图v3:检查点是否存在于多边形

顺便说一句,我不能只使用一个大方块即得到一个多边形边界的原因是,我在地图上有边界多边形,他们不能扩展到对方的领土。

编辑 继续从下面的回复中,我尝试使用我的现有多边形之一实现示例代码,但它只是说它没有被定义,我不知道为什么。

这里是我的声明:

myCoordinates = [ 
    new google.maps.LatLng(0.457301,-0.597382), 
    new google.maps.LatLng(0.475153,-0.569916), 
    new google.maps.LatLng(0.494379,-0.563049), 
    new google.maps.LatLng(0.506738,-0.553436), 
    new google.maps.LatLng(0.520470,-0.541077), 
    new google.maps.LatLng(0.531456,-0.536957), 
    new google.maps.LatLng(0.556174,-0.552063), 
    new google.maps.LatLng(0.536949,-0.596008), 
    new google.maps.LatLng(0.503991,-0.612488), 
    new google.maps.LatLng(0.473780,-0.612488) ]; 

polyOptions = { 
    path: myCoordinates, 
    strokeColor: "#FF0000", 
    strokeOpacity: 0.8, 
    strokeWeight: 2, 
    fillColor: "#0000FF", 
    fillOpacity: 0.6 }; 

var rightShoulderFront = new google.maps.Polygon(polyOptions); 
rightShoulderFront.setMap(map); 

和这里就是我检查了这一点:

var coordinate = selectedmarker.getPosition(); 
var isWithinPolygon = rightShoulderFront.containsLatLng(coordinate); 
console.log(isWithinPolygon); 

但它一直想出错误:未捕获的ReferenceError:未定义rightShoulderFront

回答

36

解决这个问题的一种算法是光线投射。请参阅说明here

而且您可以在Google Maps JS API V3 here中找到实现此功能的代码。

HTH。

3

该示例和实现没有考虑到多边形可以穿过180度边界。

该实现在边界框检查中将其考虑在内(隐式地),但多边形检查失败。

19

你可以用Google地图几何库很简单地做到这一点。

首先一定要添加谷歌地图几何库。

<script type="text/javascript" src="//maps.googleapis.com/maps/api/js?libraries=geometry&sensor=false"></script> 

然后,定义多边形

var rightShoulderFront = new google.maps.Polygon({ 
      paths: myCoordinates 
     }); 
rightShoulderFront .setMap(map); 

我要添加一个事件监听器来处理一个“click”事件,但可以适应满足您的需求

google.maps.event.addListener(rightShoulderFront , 'click', isWithinPoly); 

使用Google的几何库创建一个函数来处理我们的点击事件并检查多边形内是否存在坐标

/** @this {google.maps.Polygon} */ 
function isWithinPoly(event){ 
    var isWithinPolygon = google.maps.geometry.poly.containsLocation(event.latLng, this); 
    console.log(isWithinPolygon); 
} 
+2

是否有关于这种方法的使用提出由谷歌的任何限制, 'containsLocation()'? –

7

在Google Maps API文档中,您有一个非常好的examplecontainsLocation()方法。

1
var coordinate = new google.maps.LatLng(0.457301,-0.597382);//replace with your lat and lng values 
var isWithinPolygon = google.maps.geometry.poly.containsLocation(coordinate, yourPolygon); 

不要忘了将库包含在您的googleapis脚本中。Read more...

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script> 
0

我用我写了这个代码在PHP,你可以把它写任何编程语言同样的事情,做工精细和离线码。

class pointLocation { 
    var $pointOnVertex = true; // Check if the point sits exactly on one of the vertices? 

    function pointLocation() { 
    } 

    function pointInPolygon($point, $polygon, $pointOnVertex = true) { 
     $this->pointOnVertex = $pointOnVertex; 

     // Transform string coordinates into arrays with x and y values 
     $point = $this->pointStringToCoordinates($point); 
     $vertices = array(); 
     foreach ($polygon as $vertex) { 
      $vertices[] = $this->pointStringToCoordinates($vertex); 
     } 

     // Check if the point sits exactly on a vertex 
     if ($this->pointOnVertex == true and $this->pointOnVertex($point, $vertices) == true) { 
      return "vertex"; 
     } 

     // Check if the point is inside the polygon or on the boundary 
     $intersections = 0; 
     $vertices_count = count($vertices); 

     for ($i=1; $i < $vertices_count; $i++) { 
      $vertex1 = $vertices[$i-1]; 
      $vertex2 = $vertices[$i]; 
      if ($vertex1['y'] == $vertex2['y'] and $vertex1['y'] == $point['y'] and $point['x'] > min($vertex1['x'], $vertex2['x']) and $point['x'] < max($vertex1['x'], $vertex2['x'])) { // Check if point is on an horizontal polygon boundary 
       return "boundary"; 
      } 
      if ($point['y'] > min($vertex1['y'], $vertex2['y']) and $point['y'] <= max($vertex1['y'], $vertex2['y']) and $point['x'] <= max($vertex1['x'], $vertex2['x']) and $vertex1['y'] != $vertex2['y']) { 
       $xinters = ($point['y'] - $vertex1['y']) * ($vertex2['x'] - $vertex1['x'])/($vertex2['y'] - $vertex1['y']) + $vertex1['x']; 
       if ($xinters == $point['x']) { // Check if point is on the polygon boundary (other than horizontal) 
        return "boundary"; 
       } 
       if ($vertex1['x'] == $vertex2['x'] || $point['x'] <= $xinters) { 
        $intersections++; 
       } 
      } 
     } 
     // If the number of edges we passed through is odd, then it's in the polygon. 
     if ($intersections % 2 != 0) { 
      return "inside"; 
     } else { 
      return "outside"; 
     } 
    } 

    function pointOnVertex($point, $vertices) { 
     foreach($vertices as $vertex) { 
      if ($point == $vertex) { 
       return true; 
      } 
     } 

    } 

    function pointStringToCoordinates($pointString) { 
     $coordinates = explode(" ", $pointString); 
     return array("x" => $coordinates[0], "y" => $coordinates[1]); 
    } 

} 

$pointLocation = new pointLocation(); 
$points = array("22.732965336387213 75.8609390258789"); 
$polygon = array("22.73549852921309 75.85424423217773","22.72346544538196 75.85561752319336","22.72346544538196 75.87175369262695","22.732332030848273 75.87295532226562","22.740406456758326 75.8686637878418","22.74198962160603 75.85407257080078"); 
echo '<pre>'; 
print_r($polygon); 
// The last point's coordinates must be the same as the first one's, to "close the loop" 
foreach($points as $key => $point) { 
    echo "point " . ($key+1) . " ($point): " . $pointLocation->pointInPolygon($point, $polygon) . "<br>"; 
} 

?>