Google Maps v3:检查点是不是存在于多边形中

Posted

技术标签:

【中文标题】Google Maps v3:检查点是不是存在于多边形中【英文标题】:Google Maps v3: check if point exists in polygonGoogle Maps v3:检查点是否存在于多边形中 【发布时间】:2011-09-25 05:37:56 【问题描述】:

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

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

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

这是我的声明:

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);

但它不断出现错误:Uncaught ReferenceError: rightShoulderFront is not defined

【问题讨论】:

【参考方案1】:

我用过同样的东西,工作正常,它的离线代码我用 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>";

?>

【讨论】:

【参考方案2】:
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>

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

您应该了解一下Gmaps.js 库。它有一个非常简单的地理围栏方法。

【讨论】:

Gmaps.js 很棒 ;)【参考方案5】:

您可以使用 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);

我将添加一个事件侦听器来处理“点击”事件,但您可以根据自己的需要进行调整

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);

【讨论】:

Google 对使用此方法 'containsLocation()' 是否有任何限制?【参考方案6】:

示例和实现没有考虑多边形可以跨越 180 度边界。

实现确实在边界框检查中(隐式)考虑到它,但多边形检查失败。

【讨论】:

【参考方案7】:

解决此问题的一种算法是光线投射。见解释here。

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

HTH。

【讨论】:

你有运行代码吗?也许是codepen或jsfiddle?谢谢。

以上是关于Google Maps v3:检查点是不是存在于多边形中的主要内容,如果未能解决你的问题,请参考以下文章

如何检查是不是已加载 Google Maps API?

如何知道用户是不是更改缩放(Google Maps V3)

v3 Google Maps Geocoding API 是不是有代表准确性的字段?

如何使用 Google Maps API v3 突出显示地址?

使用 Google Maps API V3,确定标记是不是在 KML 图层边界内

获取 Google Maps v3 以调整 InfoWindow 的高度