Gibt es eine Möglichkeit, die Eckkoordinaten (in Grad Lat / Long) aus einer Rasterdatei mit den Python-Bindungen von gdal zu ermitteln?
Einige Online-Suchanfragen haben mich davon überzeugt, dass dies nicht der Fall ist. Daher habe ich eine Problemlösung entwickelt, indem ich die gdalinfo-Ausgabe analysiert habe. Sie ist etwas grundlegend, aber ich dachte, dass dies möglicherweise Zeit für Leute spart, die mit Python weniger vertraut sind. Es funktioniert auch nur, wenn gdalinfo die geografischen Koordinaten zusammen mit den Eckkoordinaten enthält, was meines Erachtens nicht immer der Fall ist.
Ist hier meine Problemumgehung, hat jemand bessere Lösungen?
Mit gdalinfo auf einem geeigneten Raster erhalten Sie in der Mitte der Ausgabe etwa Folgendes:
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)
Dieser Code funktioniert für Dateien, deren gdalinfo so aussieht. Ich glaube, dass die Koordinaten manchmal in Grad und Dezimalstellen anstatt in Grad, Minuten und Sekunden angegeben werden. Es sollte trivial sein, den Code für diese Situation anzupassen.
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
Und das gibt mir:
[-4.33429444 -5.82895833 -4.33429444 -5.82895833 -5.081625 ]
[ 137.12275833 137.12203333 137.74633889 137.74706111 137.43454722]
Antworten:
Hier ist eine andere Möglichkeit, ohne ein externes Programm aufzurufen.
Dabei werden die Koordinaten der vier Ecken von der Geotransformation abgerufen und mit osr.CoordinateTransformation in lon / lat neu projiziert.
Einige Code aus dem Metageta- Projekt, osr.CoordinateTransformation Idee aus dieser Antwort
quelle
Dies kann in weitaus weniger Codezeilen erfolgen
ulx
,uly
Ist die obere linke Eckelrx
,lry
ist die rechte untere EckeDie osr-Bibliothek (Teil von gdal) kann verwendet werden, um die Punkte in ein beliebiges Koordinatensystem zu transformieren. Für einen einzelnen Punkt:
Um eine ganze Rasterbild zu projizieren eine weitaus komplizierte Materie wäre, aber GDAL> = 2.0 bietet eine einfache Lösung für diese auch:
gdal.Warp
.quelle
ST_Transform(ST_SetSRID(ST_MakeBox2D(
[die Ergebnisse]),28355),4283)
. (Ein Streitpunkt - das 'T' insrc.GetGeoTransform()
sollte groß geschrieben werden).Ich habe es so gemacht ... es ist ein wenig hartcodiert, aber wenn sich nichts an der gdalinfo ändert, funktioniert es für UTM-projizierte Bilder!
quelle
gdalinfo
die Verfügbarkeit auf dem Pfad eines Benutzers (was insbesondere unter Windows nicht immer der Fall ist) als auch eine gedruckte Ausgabe ohne strenge Schnittstelle analysiert werden, dh dass für den korrekten Abstand diese "magischen Zahlen" verwendet werden. Es ist unnötig, wenn gdal umfassende Python-Bindungen bereitstellt, die dies auf eine explizitere und robustere Weise tun könnenWenn Ihr Raster gedreht wird, wird die Berechnung etwas komplizierter, da Sie jeden der sechs affinen Transformationskoeffizienten berücksichtigen müssen. Erwägen Sie die Verwendung von affin, um eine gedrehte affine Transformation / Geotransformation zu transformieren:
Jetzt können Sie die vier Eckkoordinatenpaare erzeugen:
Und wenn Sie auch die gitterbasierten Grenzen benötigen (xmin, ymin, xmax, ymax):
quelle
Ich glaube an neuere Versionen des OSGEO / GDAL-Moduls für Python, mit dem man GDAL-Dienstprogramme direkt aus dem Code aufrufen kann, ohne dass Systemaufrufe erforderlich sind. Beispiel: Anstatt einen Unterprozess zum Aufrufen zu verwenden:
gdalinfo kann mit gdal.Info (der_Dateiname) aufgerufen werden, um die Metadaten / Anmerkungen der Datei anzuzeigen
Anstatt den Unterprozess zum Aufrufen von: gdalwarp zu verwenden, können Sie gdal.Warp aufrufen, um das Warping für ein Raster auszuführen.
Die Liste der derzeit als interne Funktion verfügbaren GDAL-Dienstprogramme: http://erouault.blogspot.com/2015/10/gdal-and-ogr-utilities-as-library.html
quelle