Verifique se um ponto é terra ou água no Google Maps

107

..e os mapas do Google "dividem as águas das águas"

Bem, não no sentido bíblico, mas ..

Gostaria de saber que opções tenho para verificar se um ponto de [Lat, Lon] é Terra ou Água.

O Google Maps obviamente tem esses dados (os corpos d'água são azuis) - mas há algo na API que eu possa usar para isso? E se não - eles não estão servindo porque nunca pensaram nisso? Ou porque é muito complicado?

Não encontrei nenhuma informação sobre o assunto - exceto algumas questões semelhantes aqui (como encontrar o tipo de terreno ou elevação - mas não é exatamente o que eu preciso).

Existe uma camada separada para isso? Uma opção? Comando? Ou devo fazer isso manualmente?

A única maneira que consigo pensar em como abordar isso (caso precise fazer isso manualmente) é verificar cada bloco servido para o ponto exato - e, em seguida, verificar o valor RGB para esse matiz do mapa do Google. Isso é apenas na teoria - porque na prática - não tenho ideia de como fazer isso, o primeiro obstáculo é que eu não sei como posso converter a localização de um pixel em um bloco para um ponto [LatLon], por exemplo

Uma solução pronta seria muito mais fácil.

Observe que não preciso de TODA a água do mundo (por exemplo - não me importo com riachos, pequenos lagos, a maioria dos rios ou a piscina do seu vizinho. Eu preciso de pontos onde uma pessoa pode se aventurar sem o auxílio de um veículo flutuante )

EDITAR I

Depois de ler os comentários: O método de elevação não é confiável, existem muitos lugares ABAIXO do nível do mar (você pode ver uma lista dos 10 "mais profundos" aqui http://geology.com/below-sea-level/ ) e ali há muitos corpos d'água sem litoral ACIMA do nível do mar (lagos). O método de geolocalização reversa não é confiável porque retornará uma entidade geopolítica, como uma cidade ou estado - ou ZERO muitas vezes. Já examinei essas pseudo-soluções antes de fazer a pergunta - mas nenhuma delas respondeu de fato à pergunta - esses métodos são, na melhor das hipóteses, "suposições" ruins.

Obmerk Kronen
fonte
1
Você pode ser capaz de usar a biblioteca de elevação. Embora nem sempre seja verdade, imagino que na maioria das vezes as coisas no nível do mar são aquáticas. Existem alguns casos esquivos bastante óbvios (Death Valley CA, Holanda, lagos nas montanhas, etc.), mas pode funcionar para uma aproximação aproximada.
obrigado, já pensei nisso - mas como você apontou - há muitos pontos abaixo do nível do mar na terra - excluir todos eles não é uma solução viável ..
Obmerk Kronen
@michael - para não mencionar todos os corpos d'água sem
saída para o
Talvez seja melhor para GIS.SE? Você pode migrar quando a recompensa terminar.
TMS
Como você recebeu a resposta, não tenho nada a dizer sobre isso. Mas, se estiver procurando por dados de água ou informações GIS, há uma discussão separada acontecendo em nosso domínio separado http://gis.stackexchange.com/ Aqui , você encontrará muitas coisas que pode precisar, incluindo dados de água .. que irão ajudá-lo no caso .. (se necessário ..) Postagem antiga Espero que isso ajude ..
MarmiK

Respostas:

55

Existem 2 maneiras diferentes, você pode tentar:

  • Você pode usar a geocodificação reversa do Google Maps . No conjunto de resultados, você pode determinar se é água verificando types. No caso de águas, o tipo é natural_feature. Veja mais neste link http://code.google.com/apis/maps/documentation/geocoding/#Types .

    Além disso, você precisa verificar os nomes dos recursos, se eles contêm Sea, Lake, Oceane algumas outras palavras relacionadas a águas para mais precisão. Por exemplo, os desertos também são natural_features.

    Prós - Todo o processo de detecção será feito na máquina do cliente. Não há necessidade de criar serviço próprio do lado do servidor.

    Contras - Muito impreciso e as chances de você não obter "nenhum" nas águas são muito altas.

  • Você pode detectar águas / terras por pixels, usando o Google Static Maps . Mas para isso você precisa criar um serviço http.

    Estas são as etapas que seu serviço deve executar:

    1. Receba latitude, longitudee current zoomdo cliente.
    2. Enviar http://maps.googleapis.com/maps/api/staticmap?center={latitude, ,longitude }&zoom={zoom atual`} & size = 1x1 & maptype = roadmap & sensor = solicitação falsa para o serviço Google Static Map.
    3. Detecta a cor do pixel de uma imagem estática 1x1.
    4. Responda uma informação sobre detecção.

    Você não pode detectar a cor do pixel no lado do cliente. Sim, você pode carregar a imagem estática na máquina do cliente e desenhar a imagem no canvaselemento. Mas você não pode usar getImageDatao contexto da tela para obter a cor do pixel. Isso é restrito pela política de domínio cruzado.

    Prons - detecção altamente precisa

    Contras - Uso de recursos próprios do servidor para detecção

Engenheiro
fonte
2
Obrigado - já verifiquei - não sabia que os tipos estão virando Sea Lake Ocean e similares, e como você apontou na sua edição - natural_feature também seria uma montanha, uma ilha e um deserto .. Você pode talvez apontar para uma documentação? também - como você pode fazer uma geocodificação reversa para lugares sem endereços? e que tal um lago que faz parte de uma entidade geoplítica? como um lago DENTRO dos limites de uma cidade ou município (por exemplo, gênero) ou simplesmente um ponto que está DENTRO de um porto da cidade. Em minhas tentativas, não consegui fazê-lo ..
Obmerk Kronen
3
Para a maior parte da água do mundo, uma geocodificação reversa retornará "resultados zero", verifique a ferramenta de geocodificação: gmaps-samples-v3.googlecode.com/svn/trunk/geocoder/… e clique em algum lugar dentro de um oceano.
Dr.Molle de
@Tomas - não que eu queira ser antipático ou desrespeitoso com outros "stackers" - mas talvez não seja votado porque não é um método válido / preciso?
Obmerk Kronen de
3
Usar mapas estáticos da maneira proposta provavelmente seria considerado uma violação dos Termos (10.1.1 (h)).
Andrew Leach
1
Quanto à abordagem de mapas estáticos, você pode fazer isso com o estilo developers.google.com/maps/documentation/static-maps/… mas também pode usar o artigo Saurav com link.
miguev,
19

Não parece possível com nenhum serviço atual do Google.

Mas existem outros serviços, como o serviço Koordinates Vector JSON Query ! Você simplesmente consulta os dados no URL e obtém uma resposta JSON / XML .

Solicitação de exemplo: 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

Você deve registrar e fornecer sua chave e o número da camada selecionada. Você pode pesquisar todos os seus repositórios de camadas disponíveis . A maioria das camadas são apenas regionais, mas você também pode encontrar globais, como o Litoral Mundial :

insira a descrição da imagem aqui

Ao selecionar uma camada, você clica na guia "Serviços" e obtém o URL de solicitação de exemplo. Acredito que você só precisa se cadastrar e é isso!

E agora o melhor:

Você pode enviar sua camada!

Não está disponível imediatamente, ei, temos que processá-lo de alguma forma, mas deve funcionar! O repositório de camadas realmente parece que as pessoas os carregaram quando precisaram.

TMS
fonte
parece quase perfeito, mas não vejo nenhum mapa local que não seja da Oceania. Existe alguma camada dos EUA?
HaloWebMaster
@HaloWebMaster a camada que mencionei é global. E você também pode pesquisar as camadas por região.
TMS
@HaloWebMaster Acabei de notar que você pode enviar sua própria camada! Veja minha atualização.
TMS
Ei, Tomas, não sei se você realmente conseguiu a recompensa ou não (já que fiquei offline por uma semana), mas isso é incrível! Obrigado por sua ajuda, eu não teria conseguido fazer meu aplicativo funcionar. Obrigado! (Se você não recebeu a recompensa, eu vou reagrupá-la, apenas me mande um PM)
HaloWebMaster
Ei, você me salvou uma semana de codificação personalizada! Vale a pena!
HaloWebMaster
8

É isso que eu uso e está funcionando bem ... você pode melhorar o teste se tiver mais cpu para desperdiçar adicionando pixels.

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
fonte
Código doens; t funciona na nova versão. A nova versão deve ser assim se ($ red == 537 && $ green == 627 && $ blue == 765)
Wim Pruiksma
8

Existe uma API web gratuita que resolve exatamente esse problema, chamada onwater.io . Não é algo embutido no Google Maps, mas dada uma latitude e longitude, retornará verdadeiro ou falso com precisão por meio de uma solicitação get.

Exemplo na água: https://api.onwater.io/api/v1/results/23.92323,-66.3

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

Exemplo em terra: https://api.onwater.io/api/v1/results/42.35,-71.1

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

Divulgação total Eu trabalho na Dockwa.com , a empresa por trás do onwater. Construímos onwater para resolver este problema nós mesmos e ajudar a comunidade. É grátis para usar (pago para alto volume) e queríamos compartilhar :)

Stuyam
fonte
1
Links de exemplo atualizados: Exemplo de água: api.onwater.io/api/v1/results/23.92323,-66.3 Exemplo de terra: api.onwater.io/api/v1/results/42.35,-71.1
Christian K.
1
Não é mais gratuito (para volumes maiores), mas se funcionar, ainda é muito acessível!
Christian K.
A página de documentação apresenta um erro. Eu queria verificar se havia algum dado específico de cobertura? Quero dizer, quais países você cobre?
nº5 de
O onwater.io funciona para lagos e rios? Em caso afirmativo, obtenho uma indicação do tipo?
luksch
7

Achei mais interessante fazer essa consulta localmente, para ser mais autossuficiente: digamos que eu queira gerar 25.000 coordenadas terrestres aleatórias de uma vez, prefiro evitar chamadas para APIs externas possivelmente caras. Aqui está minha chance em python, usando o exemplo python mencionado por TomSchober. Basicamente, ele procura as coordenadas em um arquivo pré-fabricado de 350 MB contendo todas as coordenadas terrestres, e se as coordenadas existem lá, ele as imprime.

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)

Tentei uma dúzia de coordenadas, funciona maravilhosamente bem. O arquivo "land_polygons.shp" pode ser baixado aqui , cortesia do OpenStreetMaps. (Eu usei o primeiro link de download WGS84 sozinho, talvez o segundo funcione bem)

SylvainB
fonte
E lagos? Considera os pontos nos lagos como mar ou terra?
fatma.ekici
Boa pergunta! Verifiquei na página os dados do OpenStreetMaps que estavam vinculados à minha resposta , e ele diz que o arquivo de terras baseia seus valores na tag natural=coastline. Uma rápida pesquisa no Google oferece o uso desta página que afirma especificamente que as marcas de linha costeira, na verdade, não se aplicam a lagos em sua nomenclatura. Então, eu diria que não , meu método não identifica lagos como água, já que o conjunto de dados que estou usando não identifica. Mas tente você mesmo!
SylvainB
7

Confira este artigo . Ele detecta com precisão se algo está na água sem a necessidade de um servidor. É um hack que depende do recurso de estilo personalizado do Google Maps.

Saurav
fonte
5

Além da geocodificação reversa - como o Dr. Molle apontou, ela pode retornar ZERO_RESULTS - você pode usar o serviço Elevation. Se você obtiver zero resultados por geocodificação reversa, obtenha a elevação do local. Geralmente, o mar recebe um número negativo porque o fundo do mar está abaixo do nível do mar. Há um exemplo totalmente trabalhado do serviço de elevação.

Tenha em mente que, como o Google não disponibiliza essas informações, qualquer outro método é apenas uma suposição e as suposições são inerentemente imprecisas. No entanto, usar o typeretornado por geocodificação reversa ou a elevação, se typenão estiver disponível, cobrirá a maioria das eventualidades.

Andrew Leach
fonte
obrigado pela sua resposta e pelo link de exemplo (BTW - não está funcionando no Opera para mim) - mas eu realmente não posso ignorar todas as áreas que são terrestres e negativas e meus experimentos mostraram que o TYPE não é confiável - e muitas vezes retorna uma entidade geopolítica próxima. deve haver algum método mais preciso - "adivinhar" não parece a abordagem certa aqui. Se o TIPO fosse confiável - teria sido a melhor solução - mas não é ... e você está ignorando todos os corpos d'água sem
saída para o
3

Este método não é totalmente confiável. Na verdade, os dados retornados dependerão totalmente da parte do mundo com que você está trabalhando. Por exemplo, estou trabalhando na França. Se eu clicar no mar na costa da França, o Google retornará o local LAND mais próximo que ele pode "adivinhar". Quando solicitei informações ao Google para esta mesma pergunta, eles responderam que não conseguiram retornar com precisão aquele ponto solicitado em uma massa de água.

Não é uma resposta muito satisfatória, eu sei. Isso é muito frustrante, especialmente para aqueles de nós que fornecem ao usuário a capacidade de clicar no mapa para definir a posição de um marcador.

Simon
fonte
1
Eu concordo - os métodos sugeridos por @ user1113426 e @Andrew Leach não são realmente métodos. é melhor dizer aos usuários "não clique nas áreas azuis" :-) mas sério - estou muito surpreso que o Google não queira liberar tal função - mesmo que aproximada - é melhor que a "aproximação" que existe agora - como o seu ponteiro - às vezes "se encaixa" em um local a centenas de metros de distância. Até mesmo meu método sugerido é mais preciso (pena que não tenho ideia de como fazer isso.)
Obmerk Kronen
3

Se tudo mais falhar, você pode sempre tentar verificar a elevação no ponto e a alguma distância - muitas coisas além da água tendem a ser completamente planas.

Steve Barnes
fonte
obrigado, esta é uma boa ideia, mas falharia espetacularmente em cada cachoeira, ou um desfiladeiro de rio ...
Obmerk Kronen
2

Infelizmente, esta resposta não está na API do Google Maps e o recurso referenciado não é gratuito, mas há um serviço da web fornecido por DynamicGeometry que expõe uma operação GetWaterOrLandque aceita um par de latitude / longitude ( você pode ver uma demonstração aqui ).

Meu entendimento de como isso é implementado é usando arquivos de forma de corpo d'água. Exatamente como esses arquivos de forma são usados ​​com a API do Google Maps, mas você pode obter algumas informações na demonstração vinculada.

Espero que ajude de alguma forma.

sellmeadog
fonte
2

Aqui está outro exemplo em JavaScript puro: http://jsfiddle.net/eUwMf/

Como você pode ver, a ideia é basicamente a mesma que rebe100x, pegar a imagem da API do mapa estático do Google e ler o primeiro pixel:

$("#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
fonte
1

Aqui está uma solução simples

Como o Google não fornece resultados confiáveis ​​com relação às coordenadas localizadas no oceano ou nos corpos d'água interiores, você precisa usar outro serviço de backup, como o Yandex, para ajudar a fornecer essas informações críticas quando elas estiverem ausentes. Provavelmente, você não gostaria de usar o Yandex como seu geocodificador principal porque o Google é muito superior na confiabilidade e integridade dos dados mundiais. No entanto, o Yandex pode ser muito útil para a finalidade de recuperar dados quando se relaciona a coordenadas sobre corpos d'água, então use ambos.


Documentação Yandex: https://api.yandex.com.tr/maps/doc/geocoder/desc/concepts/input_params.xml


As etapas para recuperar o nome do oceano:

1.) Use o Google primeiro para reverter a geocodificação da coordenada.

2.) Se o Google retornar zero resultados, é 99% provável que a coordenada esteja sobre um oceano. Agora faça uma solicitação secundária de geocodificação reversa com as mesmas coordenadas para Yandex. Yandex retornará uma resposta JSON com para as coordenadas exatas, dentro desta resposta haverá dois pares de importância "chave": "valor"

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

and

["GeoObject"]["name"]

Verifique o tipo de chave, se for == "hidro" você sabe que está sobre um corpo d'água e, como o Google retornou zero resultados, é 99,99% de probabilidade desse corpo d'água ser um oceano. O nome do oceano será a chave "nome" acima.

Aqui está um exemplo de como eu uso essa estratégia escrita em Ruby

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

As etapas para recuperar um nome de corpo d'água interno:

Para este exemplo, suponha que nossa coordenada esteja em um lago em algum lugar:

1.) Use o Google primeiro para reverter a geocodificação da coordenada.

2.) O Google provavelmente retornará um resultado que é um endereço padrão de destaque em um terreno próximo. Neste resultado ele fornece as coordenadas do endereço que retornou, esta coordenada não coincidirá com a que você forneceu. Meça a distância entre a coordenada que você forneceu e aquela retornada com o resultado, se for significativamente diferente (por exemplo, 100 jardas), em seguida, execute uma solicitação de backup secundária com Yandex e verifique para ver o valor da chave "kind", se é "hidro", então você sabe que a coordenada está na água. Como o Google retornou um resultado diferente do exemplo acima, é 99,99% provável que este seja um corpo de água interior, então agora você pode obter o nome. Se "kind" não == "hydro", use o objeto geocodificado do Google.

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

and

["GeoObject"]["name"]

Aqui está o mesmo código escrito em Ruby para obter inland_body_of_water

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

Uma observação sobre o licenciamento: até onde eu sei, o Google não permite que você use seus dados para exibição em quaisquer outros mapas além dos que o Google oferece. Yandex, entretanto, tem licenciamento muito flexível, e você pode usar seus dados para serem exibidos no Google Maps.

Além disso, Yandex tem um limite de taxa alta de 50.000 solicitações / dia gratuitas e sem a chave API necessária.

header_to_tahiti
fonte
1

Consegui chegar bem perto usando a API do Google Elevation. Aqui está uma imagem dos resultados:

captura de tela dos resultados

Você vê que os hexágonos praticamente permanecem na terra, embora um perímetro retangular seja definido que passa parcialmente sobre a água. Neste caso, fiz uma verificação rápida no próprio Google Maps e a elevação mínima em terra era de cerca de 8-9m, então esse era o meu limite. O código é principalmente copiado / colado da documentação do Google e Stack Overflow, aqui está a essência completa:

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

dvas0004
fonte
Apenas para sua informação, a documentação da API do Google Elevation pode ser encontrada aqui: developers.google.com/maps/documentation/javascript/elevation
dvas0004
2
este é um ótimo exemplo de uso possível. mas falhará gloriosamente em corpos d'água de bloqueio de terra (Lago di garda - Itália no exemplo da imagem vinculada). Um código muito bom pensado para ser usado como uma possível base para outra solução!
Obmerk Kronen
1

Se o List<Address>endereço retornar 0, você pode assumir esta localização como oceano ou Recursos naturais. Basta adicionar o código abaixo em Seu método de resposta da resposta da API do Google Places.

Inicializar abaixo da lista conforme mencionado

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
fonte
0

Como um novato completo em Python, não consegui fazer a solução do SylvainB funcionar com o script Python que verifica se as coordenadas estão em terra. Eu consegui descobrir, no entanto, baixando OSGeo4W ( https://trac.osgeo.org/osgeo4w/ ) e depois instalei tudo que precisava pip, Ipython, e verifiquei se todas as importações especificadas estavam lá. Salvei o código a seguir como um arquivo .py.

Código para verificar se as coordenadas estão em terra

###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

Tentei fazê-lo funcionar em R, mas tive um pesadelo ao tentar obter todos os pacotes que você precisa para instalar tão preso ao python.

Alec Christie
fonte
-3

Eu tenho uma solução diferente aqui. Na implementação atual do mapa do Google, ele não calcula a direção / distância de um local de água para um local de terra e vice-versa. Por que não usamos essa lógica para determinar se o ponto é terra ou água.

Por exemplo, vamos dar este exemplo

se queremos determinar, se um ponto x é terra ou água, então

vamos verificar a direção entre o ponto xe um ponto conhecido yque é a terra. Se ele determina a direção / distância, o ponto xé a terra ou a água.

blganesh101
fonte
Você já experimentou ou está apenas presumindo, "cozinhando com água"?
TMS
E como você pretende lidar com pontes? ou túneis?
Obmerk Kronen