Überprüfen Sie mithilfe von Google Maps, ob sich der Lat / Long-Punkt innerhalb einer Reihe von Polygonen befindet

9

Ich weiß, wie man das oben mit Esri (Abfrageaufgabe für Shapefile) macht, aber kann dies auch mit Google Maps gemacht werden? Muss ich jedes Polygon abfragen oder gibt es eine Methode, um eine Reihe von Polygonen abzufragen?

ngramsky
quelle

Antworten:

9

Die Google Maps-API bietet noch keine Methode zum Überprüfen von Punkten in Polygonen. Nachdem ich ein wenig recherchiert hatte, stieß ich auf den Ray-Casting-Algorithmus, der bestimmt, ob sich eine XY-Koordinate innerhalb einer gezeichneten Form befindet. Dies führt zu Längen- und Breitengraden. Im Folgenden wird der google.maps.polygon.prototype erweitert, um diesen Algorithmus zu verwenden. Fügen Sie diesen Code einfach an einer Stelle im Code ein, nachdem google.maps geladen wurde:

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

    }

};

Hier haben wir die Funktionalität von google.maps.Polygon erweitert, indem wir eine Funktion mit dem Namen 'Enthält' definiert haben, mit der bestimmt werden kann, ob der im Funktionsparameter angegebene Längengrad innerhalb des Polygons liegt oder nicht. Hier verwenden wir den Ray-Casting-Algorithmus und entwickeln eine Funktion, die diesen verwendet. Nachdem wir jetzt so viel trainiert haben, können wir einen Punkt wie folgt überprüfen:

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
}

Den vollständigen Code und die Demo finden Sie unter: http://counsellingbyabhi.blogspot.in/2013/01/google-map-check-whether-point-latlong.html

Techabhi
quelle
Ja, Ray Casting ist der richtige Weg, denke ich. Ich habe diesen Algorithmus tatsächlich selbst über ein Python-Skript verwendet. Meine Implementierung finden Sie hier: gramsky.blogspot.com/2012/12/…
ngramsky
Ich musste die Bits entfernen, die 360 ​​zu negativen Koordinaten hinzufügten, damit dies um Längengrad 0 richtig funktioniert.
user1431317
4

Ich würde das Open Layers Plugin verwenden. Wenn Sie es abrufen, können Sie Ihrer Karte sogar einen beliebigen dynamischen Layer hinzufügen und exportieren.

* Bevor Sie dies tun, stellen Sie sicher, dass Ihr Projekt-CRS (EPSG) auf WGS84 eingestellt ist und dass die CRS-Umwandlung "on the fly" unter den Einstellungen für Projekteigenschaften aktiviert ist.

Hoffe das hilft.

Bryce Touchstone
quelle
0

Wenn Sie ein Programm eines Drittanbieters als Geodjango verwenden, können Sie Ihren Punkt überprüfen, ob innerhalb einer Reihe von Polygonen oder nicht. Weitere Infos gibt es hier .

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)

ich hoffe es hilft dir ...

Aragon
quelle
0

Ich weiß, dass dies etwas spät ist, aber es könnte hilfreich sein, falls SomeOne die Android-Map-Utils-Bibliothek nicht ausprobiert hat. Ich habe die spezifischen Methoden dieser Frage nur für Android veröffentlicht. Bitte schön:

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

Sagar Shah
quelle