Raster georeferencji za pomocą GDAL i Pythona?

10

Chcę georeferencję rastra za pomocą pythoni GDAL. Moje obecne podejście polega na dzwonieniu gdal_translatei gdalwarpkorzystaniu os.systemz brzydkiej listy punktów kontroli naziemnej. Naprawdę chciałbym zrobić to w sposób natywny python.

To jest obecny proces, którego używam:

import os

os.system('gdal_translate -of GTiff -gcp 1251.92 414.538 -7.9164e+06 5.21094e+06 -gcp 865.827 107.699 -7.91651e+06 5.21104e+06  "inraster.tif" "outraster1.tif"')
os.system('gdalwarp -r bilinear -tps -co COMPRESS=NONE "outraster2.tif" "outraster3.tif"')

Istnieje poprzednie pytanie i odpowiedź z 2012 roku, które stwierdzają, że gdal_translatemożna uzyskać do niej dostęp po zaimportowaniu gdal. Nie jestem pewien, czy jest przestarzały lub czy jest zły, ale kiedy uruchamiam from osgeo import gdal, nie widzę gdal.gdal_translateopcji.

Nie wiem, czy istnieje, ale bardzo bym chciała tłumaczyć i wyrzucać rastry w pythoniczny sposób. Na przykład:

# translate
gcp_points = [(1251.92, 414.538), (-7.9164e+06, 5.21094e+06)]
gdal.gdal_translate(in_raster, gcp_points, out_raster1)

# warp
gdal.gdalwarp(out_raster1, out_raster2, 'bilinear', args*)

Czy takie podejście jest możliwe?

djq
źródło
1
gdal_translate i gdalwarp oraz inne narzędzia gdal nie są pakietami / modułami Pythona, są samodzielnymi plikami wykonywalnymi. Możesz do nich wywołać system os.system lub (najlepiej) podproces. Otwórz.
user2856
@Luke, więc czy nie ma sposobu na interakcję z tymi narzędziami gdal? Z przyjemnością zbadam, jak napisać dla nich opakowanie Pythona, jeśli takie nie istnieje.
djq
Możesz użyć interfejsu API gdal python, aby zrobić prawie wszystko, co mogą zrobić narzędzia gdal_translate i gdalwarp, jest to tylko trochę bardziej skomplikowane. Sprawdź gdal.AutoCreateWarpedVRT i gdal Driver.CreateCopy.
user2856

Odpowiedzi:

17

Oto przykład, który robi mniej więcej to, o co prosisz. Główne parametry to geotransformtablica, której używa gdal do opisania położenia rastra (pozycja, skala pikseli i pochylenie) oraz epsgkod projekcji. Dzięki temu poniższy kod powinien poprawnie georeferencyjnie raster i określić jego rzut.

Nie testowałem zbyt wiele, ale wydawało mi się, że to działa. Musisz upewnić się, że współrzędne, które wprowadzam, są prawidłowe i prawdopodobnie zmienisz rzut oraz skalę / rozmiar piksela. Mam nadzieję, że to pomoże.

from osgeo import gdal, osr

src_filename ='/path/to/source.tif'
dst_filename = '/path/to/destination.tif'

# Opens source dataset
src_ds = gdal.Open(src_filename)
format = "GTiff"
driver = gdal.GetDriverByName(format)

# Open destination dataset
dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

# Specify raster location through geotransform array
# (uperleftx, scalex, skewx, uperlefty, skewy, scaley)
# Scale = size of one pixel in units of raster projection
# this example below assumes 100x100
gt = [-7916400, 100, 0, 5210940, 0, -100]

# Set location
dst_ds.SetGeoTransform(gt)

# Get raster projection
epsg = 3857
srs = osr.SpatialReference()
srs.ImportFromEPSG(epsg)
dest_wkt = srs.ExportToWkt()

# Set projection
dst_ds.SetProjection(dest_wkt)

# Close files
dst_ds = None
src_ds = None
żółta czapka
źródło
2
To prawda, ale jeśli chcesz być bardziej dokładny, w przypadku rotacji musisz użyć transformacji afinicznej i obliczyć odpowiednie parametry za pomocą pakietu afinicznego ( pobierz tutaj ). Zastosowanie: „Affine.scale (PARAMETER) * Affine.rotation (ANGLE)”. PARAMETRY pochodzą ze współczynnika pikseli dwóch obrazów, możesz użyć „gdalinfo” lub PIL, aby poznać rozmiar pikseli, KĄT to kąt.
CaMa