Estoy reproyectando rásteres en python usando GDAL. Necesito proyectar varios tiffs desde las coordenadas geográficas WGS 84 a WGS 1984 Web Mercator (esfera auxiliar), para poder usarlos más tarde en Openlayers junto con OpenStreetMap y tal vez los mapas de Google. Estoy usando Python 2.7.5 y GDAL 1.10.1 desde aquí , y transformando coordenadas usando consejos desde aquí (mi código está abajo). En resumen, importé osgeo.osr y usé ImportFromEPSG (código) y CoordinateTransformation (de, a) .
Primero probé EPSG (32629), que es la zona 29 de UTM y obtuve este ráster proyectado (más o menos fino), por lo que el código parece ser correcto: luego usé EPSG (3857) porque leí esto y estas preguntas y encontré que es el código válido reciente correcto . Pero el ráster se crea sin ninguna referencia espacial. Está muy lejos en el marco de datos WGS 84 (pero estará bien si cambio el marco de datos a Web Mercator).
Con EPSG (900913), la salida está georreferenciada, pero se desplaza unas 3 celdas ráster hacia el norte:
Cuando reproyecto el ráster usando ArcGIS (exportar en WGS_1984_Web_Mercator_Auxiliary_Sphere) el resultado es casi bueno:
Y cuando uso el antiguo código 102113 (41001,54004) el resultado es perfecto:
El resumen de mis pruebas con todos los códigos :
3857: far away up (missing georeference)
3785: far away up (like 3857)
3587: far away right
900913: slightly jumped up
102100: python error
102113: perfect
41001: perfect
54004: perfect
ArcGIS (web merc. aux.): good
Entonces mis preguntas son:
- ¿Por qué el código EPSG correcto me da resultados incorrectos?
- ¿Y por qué los viejos códigos funcionan bien, no están en desuso?
- ¿Quizás mi versión GDAL no es buena o tengo errores en mi código de Python?
El código:
yres = round(lons[1]-lons[0], 4) # pixel size, degrees
xres = round(lats[1]-lats[0], 4)
ysize = len(lats)-1 # number of pixels
xsize = len(lons)-1
ulx = round(lons[0], 4)
uly = round(lats[-1], 4) # last
driver = gdal.GetDriverByName(fileformat)
ds = driver.Create(filename, xsize, ysize, 2, gdal.GDT_Float32) # 2 bands
#--- Geographic ---
srs = osr.SpatialReference()
srs.ImportFromEPSG(4326) # Geographic lat/lon WGS 84
ds.SetProjection(srs.ExportToWkt())
gt = [ulx, xres, 0, uly, 0, -yres] # the affine transformation coeffs (ulx, pixel, angle(skew), uly, angle, -pixel)
ds.SetGeoTransform(gt) # coords of top left corner of top left pixel (w-file - center of the pixel!)
outband = ds.GetRasterBand(1)
outband.WriteArray(data)
outband2 = ds.GetRasterBand(2)
outband2.WriteArray(data3)
#--- REPROJECTION ---
utm29 = osr.SpatialReference()
# utm29.ImportFromEPSG(32629) # utm 29
utm29.ImportFromEPSG(900913) # web mercator 3857
wgs84 = osr.SpatialReference()
wgs84.ImportFromEPSG(4326)
tx = osr.CoordinateTransformation(wgs84,utm29)
# Get the Geotransform vector
# Work out the boundaries of the new dataset in the target projection
(ulx29, uly29, ulz29) = tx.TransformPoint(ulx, uly) # corner coords in utm meters
(lrx29, lry29, lrz29) = tx.TransformPoint(ulx + xres*xsize, uly - yres*ysize )
filenameutm = filename[0:-4] + '_web.tif'
dest = driver.Create(filenameutm, xsize, ysize, 2, gdal.GDT_Float32)
xres29 = round((lrx29 - ulx29)/xsize, 2) # pixel size, utm meters
yres29 = abs(round((lry29 - uly29)/ysize, 2))
new_gt = [ulx29, xres29, 0, uly29, 0, -yres29]
dest.SetGeoTransform(new_gt)
dest.SetProjection(utm29.ExportToWkt())
gdal.ReprojectImage(ds, dest, wgs84.ExportToWkt(), utm29.ExportToWkt(), gdal.GRA_Bilinear)
dest.GetRasterBand(1).SetNoDataValue(0.0)
dest.GetRasterBand(2).SetNoDataValue(0.0)
dest = None # Flush the dataset to the disk
ds = None # only after the reprojected!
print 'Image Created'
Respuestas:
Reproyectaría los archivos con
gdalwarp
.He hecho lo mismo para los archivos en EPSG: 3763 que quiero convertir a EPSG: 3857. Comparé los resultados usando QGIS y Geoserver y las imágenes generadas estaban bien. Dado que se aplica una pequeña rotación a las imágenes, puede obtener algunas líneas negras en el borde (pero estas líneas pueden hacerse transparentes después).
Como tiene varias
tif
imágenes, puede usar un script como este que no cambia ningún archivo existente y coloca los archivos generados en una carpeta llamada 3857:Si también desea generar los
.twf
archivos, he agregadolistgeo
.Este script es para Linux, pero puede escribir algo similar para Windows.
fuente
Iría por GDALwarp también. Asegúrese de ser coherente con las interpretaciones de "publicaciones" y "celdas" de los rásteres. http://www.remotesensing.org/geotiff/spec/geotiff2.5.html
fuente