¿Hay alguna manera de obtener las coordenadas de las esquinas (en grados lat / long) de un archivo ráster usando los enlaces de Python de gdal?
Algunas búsquedas en línea me han convencido de que no existe, así que he desarrollado una solución analizando el resultado de gdalinfo, es algo básico, pero pensé que podría ahorrar algo de tiempo para las personas que podrían estar menos cómodas con Python. También solo funciona si gdalinfo contiene las coordenadas geográficas junto con las coordenadas de las esquinas, lo cual no creo que sea siempre el caso.
Aquí está mi solución, ¿alguien tiene alguna solución mejor?
gdalinfo en un ráster apropiado da como resultado algo así a la mitad de la salida:
Corner Coordinates:
Upper Left ( -18449.521, -256913.934) (137d 7'21.93"E, 4d20'3.46"S)
Lower Left ( -18449.521, -345509.683) (137d 7'19.32"E, 5d49'44.25"S)
Upper Right ( 18407.241, -256913.934) (137d44'46.82"E, 4d20'3.46"S)
Lower Right ( 18407.241, -345509.683) (137d44'49.42"E, 5d49'44.25"S)
Center ( -21.140, -301211.809) (137d26'4.37"E, 5d 4'53.85"S)
Este código funcionará en archivos cuyo gdalinfo se vea así. Creo que a veces las coordenadas estarán en grados y decimales, en lugar de grados, minutos y segundos; Debería ser trivial ajustar el código para esa situación.
import numpy as np
import subprocess
def GetCornerCoordinates(FileName):
GdalInfo = subprocess.check_output('gdalinfo {}'.format(FileName), shell=True)
GdalInfo = GdalInfo.split('/n') # Creates a line by line list.
CornerLats, CornerLons = np.zeros(5), np.zeros(5)
GotUL, GotUR, GotLL, GotLR, GotC = False, False, False, False, False
for line in GdalInfo:
if line[:10] == 'Upper Left':
CornerLats[0], CornerLons[0] = GetLatLon(line)
GotUL = True
if line[:10] == 'Lower Left':
CornerLats[1], CornerLons[1] = GetLatLon(line)
GotLL = True
if line[:11] == 'Upper Right':
CornerLats[2], CornerLons[2] = GetLatLon(line)
GotUR = True
if line[:11] == 'Lower Right':
CornerLats[3], CornerLons[3] = GetLatLon(line)
GotLR = True
if line[:6] == 'Center':
CornerLats[4], CornerLons[4] = GetLatLon(line)
GotC = True
if GotUL and GotUR and GotLL and GotLR and GotC:
break
return CornerLats, CornerLons
def GetLatLon(line):
coords = line.split(') (')[1]
coords = coords[:-1]
LonStr, LatStr = coords.split(',')
# Longitude
LonStr = LonStr.split('d') # Get the degrees, and the rest
LonD = int(LonStr[0])
LonStr = LonStr[1].split('\'')# Get the arc-m, and the rest
LonM = int(LonStr[0])
LonStr = LonStr[1].split('"') # Get the arc-s, and the rest
LonS = float(LonStr[0])
Lon = LonD + LonM/60. + LonS/3600.
if LonStr[1] in ['W', 'w']:
Lon = -1*Lon
# Same for Latitude
LatStr = LatStr.split('d')
LatD = int(LatStr[0])
LatStr = LatStr[1].split('\'')
LatM = int(LatStr[0])
LatStr = LatStr[1].split('"')
LatS = float(LatStr[0])
Lat = LatD + LatM/60. + LatS/3600.
if LatStr[1] in ['S', 's']:
Lat = -1*Lat
return Lat, Lon
FileName = Image.cub
# Mine's an ISIS3 cube file.
CornerLats, CornerLons = GetCornerCoordinates(FileName)
# UpperLeft, LowerLeft, UpperRight, LowerRight, Centre
print CornerLats
print CornerLons
Y eso me da:
[-4.33429444 -5.82895833 -4.33429444 -5.82895833 -5.081625 ]
[ 137.12275833 137.12203333 137.74633889 137.74706111 137.43454722]
Respuestas:
Aquí hay otra forma de hacerlo sin llamar a un programa externo.
Lo que esto hace es obtener las coordenadas de las cuatro esquinas de la geotransformación y reproyectarlas a lon / lat usando osr.CoordinateTransformation.
Parte del código de la metageta proyecto, idea osr.CoordinateTransformation de esta respuesta
fuente
Esto se puede hacer en muchas menos líneas de código
ulx
,uly
es la esquina superior izquierdalrx
,lry
es la esquina inferior derechaLa biblioteca osr (parte de gdal) se puede usar para transformar los puntos en cualquier sistema de coordenadas. Por un solo punto:
Reproyectar una imagen de trama entera sería un asunto mucho más complicado, pero GDAL> = 2.0 ofrece una solución fácil para esto también:
gdal.Warp
.fuente
ST_Transform(ST_SetSRID(ST_MakeBox2D(
[los resultados]),28355),4283)
. (Una objeción: la 'T'src.GetGeoTransform()
debe estar en mayúscula).Lo he hecho de esta manera ... está un poco codificado, pero si nada cambia con el gdalinfo, ¡funcionará para las imágenes proyectadas de UTM!
fuente
gdalinfo
estar disponible en la ruta del usuario (no siempre es el caso, especialmente en Windows) como de analizar una salida impresa que no tiene una interfaz estricta, es decir, confiar en esos 'números mágicos' para un espaciado correcto. No es necesario cuando gdal proporciona enlaces completos de python que pueden hacer esto de una manera más explícita y robustaSi su ráster se gira, entonces las matemáticas se vuelven un poco más complicadas, ya que debe considerar cada uno de los seis coeficientes de transformación afines. Considere usar afín para transformar una transformación afín rotada / geotransformada:
Ahora puede generar los cuatro pares de coordenadas de esquina:
Y si también necesita los límites basados en la cuadrícula (xmin, ymin, xmax, ymax):
fuente
Creo que las versiones más recientes del módulo OSGEO / GDAL para python one pueden llamar directamente a las utilidades GDAL desde el código sin involucrar llamadas al sistema. por ejemplo, en lugar de usar un subproceso para llamar:
gdalinfo se puede llamar a gdal.Info (the_name_of_the_file) para tener una exposición de los metadatos / anotaciones del archivo
o en lugar de usar un subproceso para llamar: gdalwarp se puede llamar a gdal. Warp para realizar la deformación en una trama.
La lista de utilidades GDAL actualmente disponibles como una función interna: http://erouault.blogspot.com/2015/10/gdal-and-ogr-utilities-as-library.html
fuente