web-dev-qa-db-fra.com

Google Maps v3: vérifier si le point existe dans le polygone

Je cherche un moyen de vérifier si un point existe à l'intérieur d'un polygone dans Google Maps v3 (JavaScript). J'ai cherché partout et les seules solutions que j'ai trouvées jusqu'à présent ont consisté à obtenir les limites du polygone, mais le code affiché semble simplement créer un rectangle et continue d'étendre sa surface pour inclure tous les points pertinents.

Soit dit en passant, la raison pour laquelle je ne peux pas simplement utiliser un grand carré, c'est-à-dire obtenir des limites de polygones, est que j'ai des polygones limitrophes sur la carte et qu'ils ne peuvent pas s'étendre sur le territoire de l'autre.

EDIT Dans le prolongement de la réponse ci-dessous, j'ai essayé d'implémenter l'exemple de code en utilisant l'un de mes polygones existants, mais il dit simplement qu'il n'est pas défini et je ne peux pas comprendre pourquoi.

Voici ma déclaration:

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

et voici où je vérifie le point:

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

Mais il continue de produire l'erreur: Uncaught ReferenceError: rightShoulderFront n'est pas défini

29
Bob-ob

Un algorithme pour résoudre ce problème est le lancer de rayons. Voir une explication ici .

Et vous pouvez trouver du code implémentant cela pour l'API Google Maps JS V3 ici .

HTH.

39
mhyfritz

Vous pouvez le faire tout simplement avec la bibliothèque de géométrie de Google maps.

Assurez-vous d'abord d'ajouter la bibliothèque de géométrie google maps.

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

Ensuite, définissez votre polygone

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

Je vais ajouter un écouteur d'événement pour gérer un événement de "clic", mais vous pouvez vous adapter à vos besoins

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

Créez une fonction pour gérer notre événement de clic et vérifiez si des coordonnées existent dans le polygone à l'aide de la bibliothèque de géométrie de Google

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

Vous disposez d'une très bonne méthode exemple of containsLocation() dans la documentation de l'API Google Maps.

8
Damjan Pavlica

Vous devriez jeter un œil à la bibliothèque Gmaps.js . Il a une méthode assez simple sur le geofence.

5
vtproduction

L'exemple et la mise en œuvre ne tiennent pas compte du fait qu'un polygone peut traverser la limite de 180 degrés.

L'implémentation en tient compte (implicitement) dans la case à cocher englobante, mais la vérification du polygone échoue.

3
rikkertkoppes

J'ai utilisé la même chose et fonctionne bien et son code hors ligne J'ai écrit ce code en PHP vous pouvez l'écrire dans n'importe quel langage de programmation.

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

N'oubliez pas d'inclure la bibliothèque dans votre script googleapis. En savoir plus ...

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