Czy istnieje sposób na uzyskanie współrzędnych narożnych (w stopniach lat / long) z pliku rastrowego za pomocą powiązań Pythona gdal?
Kilka wyszukiwań w Internecie przekonało mnie, że tak nie jest, więc opracowałem rozwiązanie, analizując dane wyjściowe gdalinfo, jest to nieco podstawowe, ale pomyślałem, że może zaoszczędzić trochę czasu dla ludzi, którzy mogą czuć się mniej komfortowo z pythonem. Działa również tylko wtedy, gdy gdalinfo zawiera współrzędne geograficzne wraz ze współrzędnymi narożnymi, co nie wydaje mi się, że zawsze tak jest.
Oto moje obejście, czy ktoś ma jakieś lepsze rozwiązania?
gdalinfo na odpowiednim rastrze daje wynik podobny do tego w połowie wyniku:
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)
Ten kod będzie działał na plikach, które tak wyglądają gdalinfo. Wierzę, że czasami współrzędne będą podawane w stopniach i dziesiętnych, a nie w stopniach, minutach i sekundach; dostosowanie kodu do takiej sytuacji powinno być trywialne.
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
A to daje mi:
[-4.33429444 -5.82895833 -4.33429444 -5.82895833 -5.081625 ]
[ 137.12275833 137.12203333 137.74633889 137.74706111 137.43454722]
Odpowiedzi:
Oto inny sposób, aby to zrobić bez wywoływania programu zewnętrznego.
W ten sposób uzyskuje się współrzędne czterech rogów z geotransformy i ponownie rzutuje je na długość / długość za pomocą osr.CoordinateTransformation.
Niektóre kod z metageta projektu osr.CoordinateTransformation pomysł z tą odpowiedź
źródło
Można to zrobić w znacznie mniejszej liczbie wierszy kodu
ulx
,uly
to lewy górny róglrx
,lry
to prawy dolny rógBiblioteki osr (część gdal) można użyć do przekształcenia punktów w dowolny układ współrzędnych. Dla jednego punktu:
Aby odwzorować cały obraz rastrowy będzie o wiele bardziej skomplikowana sprawa, ale GDAL> = 2.0 oferuje proste rozwiązanie dla tego też:
gdal.Warp
.źródło
ST_Transform(ST_SetSRID(ST_MakeBox2D(
[wyniki]),28355),4283)
to. (Jeden spór - litera „T”src.GetGeoTransform()
powinna być pisana wielkimi literami).Zrobiłem w ten sposób ... jest trochę zakodowany, ale jeśli nic nie zmieni się z gdalinfo, będzie działać dla obrazów wyświetlanych w UTM!
źródło
gdalinfo
byciu dostępnym na ścieżce użytkownika (nie zawsze tak jest, szczególnie w systemie Windows), jak i na analizowaniu wydruków, które nie mają ścisłego interfejsu - tj. Polegając na tych „magicznych liczbach” dla poprawnego odstępu. Nie jest konieczne, gdy gdal zapewnia kompleksowe wiązania Pythona, które mogą to zrobić w bardziej wyraźny i niezawodny sposóbJeśli twój raster jest obrócony, matematyka staje się nieco bardziej skomplikowana, ponieważ musisz wziąć pod uwagę każdy z sześciu współczynników transformacji afinicznej. Rozważ użycie afinii do przekształcenia obróconej transformacji afinicznej / geotransform:
Teraz możesz wygenerować cztery pary współrzędnych narożnych:
A jeśli potrzebujesz również granic opartych na siatce (xmin, ymin, xmax, ymax):
źródło
Wierzę, że w nowszych wersjach modułu OSGEO / GDAL dla pytona można bezpośrednio wywoływać narzędzia GDAL z kodu bez angażowania wywołań systemowych. na przykład zamiast używać podprocesu do wywoływania:
gdalinfo można wywołać gdal.Info (nazwa_pliku), aby uzyskać dostęp do metadanych / adnotacji pliku
lub zamiast używać podprocesu do wywoływania: gdalwarp, możesz cal gdal.Warp zrobić wypaczenie na rastrze.
Lista narzędzi GDAL dostępnych obecnie jako funkcja wewnętrzna: http://erouault.blogspot.com/2015/10/gdal-and-ogr-utilities-as-library.html
źródło