Python GDAL: Menulis raster baru menggunakan proyeksi dari yang lama

8

Jika saya membaca dalam gambar raster sebagai array, kemudian membuat beberapa perubahan pada nilai-nilai dalam array, bagaimana cara menyimpan array sebagai raster dengan informasi proyeksi yang sama dengan array asli?

Khususnya saya sedang melakukan pemrosesan pada beberapa kubus ISIS3 dari Mars. Ini tidak diproyeksikan di salah satu opsi SetWellKnownGeogCS yang bagus. Mungkin ini membuat masalah saya agak tidak biasa, tetapi saya pikir layak mendokumentasikan solusi saya semua sama.

EddyTheB
sumber

Jawaban:

16

Ini adalah rutinitas yang saya kembangkan untuk mengubah kubus ISIS3 menjadi GTiffs. Saya berharap pendekatan yang sama harus bekerja di antara semua jenis driver (meskipun saya pikir metode driver.Create () mungkin membatasi pilihan file output).

import numpy as np
import gdal
from gdalconst import *
from osgeo import osr

# Function to read the original file's projection:
def GetGeoInfo(FileName):
    SourceDS = gdal.Open(FileName, GA_ReadOnly)
    NDV = SourceDS.GetRasterBand(1).GetNoDataValue()
    xsize = SourceDS.RasterXSize
    ysize = SourceDS.RasterYSize
    GeoT = SourceDS.GetGeoTransform()
    Projection = osr.SpatialReference()
    Projection.ImportFromWkt(SourceDS.GetProjectionRef())
    DataType = SourceDS.GetRasterBand(1).DataType
    DataType = gdal.GetDataTypeName(DataType)
    return NDV, xsize, ysize, GeoT, Projection, DataType

# Function to write a new file.
def CreateGeoTiff(Name, Array, driver, NDV, 
                  xsize, ysize, GeoT, Projection, DataType):
    if DataType == 'Float32':
        DataType = gdal.GDT_Float32
    NewFileName = Name+'.tif'
    # Set nans to the original No Data Value
    Array[np.isnan(Array)] = NDV
    # Set up the dataset
    DataSet = driver.Create( NewFileName, xsize, ysize, 1, DataType )
            # the '1' is for band 1.
    DataSet.SetGeoTransform(GeoT)
    DataSet.SetProjection( Projection.ExportToWkt() )
    # Write the array
    DataSet.GetRasterBand(1).WriteArray( Array )
    DataSet.GetRasterBand(1).SetNoDataValue(NDV)
    return NewFileName

# Open the original file
FileName = 'I29955002trim.cub'    # This is the ISIS3 cube file
                                  # It's an infra-red photograph
                                  # taken by the 2001 Mars Odyssey orbiter.
DataSet = gdal.Open(FileName, GA_ReadOnly)
# Get the first (and only) band.
Band = DataSet.GetRasterBand(1)
# Open as an array.
Array = Band.ReadAsArray()
# Get the No Data Value
NDV = Band.GetNoDataValue()
# Convert No Data Points to nans
Array[Array == NDV] = np.nan

# Now I do some processing on Array, it's pretty complex 
# but for this example I'll just add 20 to each pixel.
NewArray = Array + 20  # If only it were that easy

# Now I'm ready to save the new file, in the meantime I have 
# closed the original, so I reopen it to get the projection
# information...
NDV, xsize, ysize, GeoT, Projection, DataType = GetGeoInfo(FileName)

# Set up the GTiff driver
driver = gdal.GetDriverByName('GTiff')

# Now turn the array into a GTiff.
NewFileName = CreateGeoTiff('I29955002trim', NewArray, driver, NDV, 
                            xsize, ysize, GeoT, Projection, DataType)

Dan itu saja. Saya dapat membuka kedua gambar di QGIS. Dan gdalinfo di kedua file menunjukkan bahwa saya memiliki informasi proyeksi dan georeferensi yang sama.

EddyTheB
sumber
1
Sepertinya PyGDAL telah beralih dari menggunakan string untuk hal-hal seperti tipe data, dan menggunakan Nilai Tidak untuk Tanpa Data. Perlu men-tweak beberapa hal di sini.
Ahmed Fasih