Saya mencoba memproyeksikan ulang / melakukan resample dengan GDAL python bindings, tetapi saya mendapatkan hasil yang sedikit berbeda dibandingkan dengan yang ada di utilitas baris perintah gdalwarp
.
Lihat pembaruan di bawah untuk contoh yang lebih pendek
Script ini menggambarkan pendekatan Python:
from osgeo import osr, gdal
import numpy
def reproject_point(point, srs, target_srs):
'''
Reproject a pair of coordinates from one spatial reference system to
another.
'''
transform = osr.CoordinateTransformation(srs, target_srs)
(x, y, z) = transform.TransformPoint(*point)
return (x, y)
def reproject_bbox(top_left, bottom_right, srs, dest_srs):
x_min, y_max = top_left
x_max, y_min = bottom_right
corners = [
(x_min, y_max),
(x_max, y_max),
(x_max, y_min),
(x_min, y_min)]
projected_corners = [reproject_point(crnr, srs, dest_srs)
for crnr in corners]
dest_top_left = (min([crnr[0] for crnr in projected_corners]),
max([crnr[1] for crnr in projected_corners]))
dest_bottom_right = (max([crnr[0] for crnr in projected_corners]),
min([crnr[1] for crnr in projected_corners]))
return dest_top_left, dest_bottom_right
################################################################################
# Create synthetic data
gtiff_drv = gdal.GetDriverByName('GTiff')
w, h = 512, 512
raster = numpy.zeros((w, h), dtype=numpy.uint8)
raster[::w / 10, :] = 255
raster[:, ::h / 10] = 255
top_left = (-109764, 215677)
pixel_size = 45
src_srs = osr.SpatialReference()
src_srs.ImportFromEPSG(3413)
src_geotran = [top_left[0], pixel_size, 0,
top_left[1], 0, -pixel_size]
rows, cols = raster.shape
src_ds = gtiff_drv.Create(
'test_epsg3413.tif',
cols, rows, 1,
gdal.GDT_Byte)
src_ds.SetGeoTransform(src_geotran)
src_ds.SetProjection(src_srs.ExportToWkt())
src_ds.GetRasterBand(1).WriteArray(raster)
################################################################################
# Reproject to EPSG: 3573 and upsample to 7m
dest_pixel_size = 7
dest_srs = osr.SpatialReference()
dest_srs.ImportFromEPSG(3573)
# Calculate new bounds by re-projecting old corners
x_min, y_max = top_left
bottom_right = (x_min + cols * pixel_size,
y_max - rows * pixel_size)
dest_top_left, dest_bottom_right = reproject_bbox(
top_left, bottom_right,
src_srs, dest_srs)
# Make dest dataset
x_min, y_max = dest_top_left
x_max, y_min = dest_bottom_right
new_rows = int((x_max - x_min) / float(dest_pixel_size))
new_cols = int((y_max - y_min) / float(dest_pixel_size))
dest_ds = gtiff_drv.Create(
'test_epsg3573.tif',
new_rows, new_cols, 1,
gdal.GDT_Byte)
dest_geotran = (dest_top_left[0], dest_pixel_size, 0,
dest_top_left[1], 0, -dest_pixel_size)
dest_ds.SetGeoTransform(dest_geotran)
dest_ds.SetProjection(dest_srs.ExportToWkt())
# Perform the projection/resampling
gdal.ReprojectImage(
src_ds, dest_ds,
src_srs.ExportToWkt(), dest_srs.ExportToWkt(),
gdal.GRA_NearestNeighbour)
dest_data = dest_ds.GetRasterBand(1).ReadAsArray()
# Close datasets
src_ds = None
dest_ds = None
Bandingkan dengan output dari:
gdalwarp -s_srs EPSG:3413 -t_srs EPSG:3573 -tr 7 7 -r near -of GTiff test_epsg3413.tif test_epsg3573_gdalwarp.tif
Mereka berbeda dalam ukuran (oleh 2 baris dan 1 kolom) serta dengan beberapa nilai piksel yang berbeda di dekat tepi.
Lihat overlay transparan test_epsg3573.tif dan test_epsg3573_gdalwarp.tif di bawah ini. Jika gambar identik, hanya akan ada piksel hitam dan putih, tidak ada abu-abu.
Diuji dengan Python 2.7.8, GDAL 1.11.1, Numpy 1.9.1
Perbarui :
Ini adalah contoh yang jauh lebih pendek. Ini tampaknya tidak disebabkan oleh upsampling karena yang berikut ini juga menghasilkan hasil yang tidak konsistengdalwarp
from osgeo import osr, gdal
import numpy
# Create synthetic data
gtiff_drv = gdal.GetDriverByName('GTiff')
w, h = 512, 512
raster = numpy.zeros((w, h), dtype=numpy.uint8)
raster[::w / 10, :] = 255
raster[:, ::h / 10] = 255
top_left = (-109764, 215677)
pixel_size = 45
src_srs = osr.SpatialReference()
src_srs.ImportFromEPSG(3413)
src_geotran = [top_left[0], pixel_size, 0,
top_left[1], 0, -pixel_size]
rows, cols = raster.shape
src_ds = gtiff_drv.Create(
'test_epsg3413.tif',
cols, rows, 1,
gdal.GDT_Byte)
src_ds.SetGeoTransform(src_geotran)
src_ds.SetProjection(src_srs.ExportToWkt())
src_ds.GetRasterBand(1).WriteArray(raster)
# Reproject to EPSG: 3573
dest_srs = osr.SpatialReference()
dest_srs.ImportFromEPSG(3573)
int_ds = gdal.AutoCreateWarpedVRT(src_ds, src_srs.ExportToWkt(), dest_srs.ExportToWkt())
# Make dest dataset
dest_ds = gtiff_drv.Create(
'test_epsg3573_avrt.tif',
int_ds.RasterXSize, int_ds.RasterYSize, 1,
gdal.GDT_Byte)
dest_ds.SetGeoTransform(int_ds.GetGeoTransform())
dest_ds.SetProjection(int_ds.GetProjection())
dest_ds.GetRasterBand(1).WriteArray(int_ds.GetRasterBand(1).ReadAsArray())
# Close datasets
src_ds = None
dest_ds = None
Dan ini adalah panggilan gdalwarp yang saya harapkan sama, namun tidak:
gdalwarp -s_srs EPSG:3413 -t_srs EPSG:3573 -of GTiff test_epsg3413.tif test_epsg3573_gdalwarp.tif
Gambar di bawah ini menunjukkan masing-masing gambar biner yang dihasilkan overlay pada transparansi 50%. Pixel abu-abu terang adalah inkonsistensi antara dua hasil.
gdal.AutoCreateWarpedVRT(source_file, source_srs_wkt, dest_srs_wkt)
?