Saya memproyeksikan ulang raster dalam python menggunakan GDAL. Saya perlu memproyeksikan beberapa tiff dari koordinat geografis WGS 84 ke WGS 1984 Web Mercator (Auxiliary Sphere), untuk menggunakannya nanti di Openlayers bersama dengan OpenStreetMap dan mungkin Google maps. Saya menggunakan Python 2.7.5 dan GDAL 1.10.1 dari sini , dan mengubah koordinat menggunakan saran dari sini (kode saya di bawah). Singkatnya, saya mengimpor osgeo.osr dan menggunakan ImportFromEPSG (kode) dan CoordinateTransformation (dari, ke) .
Saya pertama kali mencoba EPSG (32629) yang merupakan zona UTM 29 dan mendapatkan raster yang diproyeksikan ini (kurang lebih baik), jadi kodenya tampaknya benar: Kemudian saya menggunakan EPSG (3857) karena saya sudah membaca ini dan ini pertanyaan dan menemukan bahwa itu adalah kode valid terbaru yang benar . Tetapi raster dibuat tanpa referensi spasial sama sekali. Itu jauh di bingkai data WGS 84 (tapi akan baik-baik saja jika saya beralih bingkai data ke Web Mercator).
Dengan EPSG (900913) output di-georeferensi, tetapi bergeser sekitar 3 sel raster ke utara:
Ketika saya memproyeksikan ulang raster menggunakan ArcGIS (ekspor di WGS_1984_Web_Mercator_Auxiliary_Sphere) hasilnya hampir baik:
Dan ketika saya menggunakan kode lama 102113 (41001.54004) hasilnya sempurna:
Ringkasan tes saya menggunakan semua kode :
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
Jadi pertanyaan saya adalah:
- Mengapa kode EPSG yang benar memberi saya hasil yang salah?
- Dan mengapa kode lama berfungsi dengan baik, bukankah itu sudah usang?
- Mungkin versi GDAL saya tidak baik atau saya memiliki kesalahan dalam kode python saya?
Kode:
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'