Google Maps v3: comprobar si el punto existe en polígono


Estoy buscando una manera de comprobar si existe un punto dentro de un polígono en Google Maps v3 (JavaScript). He buscado por todas partes y las únicas soluciones que he encontrado hasta ahora han sido hacer con obtener los límites del polígono, pero el código que se muestra parece crear un rectángulo y sigue expandiendo su área de superficie para incluir todos los puntos relevantes.

Por cierto, la razón por la que no puedo usar un cuadrado grande, es decir, obtener un polígonos límites, es que tengo polígonos limítrofes en el mapa y no pueden expandirse en el territorio del otro.

EDITAR Siguiendo con la respuesta a continuación, he intentado implementar el código de ejemplo utilizando uno de mis polígonos existentes, pero solo está diciendo que no está definido y no puedo averiguar por qué.

Aquí está mi declaración:

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

Y aquí es donde estoy comprobando el punto:

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

Pero sigue apareciendo el error: Uncaught ReferenceError: rightShoulderFront no está definido

Author: halfer, 2011-06-29

7 answers

Un algoritmo para resolver esto es ray-casting. Ver una explicación aquí.

Y puede encontrar el código que implementa esto para la API JS V3 de Google Maps aquí.

HTH.

 37
Author: mhyfritz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-29 14:43:26

Puede hacer esto simplemente con la biblioteca de geometría de Google maps.

Primero asegúrese de agregar la biblioteca de geometría de Google Maps.

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

Luego, defina su polígono

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

Voy a agregar un receptor de eventos para manejar un evento 'click', pero puedes adaptarte a tus necesidades

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

Crear una función para manejar nuestro evento de clic un comprobar si la coordenada existe dentro del polígono utilizando la biblioteca de geometría de Google

/** @this {google.maps.Polygon} */
function isWithinPoly(event){
   var isWithinPolygon = google.maps.geometry.poly.containsLocation(event.latLng, this);
    console.log(isWithinPolygon);
}
 19
Author: Kyle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-21 16:53:37

Tienes un muy buen ejemplo del método containsLocation() en la documentación de la API de Google Maps.

 7
Author: Damjan Pavlica,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 09:27:29

Deberías echar un vistazo a los Gmaps.biblioteca js. Tiene un método bastante simple sobre la geocerca.

 5
Author: vtproduction,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-13 08:18:29

El ejemplo y la implementación no tienen en cuenta que un polígono puede cruzar el límite de 180 grados.

La implementación lo tiene en cuenta (implícitamente) en la casilla de verificación, pero la verificación de polígonos falla.

 3
Author: rikkertkoppes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-25 13:51:43
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);

No olvide incluir la biblioteca en su script googleapis. Leer más...

<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry"></script>
 1
Author: Bruce Phillip Perez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-26 05:27:15

He usado lo mismo y funcionando bien y su código offline He escrito este código en PHP puedes escribirlo en cualquier lenguaje de programación.

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>";
}

?>

 1
Author: vinod gami,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-04 11:10:13