Comment convertir des coordonnées affines en lat / lng?

14

Je suis extrêmement nouveau dans le SIG.

J'utilise gdalpour lire une carte d'utilisation des terres / couverture terrestre et j'ai besoin de choisir le lat / lng de certains types de couverture terrestre à indexer dans un ensemble de données différent qui n'est exprimé qu'en lat / lng. Malheureusement, je ne comprends pas la forme des coordonnées x et y qui me sont données par la géotransformation, en particulier la originXet originYci - dessous:

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

L'impression de ces valeurs me donne des coordonnées comme (447466.693808, 4952570.40529). Quel est leur rapport avec la latitude et la longitude d'origine?

Éditer:

Voici un exemple simple de python qui m'a donné ce que je cherchais:

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

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

Volé à: tolatlong.py

Riches
la source
Il semble que vos données soient projetées (par exemple, UTM) et vous aurez besoin de savoir ce qu'est la projection afin de la "dé-projeter" en arrière aux coordonnées long / lat.
@ Dan Merci, donc je sais que je peux obtenir la projection via un dataset.GetProjectionRef()et savoir que j'utilise "UTM Zone 10", mais alors quoi? Je recherche des méthodes telles que "non-projeter" mais je suis nulle.
Rich
désolé pour l'utilisation du terme non projeté (entre guillemets) car les données en degrés décimaux ne sont pas projetées, mais si vous souhaitez récupérer les données projetées en degrés décimaux à partir d'une projection donnée, vous devez (noter les guillemets) "projeter" il revenir à un système de coordonnées géographiques, alias données de degré décimal.
2
Ce fil (plus récent) fournit un exemple explicite et une autre solution: gis.stackexchange.com/questions/8430/…
whuber

Réponses:

10

gdal_translate va reprojeter vos données de n'importe quelle projection dans laquelle elles se trouvent vers une autre (dans ce cas, vous voulez EPSG: 4326) en utilisant:

gdal_translate -a_srs epsg:4326 srcfile new_file 

ou vous pouvez utiliser gdaltrasform pour convertir les points (et je suis sûr que vous pouvez aussi y accéder depuis Python (?))

Ian Turton
la source
(+1) Je ne sais pas pourquoi cela a été rejeté, Ian, car cela me semble être une sorte d'opération comme si elle allait être nécessaire après l'application de la transformation affine.
whuber
gdal_translate ne fonctionnera pas comme vous l'avez (ou plutôt il assignerait simplement EPSG: 4326 aux données), vous devez déformer les données avec quelque chose comme: gdalwarp -s_srs EPSG: 32610 -t_srs EPSG: 4326 src dest Si le les données contiennent déjà des métadonnées proj, vous pouvez abandonner le paramètre -s_srs.
MerseyViking
C'est peut-être ce que je recherche. Le "epsg: 4326" est-il une transformation en lat / lng global? Je pense que je vois des classes où je peux fournir une projection, je pensais "WGS: 84", mais je ne connais pas la différence.
Rich
1
@Rich Cliquez sur la balise "système de coordonnées" dans votre question, triez la page résultante par votes et commencez à lire. Beaucoup de vos questions recevront une réponse en quelques minutes.
whuber
7

La géotransformation est documentée sur https://gdal.org/user/raster_data_model.html . L'idée est que vous prenez les coordonnées (x, y) directement à partir du jeu de données, appliquez une transformation linéaire pour obtenir (u, v) avec

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

(vous pouvez prendre cela comme la définition d'une transformation linéaire), puis déplacez l'origine en ajoutant la géotransformation [0] à u et la géotransformation [3] à v. Cela donne la "transformation affine" de (x, y). Il est vraiment destiné à faire pivoter, changer d'échelle, peut-être corriger un peu certaines erreurs d'inclinaison, et re-situer les coordonnées spécifiques aux données (x, y) pour qu'elles correspondent à un système de coordonnées connu. Le résultat est censé produire des coordonnées projetées. Cela signifie simplement qu'il existe une procédure mathématique prenant (longitude, latitude) et les transformant en coordonnées connues: c'est ce qu'on appelle la "projection". "Unprojecting" fait l'inverse; Donc, si vous savez quelle projection est nécessaire, vous l'appliquez aux coordonnées affinées transformées (x, y) pour obtenir la latitude et la longitude.

Soit dit en passant, les valeurs des constantes a, b, c, d sont données par les entrées 1, 2, 4 et 5 du tableau de géotransformation.

whuber
la source
1
J'ai lu la section de géotransformation du lien que vous avez fourni, mais je ne pense pas que ce soit ce que je recherche. Désolé si je suis obtus, mais cela ne décrit-il pas comment projeter les indices x et y (0 à XSize ou YSize) aux coordonnées projetées? Je suis curieux de savoir comment vous traduisez les coordonnées projetées en latitude et longitude. À titre d'exemple simple, la géotransformation définit l'origine x / y du coin supérieur gauche du raster en coordonnées projetées (447466.693808, 4952570.40529). Comment pourrais-je transformer ces coordonnées en lat / lng (quelque chose comme lat: 44, lng: -122).
Rich
@Rich Non, ce lien ne décrit pas une projection. Il décrit uniquement un changement de coordonnées entre deux cartes, pas entre le monde et une carte. La non - projection transforme la transformation affine des coordonnées en (lat, lon). Vous ne pas voulez écrire le code pour que si vous pouvez l' aider! La non-projection consiste presque toujours à identifier la projection nécessaire et à appeler le bon logiciel pour faire le travail pour vous (comme suggéré dans la réponse de @ iant).
whuber
Le lien est rompu. @whuber ai-je raison que la transformation affine (de GetGeoTransform de GDAL) est une transformation entre pixels et coordonnées CRS? Ainsi, par exemple, si les données sont dans une projection GDA, les points doivent être transformés de WGS84 / lat / lon en GDAXX en utilisant, par exemple, la CoordianteTransform, puis en pixels en utilisant l'affin GeoTransform? Ce processus en deux étapes m'a beaucoup fait trébucher, et je soupçonne également de causer des problèmes OP. N'a pas aidé que xarray / rasterio semble avoir un bogue qui fout les valeurs de GeoTransform
naught101
@naught j'ai trouvé la nouvelle URL et mis à jour mon message.
whuber
0

Vous pouvez utiliser les éléments suivants:

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 renverra la longitude (x) et la latitude (y) de tous les pixels. Gardez à l'esprit que les coordonnées sont du coin gauche d'un pixel

Ishan Tomar
la source
Ne devrait-il pas s'agir d'indixes [1] * padfTransform [1] + d'indices [0] * padfTransform [2] et vice versa pour le yp?
CMCDragonkai