Como converter coordenadas afins em lat / lng?

14

Eu sou extremamente novo no GIS.

Estou usando gdalpara ler em um mapa de uso e cobertura de terra e preciso escolher a lat / lng de certos tipos de cobertura da terra para indexar em um conjunto de dados diferente, expresso apenas em lat / lng. Unfortuantely, eu não entendo a forma das coordenadas x e y que me foi dada a partir do geotransform, especificamente o originXe originYabaixo:

geotransform = dataset.GetGeoTransform()
originX = geotransform[0]
originY = geotransform[3]

Imprimir esses valores me dá coordenadas como (447466.693808, 4952570.40529). Como eles se relacionam com a latitude e longitude originais?

Editar:

Aqui está um exemplo simples de python que me deu o que eu estava procurando:

srs = osr.SpatialReference()
srs.ImportFromWkt(dataset.GetProjection())

srsLatLong = srs.CloneGeogCS()
ct = osr.CoordinateTransformation(srs,srsLatLong)
print ct.TransformPoint(originX,originY)

Roubado de: tolatlong.py

Rico
fonte
Parece que seus dados são projetados (por exemplo, UTM) e você precisará saber qual é a projeção para "desprojetar" as coordenadas longas / latinas.
@ Dan Obrigado, então eu sei que posso obter a projeção através de um dataset.GetProjectionRef()e descobrir que estou usando a "UTM Zone 10", mas e daí? Estou pesquisando métodos como "desprojeto", mas estou aparecendo nulo.
Rich
desculpe pelo uso do termo desprojeto (entre aspas), pois os dados em graus decimais não são projetados, mas se você deseja obter dados projetados de volta aos graus decimais de qualquer projeção, é necessário (observe as aspas) "projeto" de volta a um sistema de coordenadas geográficas, também conhecido como dados em graus decimais.
2
Esse encadeamento (mais novo) fornece um exemplo explícito e outra solução: gis.stackexchange.com/questions/8430/…
whuber

Respostas:

10

O gdal_translate irá reprojetar seus dados de qualquer projeção em que houver (nesse caso, você deseja o EPSG: 4326) usando:

gdal_translate -a_srs epsg:4326 srcfile new_file 

ou você pode usar o gdaltrasform para converter os pontos (e tenho certeza de que também pode acessá-lo no Python (?))

Ian Turton
fonte
(+1) Não sei por que isso foi negado, Ian, porque me parece algum tipo de operação que será necessária após a transformação afim ser aplicada.
whuber
gdal_translate não funcionará da maneira que você a possui (ou seria apenas atribuir EPSG: 4326 aos dados), você precisará distorcer os dados com algo como: gdalwarp -s_srs EPSG: 32610 -t_srs EPSG: 4326 src dest Se o Como os dados já possuem metadados do proj, você pode abandonar o parâmetro -s_srs.
MerseyViking
Talvez seja isso que eu estou procurando. O "epsg: 4326" é uma transformação para lat / lng global? Acho que vejo algumas aulas em que posso fornecer uma projeção. Estava pensando em "WGS: 84", mas não sei a diferença.
Rich
1
@ Rich Clique na tag "sistema de coordenadas" em sua pergunta, classifique a página resultante por votos e comece a ler. Muitas de suas perguntas serão respondidas em alguns minutos.
whuber
7

A geotransformação está documentada em https://gdal.org/user/raster_data_model.html . A idéia é que você pegue (x, y) coordenadas diretamente do conjunto de dados, aplique uma transformação linear para obter (u, v) com

u = a*x + b*y
v = c*x + d*y

(você pode considerar isso como a definição de uma transformação linear) e, em seguida, mudar a origem adicionando geotransforma [0] a u e geotransforma [3] a v. Isso fornece a "transformação afim" de (x, y). Ele realmente pretende girar, alterar a escala, talvez corrigir um pouco alguns erros de inclinação e reposicionar as coordenadas específicas dos dados (x, y) para corresponder a um sistema de coordenadas conhecido. O resultado deve produzir coordenadas projetadas. Isso significa simplesmente que existe um procedimento matemático que toma (longitude, latitude) e as transforma em coordenadas conhecidas: isso é chamado de "projeção". "Desprojetar" está fazendo o inverso; portanto, se você sabe qual projeção é necessária, aplica- a às coordenadas afim transformadas (x, y) para obter a latitude e longitude.

A propósito, os valores das constantes a, b, c, d são dados pelas entradas 1, 2, 4 e 5 na matriz de geotransformações.

whuber
fonte
1
Li a seção de geotransformação do link que você forneceu, mas acho que não é isso que estou buscando. Desculpe se estou sendo obtuso, mas isso não descreve como projetar índices x e y (0 a XSize ou YSize) para coordenadas projetadas? Estou curioso para saber como você traduz coordenadas projetadas em latitude e longitude. Como um exemplo simples, a geotransformação define a origem x / y do canto superior esquerdo da varredura em coordenadas projetadas (447466.693808, 4952570.40529). Como eu transformaria essas coordenadas novamente em lat / lng (algo como lat: 44, lng: -122).
Rich
@ Rich Não, esse link não descreve uma projeção. Ele descreve apenas uma mudança de coordenadas entre dois mapas, não entre o mundo e um mapa. A desprojeção transforma a transformação afim das coordenadas em (lat, lon). Você não deseja escrever o código para isso, se puder ajudá-lo! A desprojeção é quase sempre uma questão de identificar qual projeção é necessária e chamar o software certo para fazer o trabalho por você (como sugerido na resposta da @iant).
whuber
Link quebrado. @whuber estou certo de que a transformação afim (de GetGeoTransform da GDAL) é uma transformação entre pixels e coordenadas CRS? Assim, por exemplo, se os dados estiverem em uma projeção GDA, os pontos precisam ser transformados de WGS84 / lat / lon para GDAXX usando, por exemplo, o CoordianteTransform, e depois para pixels, usando o GeoTransform afim? Esse processo de duas etapas é algo que me atrapalha bastante, e suspeito que também esteja causando problemas no OP. Não ajudou que o xarray / rasterio parece ter um bug que atrapalha os valores do GeoTransform: github.com/pydata/xarray/issues/3185
naught101
@naught Encontrei o novo URL e atualizei minha postagem.
whuber
0

Você pode usar o seguinte:

import gdal, numpy as n
def coord(file):
    padfTransform = file.GetGeoTransform()
    indices = n.indices(file.ReadAsArray().shape)
    xp = padfTransform[0] + indices[1]*padfTransform[1] + indices[1]*padfTransform[2]   
    yp = padfTransform[3] + indices[0]*padfTransform[4] + indices[0]*padfTransform[5]  
    return xp,yp
file = gdal.Open('Yourfile.tif') # A GeoTiff file
x,y = coord(file)

coord retornará longitude (x) e latitude (y) de todos os pixels. Lembre-se de que as coordenadas estão no canto esquerdo de um pixel

Ishan Tomar
fonte
Não deveriam ser indixes [1] * padfTransform [1] + índices [0] * padfTransform [2] e vice-versa para o yp?
precisa saber é o seguinte