Sprawdź, czy długość / szerokość punktu znajduje się w zbiorze wielokątów za pomocą map Google

9

Wiem, jak to zrobić za pomocą Esri (zadanie zapytania na pliku kształtu), ale czy można to również zrobić za pomocą Google Maps? Czy muszę przesyłać zapytania do każdego wielokąta, czy też istnieje jedna metoda zapytania zestawu wielokątów?

ngramsky
źródło

Odpowiedzi:

9

Interfejs API map Google nie zapewnia jeszcze metody sprawdzania punktów w wielokątach. Po dokładnym zbadaniu natknąłem się na algorytm rzucania promieni, który określi, czy współrzędna XY znajduje się w narysowanym kształcie. To przełoży się na szerokość i długość geograficzną. Poniżej rozszerza google.maps.polygon.prototype do korzystania z tego algorytmu. Po prostu dołącz ten kod w jednym punkcie kodu po załadowaniu 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);

    }

};

Tutaj rozszerzyliśmy funkcjonalność google.maps.Polygon, definiując funkcję o nazwie „Zawiera”, której można użyć do ustalenia, czy długość geograficzna podana w parametrze funkcji mieści się w wielokącie, czy nie. Korzystamy z algorytmu odlewania promieniami i opracowaliśmy funkcję przy użyciu tego samego. Po wykonaniu tak dużej ilości ćwiczeń możemy teraz sprawdzić punkt w następujący sposób:

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
}

Pełny kod i wersję demo można znaleźć na stronie : http://counsellingbyabhi.blogspot.in/2013/01/google-map-check-whether-point-latlong.html

techabhi
źródło
Tak, myślę, że to casting. Właściwie sam wykorzystałem ten algorytm za pomocą skryptu python. Moje wdrożenie można znaleźć tutaj: gramsky.blogspot.com/2012/12/...
ngramsky
Musiałem usunąć bity, które dodały 360 do współrzędnych ujemnych, aby działało to właściwie na długości 0.
user1431317 15.04.16
4

Wybrałbym wtyczkę Open Layers; pobierz go, a następnie możesz nawet dodać dowolną warstwę dynamiczną do mapy i wyeksportować.

* Zanim to zrobisz, upewnij się, że Twój projekt CRS (EPSG) jest ustawiony na WGS84 oraz że transformacja CRS „w locie” jest włączona w ustawieniach właściwości projektu.

Mam nadzieję że to pomoże.

Bryce Touchstone
źródło
0

jeśli używasz programu innej firmy jako geodjango, możesz sprawdzić swój punkt, czy w obrębie zestawu wielokątów, czy nie. więcej informacji jest tutaj .

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)

Mam nadzieję, że Ci to pomoże...

Aragonia
źródło
0

Wiem, że to trochę za późno, ale może się przydać, gdyby SomeOne nie wypróbował biblioteki Androida-Map-Utils. Opublikowałem metody specyficzne dla tego pytania tylko dla Androida. Proszę bardzo:

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

Sagar Shah
źródło