Vérifiez si le point lat / long se trouve dans un ensemble de polygones à l'aide de Google Maps

9

Je sais comment faire ce qui précède en utilisant Esri (tâche de requête sur le fichier de formes), mais cela peut-il également être fait en utilisant Google Maps? Dois-je interroger chaque polygone ou existe-t-il une méthode pour interroger un ensemble de polygones?

ngramsky
la source

Réponses:

9

L'API Google maps ne fournit pas déjà de méthode pour vérifier les points dans les polygones. Après quelques recherches, je suis tombé sur l'algorithme de lancer de rayons qui déterminera si une coordonnée XY est à l'intérieur d'une forme tracée. Cela se traduira par la latitude et la longitude. Ce qui suit étend le google.maps.polygon.prototype pour utiliser cet algorithme. Incluez simplement ce code à un point du code après le chargement de 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);

    }

};

Ici, nous avons étendu les fonctionnalités de google.maps.Polygon en définissant une fonction avec le nom «Contient» qui peut être utilisée pour déterminer si la longitude de latitude fournie dans le paramètre de fonction se trouve dans le polygone ou non. Ici, nous utilisons l'algorithme de lancer de rayons et avons développé une fonction l'utilisant. Après avoir fait autant d'exercices maintenant, nous pouvons vérifier un point comme suit:

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 inside polygon
}

Pour le code complet et la démo, rendez-vous sur: http://counsellingbyabhi.blogspot.in/2013/01/google-map-check-whether-point-latlong.html

techabhi
la source
Oui, je pense que le lancer de rayons est la voie à suivre. J'ai moi-même utilisé cet algorithme via un script python. Mon implémentation peut être trouvée ici: grammesky.blogspot.com/2012/12/…
ngramsky
J'ai dû supprimer les bits qui ont ajouté 360 aux coordonnées négatives pour que cela fonctionne correctement autour de la longitude 0.
user1431317
4

J'irais le plugin Open Layers; le récupérer, et vous pouvez même ajouter n'importe quelle couche dynamique à votre carte et l'exporter.

* Avant de le faire, assurez-vous que votre CRS de projet (EPSG) est défini sur WGS84 et que la transformation CRS «à la volée» est activée dans les paramètres de vos propriétés de projet.

J'espère que cela t'aides.

Bryce Touchstone
la source
0

si vous utilisez un programme tiers comme geodjango, vous pouvez vérifier votre point que ce soit dans un ensemble de polygones ou non. plus d'informations sont ici .

contains

Availability: PostGIS, Oracle, MySQL, SpatiaLite

Tests if the geometry field spatially contains the lookup geometry.

Example:

Zipcode.objects.filter(poly__contains=geom)

Backend     SQL Equivalent
PostGIS     ST_Contains(poly, geom)
Oracle  SDO_CONTAINS(poly, geom)
MySQL   MBRContains(poly, geom)
SpatiaLite  Contains(poly, geom)

J'espère que ça t'aide...

Aragon
la source
0

Je sais que c'est un peu tard, mais cela pourrait être utile au cas où SomeOne n'aurait pas essayé la bibliothèque Android-Map-Utils. J'ai publié les méthodes spécifiques à cette question uniquement pour Android. Voici:

https://stackoverflow.com/a/31988461/2054348

Sagar Shah
la source