Sprawdź, czy punkt to Ląd czy Woda w Mapach Google

107

.. a następnie mapy Google „oddzielają wody od wód”

Cóż, nie w sensie biblijnym, ale ...

Chciałbym wiedzieć, jakie mam opcje, aby sprawdzić, czy punkt [Lat, Lon] to Ląd czy Woda.

Mapy Google oczywiście mają te dane (zbiorniki wodne są niebieskie) - ale czy jest coś w API, czego mogę użyć do tego? A jeśli nie - czy nie służą temu, ponieważ nigdy o tym nie pomyśleli? Albo dlatego, że jest to zbyt skomplikowane?

Nie znalazłem żadnych informacji w tej sprawie - poza kilkoma podobnymi pytaniami (np. Znalezienie typu terenu, czy wzniesienia - ale nie jest to dokładnie to, czego potrzebuję).

Czy jest do tego oddzielna warstwa? Opcja? Komenda? Czy powinienem zrobić to ręcznie?

Jedynym sposobem, w jaki mogę wymyślić, jak podejść do tego (powinienem zrobić to ręcznie), jest sprawdzenie każdego serwowanego kafelka pod kątem dokładnego punktu - a następnie sprawdzenie wartości RGB dla tego odcienia mapy Google. To tylko teoria - bo w praktyce - nie mam pojęcia, jak to osiągnąć, pierwszą przeszkodą jest to, że nie wiem, jak mogę na przykład przekonwertować położenie piksela na kafelku na punkt [LatLon]

Gotowe rozwiązanie byłoby znacznie łatwiejsze.

Zwróć uwagę, że nie potrzebuję CAŁEJ wody na świecie (na przykład - nie obchodzą mnie strumienie, oczka wodne, większość rzek czy basen twojego sąsiada. Potrzebuję punktów, gdzie można zapuścić się bez pomocy pływającego pojazdu )

EDYTUJ I

Po przeczytaniu komentarzy: Metoda elewacji nie jest wiarygodna, jest zbyt wiele miejsc PONIŻEJ poziomu morza (listę „najgłębszych” 10 można zobaczyć tutaj http://geology.com/below-sea-level/ ) i tam jest zbyt wiele śródlądowych zbiorników wodnych POWYŻEJ poziomu morza (jezior). Metoda odwrotnej geolokalizacji nie jest niezawodna, ponieważ zwróci podmiot geopolityczny, taki jak miasto lub stan - lub wielokrotnie ZERO. Sprawdziłem już te pseudo-rozwiązania, zanim zadałem pytanie - ale żadne z nich tak naprawdę nie odpowiedział na pytanie - te metody są w najlepszym razie złym „zgadywaniem”.

Obmerk Kronen
źródło
1
Możesz użyć biblioteki elewacji. Chociaż nie zawsze jest to prawdą, wyobrażam sobie, że przez większość czasu dzieje się to na poziomie morza. Istnieją dość oczywiste przypadki narożne (Death Valley CA, Holandia, jeziora w górach itp.), Ale może to działać w przybliżeniu.
dzięki, już o tym myślałem - ale jak zauważyłeś - jest zbyt wiele punktów poniżej poziomu morza na ziemi - wykluczenie ich wszystkich nie jest realnym rozwiązaniem ..
Obmerk Kronen
@michael - nie wspominając o wszystkich śródlądowych zbiornikach wodnych, o których wspomniałeś ... (jeziora itp.)
Obmerk Kronen
Może lepiej pasuje do GIS.SE? Możesz migrować, gdy nagroda dobiegnie końca.
TMS
Jak otrzymałeś odpowiedź, nie mam nic do powiedzenia na ten temat. Ale jeśli szukasz danych o wodzie lub informacji GIS, to jest oddzielna dyskusja na naszej oddzielnej domenie http://gis.stackexchange.com/ Tutaj , znajdziesz wiele rzeczy, których możesz potrzebować, w tym dane dotyczące wody .. które pomogą ci w przypadku ... (jeśli to konieczne ..) Old Post Mam nadzieję, że to pomoże ..
MarmiK

Odpowiedzi:

55

Oto 2 różne sposoby, możesz spróbować:

  • Możesz użyć odwrotnego geokodowania Map Google . W zestawie wyników możesz określić, czy jest to woda, sprawdzając types. Na wodach jest to typ natural_feature. Zobacz więcej pod tym linkiem http://code.google.com/apis/maps/documentation/geocoding/#Types .

    Musisz również sprawdzić nazwy obiektów, jeśli zawierają, Sea, Lake, Oceani kilka innych słów związanych z wodami, aby uzyskać większą dokładność. Na przykład pustynie też są natural_features.

    Plusy - Cały proces wykrywania zostanie wykonany na komputerze klienta. Nie ma potrzeby tworzenia własnej usługi po stronie serwera.

    Wady - bardzo niedokładne, a szanse na uzyskanie „żadnego” na wodach są bardzo wysokie.

  • Możesz wykryć wody / lądy według pikseli, używając Google Static Maps . Ale w tym celu musisz stworzyć usługę http.

    Oto kroki, które musi wykonać Twoja usługa:

    1. Otrzymywać latitude,longitude icurrent zoom od klienta.
    2. Wyślij http://maps.googleapis.com/maps/api/staticmap?center={szerokość geograficzną, długość}&zoom={ aktualne powiększenie } & size = 1x1 & maptype = roadmap & sensor = false request do usługi Google Static Map.
    3. Wykryj kolor piksela w statycznym obrazie 1x1.
    4. Odpowiedz na informacje o wykryciu.

    Nie możesz wykryć koloru piksela po stronie klienta. Tak, możesz załadować statyczny obraz na komputer klienta i narysować obraz na canvaselemencie. Ale nie możesz użyćgetImageData kontekstu płótna do uzyskania koloru piksela. Jest to ograniczone przez zasady dotyczące wielu domen.

    Więzy - bardzo dokładne wykrywanie

    Wady - użycie własnych zasobów serwera do wykrywania

Inżynier
źródło
2
Dzięki - już to sprawdziłem - nie wiedziałem, że te typy zmieniają się w Sea Lake Ocean i tym podobne, a tak jak wskazałeś w swoim redagowaniu - natural_feature to też góra, wyspa i pustynia. wskazywać na dokumentację? także - jak można wykonać odwrotne geokodowanie dla miejsc bez adresów? a co z jeziorem, które jest częścią geopoitycznego bytu? jak jezioro WEWNĄTRZ granicy miasta lub gminy (na przykład gatunek) lub po prostu punkt, który jest WEWNĄTRZ portu miejskiego. W moich próbach mi się to nie udało ..
Obmerk Kronen
3
Dla większości wody na świecie odwrotne geokodowanie zwróci „zero wyników”, sprawdź narzędzie do geokodowania: gmaps-samples-v3.googlecode.com/svn/trunk/geocoder/… i kliknij gdzieś w głębi oceanu.
Dr Molle,
@Tomas - nie to, że chcę być niemiły lub brak szacunku dla innych „układaczy” - ale może nie jest to głosowanie, ponieważ nie jest to poprawna / dokładna metoda?
Obmerk Kronen
3
Korzystanie z map statycznych w proponowany sposób prawdopodobnie byłoby uznane za naruszenie Warunków (10.1.1 (h)).
Andrew Leach
1
Jeśli chodzi o podejście do statycznych map, możesz to zrobić za pomocą stylu developers.google.com/maps/documentation/static-maps/…, ale równie dobrze możesz skorzystać z artykułu Saurav link.
miguev
19

Wydaje się, że nie jest to możliwe w przypadku żadnej obecnej usługi Google.

Ale są też inne usługi, takie jak usługa zapytań w wektorach współrzędnych JSON ! Po prostu odpytujesz dane w adresie URL i otrzymujesz odpowiedź JSON / XML .

Przykładowe żądanie: http://api.koordinates.com/api/vectorQuery.json?key=YOUR_GEODATA_KEY&layer=1298&x=-159.9609375&y=13.239945499286312&max_results=3&radius=10000&geometry=true&with_field_names=true

Musisz zarejestrować się i podać swój klucz oraz wybrany numer warstwy. Możesz przeszukiwać wszystkie ich repozytorium dostępnych warstw . Większość warstw ma charakter tylko regionalny, ale można też znaleźć warstwy globalne, takie jak World Coastline :

wprowadź opis obrazu tutaj

Po wybraniu warstwy i kliknięciu na zakładkę „Usługi” otrzymasz przykładowy adres URL żądania. Uważam, że wystarczy się zarejestrować i to wszystko!

A teraz najlepsze:

Możesz przesłać swoją warstwę!

Nie jest dostępny od razu, hej trzeba to jakoś przetworzyć, ale powinno działać! Repozytorium warstw wygląda tak, jakby ludzie przesyłali je w miarę potrzeb.

TMS
źródło
wygląda to prawie idealnie, jednak nie widzę żadnych lokalnych map, które nie są z Oceanii. Czy są jakieś warstwy w USA?
HaloWebMaster
@HaloWebMaster warstwa, o której wspomniałem, jest globalna. Możesz także przeszukiwać warstwy według regionu.
TMS
@HaloWebMaster Właśnie zauważyłem, że możesz przesłać własną warstwę! Zobacz moją aktualizację.
TMS,
Hej, Tomas, nie wiem, czy rzeczywiście dostałeś nagrodę, czy nie (ponieważ byłem offline przez tydzień), ale to jest niesamowite! Dziękuję za pomoc, nie byłbym w stanie uruchomić mojej aplikacji. Dzięki! (Jeśli nie dostałeś nagrody, nagrodzę ją, po prostu PM mnie)
HaloWebMaster
Hej, zaoszczędziłeś mi tydzień niestandardowego kodowania! To jest tego warte!
HaloWebMaster
8

To, czego używam i działa nieźle ... możesz poprawić test, jeśli masz więcej procesora do zmarnowania, dodając piksele.

function isItWatter($lat,$lng) {

    $GMAPStaticUrl = "https://maps.googleapis.com/maps/api/staticmap?center=".$lat.",".$lng."&size=40x40&maptype=roadmap&sensor=false&zoom=12&key=YOURAPIKEY";  
    //echo $GMAPStaticUrl;
    $chuid = curl_init();
    curl_setopt($chuid, CURLOPT_URL, $GMAPStaticUrl);   
    curl_setopt($chuid, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($chuid, CURLOPT_SSL_VERIFYPEER, FALSE);
    $data = trim(curl_exec($chuid));
    curl_close($chuid);
    $image = imagecreatefromstring($data);

    // this is for debug to print the image
    ob_start();
    imagepng($image);
    $contents =  ob_get_contents();
    ob_end_clean();
    echo "<img src='data:image/png;base64,".base64_encode($contents)."' />";

    // here is the test : I only test 3 pixels ( enough to avoid rivers ... )
    $hexaColor = imagecolorat($image,0,0);
    $color_tran = imagecolorsforindex($image, $hexaColor);

    $hexaColor2 = imagecolorat($image,0,1);
    $color_tran2 = imagecolorsforindex($image, $hexaColor2);

    $hexaColor3 = imagecolorat($image,0,2);
    $color_tran3 = imagecolorsforindex($image, $hexaColor3);

    $red = $color_tran['red'] + $color_tran2['red'] + $color_tran3['red'];
    $green = $color_tran['green'] + $color_tran2['green'] + $color_tran3['green'];
    $blue = $color_tran['blue'] + $color_tran2['blue'] + $color_tran3['blue'];

    imagedestroy($image);
    var_dump($red,$green,$blue);
    //int(492) int(570) int(660) 
    if($red == 492 && $green == 570 && $blue == 660)
        return 1;
    else
        return 0;
}
rebe100x
źródło
Kod działa; t działa na nowej wersji. Nowa wersja powinna wyglądać tak, jeśli ($ red == 537 && $ green == 627 && $ blue == 765)
Wim Pruiksma
8

Istnieje darmowy internetowy interfejs API, który dokładnie rozwiązuje ten problem o nazwie onwater.io . To nie jest coś wbudowanego w mapy Google, ale biorąc pod uwagę szerokość i długość geograficzną, dokładnie zwróci prawdę lub fałsz za pośrednictwem żądania get.

Przykład na wodzie: https://api.onwater.io/api/v1/results/23.92323,-66.3

{
  lat: 23.92323,
  lon: -66.3,
  water: true
}

Przykład na lądzie: https://api.onwater.io/api/v1/results/42.35,-71.1

{
  lat: 42.35,
  lon: -71.1,
  water: false
}

Pełne ujawnienie Pracuję w Dockwa.com , firmie stojącej za onwater. Zbudowaliśmy na wodzie, aby sami rozwiązać ten problem i pomóc społeczności. Jest darmowy (płatny za duży wolumen) i chcieliśmy się nim podzielić :)

stuyam
źródło
1
Zaktualizowane linki przykładowe: Przykład wody: api.onwater.io/api/v1/results/23.92323,-66.3 Przykład terenu: api.onwater.io/api/v1/results/42.35,-71.1
Christian K.
1
Nie jest już darmowy (dla większych ilości), ale jeśli spełnia swoje zadanie, nadal jest bardzo przystępny!
Christian K.,
Strona dokumentacji zawiera błąd. Chciałem sprawdzić, czy są jakieś dane dotyczące zasięgu? Mam na myśli, które kraje obejmujesz?
nr5
Czy onwater.io działa na jeziorach i rzekach? Jeśli tak, czy otrzymam wskazanie typu?
luksch
7

Pomyślałem, że bardziej interesujące byłoby wykonanie tego zapytania lokalnie, więc mogę być bardziej samodzielny: powiedzmy, że chcę wygenerować 25000 losowych współrzędnych lądowych naraz, wolałbym raczej uniknąć wywołań potencjalnie kosztownych zewnętrznych interfejsów API. Oto moje ujęcie w Pythonie, na przykładzie Pythona wspomnianym przez TomSchober. Zasadniczo wyszukuje współrzędne w gotowym pliku 350 MB zawierającym wszystkie współrzędne lądowe, a jeśli współrzędne tam istnieją, drukuje je.

import ogr
from IPython import embed
import sys

drv = ogr.GetDriverByName('ESRI Shapefile') #We will load a shape file
ds_in = drv.Open("land_polygons.shp")    #Get the contents of the shape file
lyr_in = ds_in.GetLayer(0)    #Get the shape file's first layer

#Put the title of the field you are interested in here
idx_reg = lyr_in.GetLayerDefn().GetFieldIndex("P_Loc_Nm")

#If the latitude/longitude we're going to use is not in the projection
#of the shapefile, then we will get erroneous results.
#The following assumes that the latitude longitude is in WGS84
#This is identified by the number "4236", as in "EPSG:4326"
#We will create a transformation between this and the shapefile's
#project, whatever it may be
geo_ref = lyr_in.GetSpatialRef()
point_ref=ogr.osr.SpatialReference()
point_ref.ImportFromEPSG(4326)
ctran=ogr.osr.CoordinateTransformation(point_ref,geo_ref)

def check(lon, lat):
    #Transform incoming longitude/latitude to the shapefile's projection
    [lon,lat,z]=ctran.TransformPoint(lon,lat)

    #Create a point
    pt = ogr.Geometry(ogr.wkbPoint)
    pt.SetPoint_2D(0, lon, lat)

    #Set up a spatial filter such that the only features we see when we
    #loop through "lyr_in" are those which overlap the point defined above
    lyr_in.SetSpatialFilter(pt)

    #Loop through the overlapped features and display the field of interest
    for feat_in in lyr_in:
        # success!
        print lon, lat

check(-95,47)

Wypróbowałem kilkanaście współrzędnych, działa cudownie. Plik „land_polygons.shp” można pobrać tutaj , komplementy dla OpenStreetMaps. (Sam użyłem pierwszego linku do pobrania WGS84, może drugi też działa)

SylvainB
źródło
A co z jeziorami? Czy traktuje punkty na jeziorach jako morze czy ląd?
fatma.ekici
Dobre pytanie! Sprawdziłem na stronie dane OpenStreetMaps, które były połączone w mojej odpowiedzi , i mówi, że plik lands opiera swoje wartości na tagu natural=coastline. Szybkie wyszukiwanie w Google daje użycie tej strony, która wyraźnie stwierdza, że ​​tagi wybrzeża w rzeczywistości nie mają zastosowania do jezior w ich nomenklaturze. Więc powiedziałbym, że nie , moja metoda nie identyfikuje jezior jako wody, ponieważ zestaw danych, którego używam, nie identyfikuje. Ale spróbuj sam!
SylvainB
7

Sprawdź ten artykuł . Dokładnie wykrywa, czy coś jest na wodzie, bez konieczności posiadania serwera. To sztuczka polegająca na niestandardowej funkcji stylizacji w Mapach Google.

Saurav
źródło
5

Oprócz odwrotnego geokodowania - jak zauważył dr Molle , może ono zwrócić ZERO_RESULTS - możesz skorzystać z usługi Elevation. Jeśli uzyskasz zero wyników przez odwrotne geokodowanie, uzyskaj wysokość lokalizacji. Ogólnie poziom morza jest ujemny, ponieważ dno morskie znajduje się poniżej poziomu morza. Jest w pełni opracowany przykład usługi elewacji.

Pamiętaj, że ponieważ Google nie udostępnia tych informacji, żadna inna metoda jest tylko domysłem, a domysły są z natury niedokładne. Jednak użycie typezwróconego przez odwrotne geokodowanie lub wysokości, jeśli typenie jest dostępna, obejmie większość ewentualności.

Andrew Leach
źródło
dziękuję za odpowiedź i przykładowy link (przy okazji - u mnie nie działa w Operze) - ale tak naprawdę nie mogę zignorować wszystkich obszarów które są lądowe i negatywne a moje eksperymenty pokazały, że TYP nie jest wiarygodny - i wielokrotnie wraca pobliski podmiot geopolityczny. musi istnieć bardziej precyzyjna metoda - „zgadywanie” nie wydaje się tutaj właściwym podejściem. Gdyby TYP był niezawodny - Byłoby to najlepsze rozwiązanie - ale tak nie jest ... i ignorujesz wszystkie śródlądowe zbiorniki wodne, które znajdują się POWYŻEJ poziomu morza ...
Obmerk Kronen
3

Ta metoda jest całkowicie zawodna. W rzeczywistości zwrócone dane będą całkowicie zależeć od tego, z jaką częścią świata pracujesz. Na przykład pracuję we Francji. Jeśli kliknę na morze na wybrzeżu Francji, Google zwróci najbliższą lokalizację LANDU, jaką może „odgadnąć”. Kiedy poprosiłem Google o informacje na to samo pytanie, odpowiedzieli, że nie są w stanie dokładnie zwrócić żądanego punktu na masie wody.

Wiem, że to niezbyt satysfakcjonująca odpowiedź. Jest to dość frustrujące, szczególnie dla tych z nas, którzy zapewniają użytkownikowi możliwość kliknięcia mapy w celu zdefiniowania pozycji znacznika.

Szymon
źródło
1
Zgadzam się - metody, które zasugerowali @ user1113426 i @Andrew Leach, nie są tak naprawdę metodami. lepiej powiedzieć użytkownikom „nie klikaj w niebieskie obszary” :-) ale poważnie - jestem bardzo zaskoczony, że Google nie chce wypuszczać takiej funkcji - choćby przybliżonej - lepiej niż „przybliżenie”, że istnieje teraz - tak jak Ty - czasami „przyciąga” do miejsca oddalonego o setki metrów. Nawet mój zaproponował metoda jest bardziej ccurate (szkoda, że nie ma pojęcia, w jaki sposób tego dokonać.)
Obmerk Kronen
3

Jeśli wszystko inne zawiedzie, zawsze możesz spróbować sprawdzić wysokość w danym punkcie i na pewną odległość - niewiele rzeczy poza wodą zwykle jest całkowicie płaskich.

Steve Barnes
źródło
dzięki, to fajny pomysł, ale nie udałoby się spektakularnie na każdym wodospadzie, czy kanionie rzeki ...
Obmerk Kronen
2

Niestety ta odpowiedź nie znajduje się w interfejsie API Map Google, a odnośny zasób nie jest bezpłatny, ale istnieje usługa internetowa dostarczana przez DynamicGeometry, która ujawnia operację, GetWaterOrLandktóra akceptuje parę szerokość / długość geograficzna ( możesz zobaczyć demo tutaj ).

Moje zrozumienie tego, jak to jest realizowane, polega na wykorzystaniu plików kształtów zbiorników wodnych. Jak dokładnie te pliki kształtów są używane z interfejsem API Map Google, ale możesz uzyskać pewne informacje z połączonej wersji demonstracyjnej.

Mam nadzieję, że to w jakiś sposób pomoże.

sellmeadog
źródło
2

Oto kolejny przykład w czystym JavaScript: http://jsfiddle.net/eUwMf/

Jak widać, idea jest w zasadzie taka sama jak rebe100x, pobiera obraz z interfejsu API statycznej mapy Google i odczytuje pierwszy piksel:

$("#xGps, #yGps").change(function() {
    var img = document.getElementById('mapImg');

    // Bypass the security issue : drawing a canvas from an external URL.
    img.crossOrigin='anonymous';

    var xGps = $("#xGps").val();
    var yGps = $("#yGps").val();

    var mapUrl = "http://maps.googleapis.com/maps/api/staticmap?center=" + xGps + "," + yGps +
        "&zoom=14&size=20x20&maptype=roadmap&sensor=false";

    // mapUrl += "&key=" + key;

    $(img).attr("src", mapUrl);

    var canvas = $('<canvas/>')[0];
    canvas.width = img.width;
    canvas.height = img.height;
    canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

    var pixelData = canvas.getContext('2d').getImageData(1, 1, 1, 1).data;

    if (pixelData[0] == 164 &&
        pixelData[1] == 190 &&
        pixelData[2] == 220) {
        $("#result").html("Water");
    } else {
        $("#result").html("Not water");
    }
});
IcanDivideBy0
źródło
1

Oto proste rozwiązanie

Ponieważ Google nie dostarcza wiarygodnych wyników w odniesieniu do współrzędnych znajdujących się na wodach oceanicznych lub śródlądowych, musisz skorzystać z innej usługi kopii zapasowej, takiej jak Yandex, aby pomóc w dostarczeniu tych krytycznych informacji, gdy ich brakuje. Najprawdopodobniej nie chciałbyś używać Yandex jako swojego głównego geokodera, ponieważ Google jest znacznie lepszy pod względem niezawodności i kompletności danych światowych, jednak Yandex może być bardzo przydatny w celu odzyskiwania danych, gdy dotyczą współrzędnych nad zbiornikami wodnymi, więc używaj obu.


Dokumentacja Yandex: https://api.yandex.com.tr/maps/doc/geocoder/desc/concepts/input_params.xml


Kroki, aby odzyskać nazwę oceanu:

1.) Najpierw użyj Google, aby odwrócić geokodowanie współrzędnych.

2.) Jeśli Google zwraca zero wyników, jest 99% prawdopodobne, że współrzędna leży nad oceanem. Teraz wykonaj drugie żądanie odwrotnego geokodowania z tymi samymi współrzędnymi do Yandex. Yandex zwróci odpowiedź JSON z dokładnymi współrzędnymi, w ramach tej odpowiedzi będą dwie ważne pary „klucz”: „wartość”

["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"]

and

["GeoObject"]["name"]

Sprawdź klucz rodzaju, jeśli == "hydro" wiesz, że znajdujesz się nad zbiornikiem wodnym, a ponieważ Google zwrócił zero wyników, na 99,99% jest prawdopodobne, że ten zbiornik wodny jest oceanem. Nazwą oceanu będzie powyższy klucz „nazwa”.

Oto przykład, jak używam tej strategii napisanej w języku Ruby

if result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] == "hydro"
     ocean = result.data["GeoObject"]["name"] 
end

Kroki w celu uzyskania nazwy śródlądowego akwenu:

W tym przykładzie załóżmy, że nasza współrzędna leży gdzieś w jeziorze:

1.) Najpierw użyj Google, aby odwrócić geokodowanie współrzędnych.

2.) Google najprawdopodobniej zwróci wynik będący widocznym adresem domyślnym na pobliskim terenie. W ten sposób dostarcza współrzędne adresu, który zwrócił, te współrzędne nie będą pasować do podanego przez Ciebie. Zmierz odległość między podaną współrzędną a tą, która została zwrócona z wynikiem, jeśli jest ona znacząco różna (na przykład 100 jardów), a następnie wykonaj żądanie dodatkowej kopii zapasowej w Yandex i sprawdź, czy wartość klucza „rodzaj” jest taka jest "hydro", to wiesz, że współrzędna leży na wodzie. Ponieważ Google zwrócił wynik w przeciwieństwie do powyższego przykładu, jest 99,99% prawdopodobne, że jest to zbiornik wodny śródlądowy, więc teraz możesz uzyskać nazwę. Jeśli „kind” nie == „hydro”, użyj geokodowanego obiektu Google.

["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"]

and

["GeoObject"]["name"]

Oto ten sam kod napisany w Rubim, aby uzyskać inland_body_of_water

if result.data["GeoObject"]["metaDataProperty"]["GeocoderMetaData"]["kind"] == "hydro"
     inland_body_of_water = result.data["GeoObject"]["name"] 
end

Uwaga dotycząca licencjonowania: z tego, co wiem, Google nie zezwala na wykorzystywanie ich danych do wyświetlania na żadnych innych mapach niż te oferowane przez Google. Yandex ma jednak bardzo elastyczne licencje i możesz używać ich danych do wyświetlania na mapach Google.

Yandex ma również wysoki limit 50 000 żądań dziennie bezpłatnie i bez wymaganego klucza API.

nagłówek_to_tahiti
źródło
1

Udało mi się podejść dość blisko, korzystając z Google Elevation API. Oto obraz wyników:

zrzut ekranu wyników

Widzisz, że sześciokąty prawie pozostają na lądzie, mimo że zdefiniowano prostokątny obwód, który częściowo przechodzi nad wodą. W tym przypadku sprawdziłem szybko z samych Google Maps i minimalna wysokość na lądzie wynosiła około 8-9m, czyli taki był mój próg. Kod jest w większości kopiowany / wklejany z dokumentacji Google i Stack Overflow, oto cała istota:

https://gist.github.com/dvas0004/fd541a0502528ebfb825

dvas0004
źródło
Do Twojej wiadomości, dokumentację Google Elevation API można znaleźć tutaj: developers.google.com/maps/documentation/javascript/elevation
dvas0004
2
jest to doskonały przykład możliwego zastosowania. ale cudownie zawiedzie na zbiornikach wodnych ze śluzą lądową (Lago di garda - Włochy w przykładzie z linkiem). Bardzo ładny kod, który może posłużyć jako podstawa do innego rozwiązania!
Obmerk Kronen,
1

Jeśli List<Address> adres zwraca 0, możesz przyjąć tę lokalizację jako ocean lub zasoby naturalne. Po prostu dodaj poniższy kod w swojej odpowiedzi Metoda odpowiedzi interfejsu API Miejsc Google.

Zainicjuj poniższą listę, jak wspomniano

List<Address> addresses = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);

if (addresses.size()==0) { Toast.MakeText(getApplicationContext,"Ocean or Natural Resources selected",Toast.LENGTH_SHORT).show(); }else{ }

Kumar PG
źródło
0

Jako kompletny nowicjusz w Pythonie nie mogłem znaleźć rozwiązania SylvainB do pracy ze skryptem Pythona, który sprawdza, czy współrzędne są na lądzie. Jednak udało mi się to rozgryźć, pobierając OSGeo4W ( https://trac.osgeo.org/osgeo4w/ ), a następnie zainstalowałem wszystko, czego potrzebowałem, pip, Ipython i sprawdziłem, czy są tam wszystkie określone importy. Zapisałem następujący kod jako plik .py.

Kod, aby sprawdzić, czy współrzędne są na lądzie

###make sure you check these are there and working separately before using the .py file 

import ogr
from IPython import embed
from osgeo import osr
import osgeo

import random
#####generate a 1000 random coordinates
ran1= [random.uniform(-180,180) for x in range(1,1001)]
ran2= [random.uniform(-180,180) for x in range(1,1001)]


drv = ogr.GetDriverByName('ESRI Shapefile') #We will load a shape file
ds_in = drv.Open("D:\Downloads\land-polygons-complete-4326\land-polygons-complete-4326\land_polygons.shp")    #Get the contents of the shape file
lyr_in = ds_in.GetLayer(0)    #Get the shape file's first layer

#Put the title of the field you are interested in here
idx_reg = lyr_in.GetLayerDefn().GetFieldIndex("P_Loc_Nm")

#If the latitude/longitude we're going to use is not in the projection
#of the shapefile, then we will get erroneous results.
#The following assumes that the latitude longitude is in WGS84
#This is identified by the number "4236", as in "EPSG:4326"
#We will create a transformation between this and the shapefile's
#project, whatever it may be
geo_ref = lyr_in.GetSpatialRef()
point_ref=osgeo.osr.SpatialReference()
point_ref.ImportFromEPSG(4326)
ctran=osgeo.osr.CoordinateTransformation(point_ref,geo_ref)
###check if the random coordinates are on land
def check(runs):
    lon=ran1[runs]
    lat=ran2[runs]
    #Transform incoming longitude/latitude to the shapefile's projection
    [lon,lat,z]=ctran.TransformPoint(lon,lat)
    #Create a point
    pt = ogr.Geometry(ogr.wkbPoint)
    pt.SetPoint_2D(0, lon, lat)
    #Set up a spatial filter such that the only features we see when we
    #loop through "lyr_in" are those which overlap the point defined above
    lyr_in.SetSpatialFilter(pt)
    #Loop through the overlapped features and display the field of interest
    for feat_in in lyr_in:
        return(lon, lat)

###give it a try
result = [check(x) for x in range(1,11)] ###checks first 10 coordinates

Próbowałem zmusić go do działania w R, ale miałem koszmar, próbując uzyskać wszystkie pakiety, które musisz zainstalować, więc utknęły w Pythonie.

Alec Christie
źródło
-3

Mam tutaj inne rozwiązanie. W obecnej implementacji mapy google nie oblicza kierunku / odległości od położenia wody do położenia lądu i odwrotnie. Dlaczego nie użyjemy tej logiki do określenia, czy chodzi o ląd czy wodę.

Weźmy na przykład ten przykład

jeśli chcemy określić, czy punkt xjest lądem czy wodą, to

sprawdźmy kierunek między punktem xa znanym punktem, yktórym jest ląd. Jeśli określa kierunek / odległość, to punkt xjest lądem lub wodą.

blganesh101
źródło
Czy faktycznie próbowałeś tego, czy po prostu zakładasz „gotowanie z wody”?
TMS,
A jak masz radzić sobie z mostami? czy tunele?
Obmerk Kronen