def obj_to_rst(inArray, outRst, template, noData=None, geotrans=None): """ Send Array to Raster API Available: * gdal; """ gisApi = 'gdal' if gisApi == 'gdal': from osgeo import gdal, osr, gdal_array from gasp.gt.prop.ff import drv_name from gasp.gt.prop.rst import compress_option if type(template).__name__ == 'Dataset': img_template = template else: img_template = gdal.Open(template) geo_transform = img_template.GetGeoTransform() if not geotrans else \ geotrans rows, cols = inArray.shape drv_n = drv_name(outRst) driver = gdal.GetDriverByName(drv_n) c_opt = compress_option(drv_n) if c_opt: out = driver.Create(outRst, cols, rows, 1, gdal_array.NumericTypeCodeToGDALTypeCode( inArray.dtype), options=[c_opt]) else: out = driver.Create( outRst, cols, rows, 1, gdal_array.NumericTypeCodeToGDALTypeCode(inArray.dtype)) out.SetGeoTransform(geo_transform) outBand = out.GetRasterBand(1) if noData: outBand.SetNoDataValue(noData) outBand.WriteArray(inArray) proj = osr.SpatialReference(wkt=img_template.GetProjection()) if proj: out.SetProjection(img_template.GetProjection()) outBand.FlushCache() else: raise ValueError('The api {} is not available'.format(gisApi)) return outRst
def obj_to_rst(inArray, outRst, template, noData=None, geotrans=None): """ Send Array to Raster """ from osgeo import gdal, osr, gdal_array from glass.g.prop import drv_name from glass.g.prop.rst import compress_option if type(template).__name__ == 'Dataset': img_template = template else: img_template = gdal.Open(template) geo_transform = img_template.GetGeoTransform() if not geotrans else \ geotrans rows, cols = inArray.shape drv_n = drv_name(outRst) driver = gdal.GetDriverByName(drv_n) c_opt = compress_option(drv_n) if c_opt: out = driver.Create(outRst, cols, rows, 1, gdal_array.NumericTypeCodeToGDALTypeCode( inArray.dtype), options=[c_opt]) else: out = driver.Create( outRst, cols, rows, 1, gdal_array.NumericTypeCodeToGDALTypeCode(inArray.dtype)) out.SetGeoTransform(geo_transform) outBand = out.GetRasterBand(1) if noData or noData == 0: outBand.SetNoDataValue(noData) outBand.WriteArray(inArray) proj = osr.SpatialReference(wkt=img_template.GetProjection()) if proj: out.SetProjection(img_template.GetProjection()) outBand.FlushCache() return outRst
def open(self, file=None, dtype=None): """ Open a local file handle for reading and assignment :param file: :return: None """ # args[0]/file= if file is None: raise IndexError("invalid file= argument provided") # grab raster meta information from GeoRasters try: self.ndv, self.x_cell_size, self.y_cell_size, self.geot, self.projection, self.dtype = \ get_geo_info(file) except Exception: raise AttributeError("problem processing file input -- is this", "a raster file?") # args[1]/dtype= if dtype is not None: # override our shadow'd value from GeoRasters if # something was specified by the user self.dtype = dtype # re-cast our datatype as a numpy type, if needed if type(self.dtype) == str: self.dtype = NUMPY_TYPES[self.dtype.lower()] if self.ndv is None: self.ndv = _DEFAULT_NA_VALUE # low-level call to gdal with explicit type specification # that will store in memory or as a disc cache, depending # on the state of our _using_disc_caching property if self._using_disc_caching is not None: # create a cache file self.array = np.memmap(self._using_disc_caching, dtype=dtype, mode='w+', shape=(_x_size, _y_size)) # load file contents into the cache self.array[:] = gdalnumeric.LoadFile( filename=self.filename, buf_type=gdal_array.NumericTypeCodeToGDALTypeCode( self.dtype))[:] # by default, load the whole file into memory else: self.array = gdalnumeric.LoadFile( filename=self.filename, buf_type=gdal_array.NumericTypeCodeToGDALTypeCode(self.dtype)) # make sure we honor our no data value self.array = np.ma.masked_array(self.array, mask=self.array == self.ndv, fill_value=self.ndv)
def stretch(src, dst, stretch, bands, ndv, minmax, pct, _format, dtype, co, verbose): # Read input image try: ds = gdal.Open(src, gdal.GA_ReadOnly) except: click.echo("Could not open source dataset {0}".format(src)) raise driver = gdal.GetDriverByName(str(_format)) # If no output dtype selected, default to input image dtype if not dtype: dtype = gdal_array.GDALTypeCodeToNumericTypeCode( ds.GetRasterBand(1).DataType) dtype = np.dtype(dtype) gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(dtype) if not bands: nbands = ds.RasterCount bands = range(1, nbands + 1) else: nbands = len(bands) # Create output if _format.lower() in COPY_FORMATS: if nbands not in (1, 3, 4): raise click.BadParameter( 'JPEG/PNG images must have 1, 3, or 4 bands') mem_driver = gdal.GetDriverByName('MEM') out_ds = mem_driver.Create('', ds.RasterXSize, ds.RasterYSize, nbands, gdal_dtype) else: out_ds = driver.Create(dst, ds.RasterXSize, ds.RasterYSize, nbands, gdal_dtype) for idx, (b, _minmax) in enumerate(zip_longest(bands, minmax)): kwargs = dict(ndv=ndv, minmax=_minmax, percent=pct) in_band = ds.GetRasterBand(b) arr = in_band.ReadAsArray() arr, out_ndv = _STRETCH_FUNCS[stretch](arr, **kwargs) out_band = out_ds.GetRasterBand(idx + 1) out_band.WriteArray(arr) out_band.SetDescription(in_band.GetDescription()) out_band.SetNoDataValue(out_ndv) out_ds.SetMetadata(ds.GetMetadata()) out_ds.SetProjection(ds.GetProjection()) out_ds.SetGeoTransform(ds.GetGeoTransform()) if _format.lower() in COPY_FORMATS: _out_ds = driver.CreateCopy(dst, out_ds, 0, co) _out_ds = None ds = None out_ds = None if verbose: click.echo('Complete!')
def write_geotiff(out_file, in_arr, geotran, srs_wkt): """ in_arr must be in channels, rows, cols """ driver = gdal.GetDriverByName('GTiff') if in_arr.dtype == np.uint64 or in_arr.dtype == np.int64: in_arr = in_arr.astype(float) type_code = gdal_array.NumericTypeCodeToGDALTypeCode(in_arr.dtype) # get the numpy array data type if len(in_arr.shape) == 3: # if the shape is (bands, rows, columns) out = driver.Create(out_file, in_arr.shape[2], in_arr.shape[1], in_arr.shape[0], type_code) out.SetGeoTransform(geotran) for b in range(in_arr.shape[0]): outband = out.GetRasterBand(b+1) outband.WriteArray(in_arr[b]) outband.FlushCache() elif len(in_arr.shape) == 4: nbands = np.prod([n for n in in_arr.shape[:-2]]) out = driver.Create(out_file, in_arr.shape[-1], in_arr.shape[-2], int(nbands), type_code) out.SetGeoTransform(geotran) b = 1 for b1 in range(in_arr.shape[0]): for b2 in range(in_arr.shape[1]): outband = out.GetRasterBand(b) outband.WriteArray(in_arr[b1,b2,:,:]) outband.FlushCache() b+=1 else: out = driver.Create(out_file, in_arr.shape[1], in_arr.shape[0], 1, type_code) out.SetGeoTransform(geotran) # the origin is the upper left of the input shapefile outband = out.GetRasterBand(1) outband.WriteArray(in_arr) outband.FlushCache() out.SetProjection(srs_wkt)
def test_datatypes(self): datatypes = [ np.uint8, np.int8, np.uint16, np.int16, np.uint32, np.int32, np.float32, np.float64 ] npix_x = 100 npix_y = 80 nbands = 1 output_fname = "/tmp/test_geotiff.tif" geot = [0, 1, 0, 0, 0, -1] for datatype in datatypes: image_data = image_utils.create_uniform_image_data(npix_x, npix_y, nbands, dtype=datatype) gtiff_image = ImageFactory.geotiff.from_numpy_array( image_data, geot, crs_defs.PROJ_4326) gtiff_image.write_to_disk(output_fname) gtiff_image_from_file = ImageFactory.geotiff.from_file( output_fname) gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(datatype) assert gtiff_image.get_metadata().get_gdal_datatype( ) == gtiff_image_from_file.get_metadata().get_gdal_datatype( ) == gdal_dtype print("datatype tests passed")
def NumPyArrayToRaster(nparr, proj, geot, nodata_value, out_raster_path, dtype=None): gdal.AllRegister() np_dt = nparr.dtype if dtype == None: dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np_dt) print( "saving") # Check if working with multiband raster if len(nparr.shape) == 3: n_bands = nparr.shape[0] for x in range(0, n_bands): driver = gdal.GetDriverByName('GTIFF') outDs = driver.Create(out_raster_path, nparr.shape[2], nparr.shape[1], n_bands, dtype, ['COMPRESS=LZW', 'TILED=YES', 'BLOCKXSIZE=128', 'BLOCKYSIZE=128']) outDs.GetRasterBand(x + 1).WriteArray(nparr[x]) outDs.GetRasterBand(x + 1).SetNoDataValue(nodata_value) outDs.GetRasterBand(x + 1).FlushCache() outDs.SetProjection(proj) outDs.SetGeoTransform(geot) outDs = None else: driver = gdal.GetDriverByName('GTIFF') outDs = driver.Create(out_raster_path, nparr.shape[1], nparr.shape[0], 1, dtype, ['COMPRESS=LZW', 'TILED=YES', 'BLOCKXSIZE=128', 'BLOCKYSIZE=128']) outDs.GetRasterBand(1).WriteArray(nparr) outDs.GetRasterBand(1).SetNoDataValue(nodata_value) outDs.GetRasterBand(1).FlushCache() outDs.SetProjection(proj) outDs.SetGeoTransform(geot) outDs = None
def create_dataset(geometry, cellsize, fillvalue, dtype, path): """ The big sparse target dateset""" # properties a, b, c, d = cellsize[0], 0.0, 0.0, -cellsize[1] x1, x2, y1, y2 = geometry.GetEnvelope() p, q = a * (x1 // a), d * (y2 // d) width = -int((p - x2) // a) height = -int((q - y1) // d) geo_transform = p, a, b, q, c, d projection = geometry.GetSpatialReference().ExportToWkt() # data type from store, no data value max of that type data_type = gdal_array.NumericTypeCodeToGDALTypeCode(dtype) no_data_value = fillvalue # create options = [ 'TILED=YES', 'BIGTIFF=YES', 'SPARSE_OK=TRUE', 'COMPRESS=DEFLATE' ] dataset = DRIVER_GDAL_GTIFF.Create( path, width, height, 1, data_type, options, ) dataset.SetProjection(projection) dataset.SetGeoTransform(geo_transform) dataset.GetRasterBand(1).SetNoDataValue(no_data_value) return dataset
def _create_geotiff(filePath, binary, ripDic, metadataDic): x = int(ripDic["FT_DATASET_ROWS"]) y = int(ripDic["FT_DATASET_COLUMNS"]) # thirdVal's value in the 'Affine GeoTransform' relationship is multiplied by a coefficient of 0, so we always expect it to be zero. Same with fifthVal # In case this ever changes, we set them here rather than using magic numbers thirdVal = 0 fifthVal = 0 upperLeft = ripDic["FT_DATASET_GRID_UPPER_LEFT_XY"] yMax = float(ripDic["FT_DATASET_GEOG_NORTH_BOUND_LATITUDE"]) yMin = float(ripDic["FT_DATASET_GEOG_SOUTH_BOUND_LATITUDE"]) xMin = float(ripDic["FT_DATASET_GEOG_WEST_BOUND_LONGITUDE"]) xMax = float(ripDic["FT_DATASET_GEOG_EAST_BOUND_LONGITUDE"]) xRes = (xMax - xMin) / float(x) yRes = (yMax - yMin) / float(y) numberBands = 1 # EASEGRID Global EPSG = 3410 # create geoTransform in accordance with relationship described at https://gdal.org/user/raster_data_model.html#affine-geotransform geoTransform = (xMin, xRes, thirdVal, yMax, fifthVal, -yRes) gdalType = gdal_array.NumericTypeCodeToGDALTypeCode(binary.dtype) geoTiff = gdal.GetDriverByName('GTiff').Create(filePath, y, x, numberBands, gdalType) geoTiff.SetGeoTransform(geoTransform) srs = osr.SpatialReference() srs.ImportFromEPSG(EPSG) geoTiff.SetProjection(srs.ExportToWkt()) geoTiff.GetRasterBand(1).WriteArray(binary) geoTiff.FlushCache() return
def create_geotiff(suffix, Array, NDV, xsize, ysize, GeoT, Projection): ''' Creates new GeoTiff from array ''' DataType = gdal_array.NumericTypeCodeToGDALTypeCode(Array.dtype) if type(DataType) != np.int: if DataType.startswith('gdal.GDT_') == False: DataType = eval('gdal.GDT_' + DataType) NewFileName = suffix + '.tif' zsize = Array.shape[0] # create a driver driver = gdal.GetDriverByName('GTiff') # Set nans to the original No Data Value Array[np.isnan(Array)] = NDV # Set up the dataset with zsize bands DataSet = driver.Create(NewFileName, xsize, ysize, zsize, DataType) DataSet.SetGeoTransform(GeoT) DataSet.SetProjection(Projection.ExportToWkt()) # Write each slice of the array along the zsize for i in xrange(0, zsize): DataSet.GetRasterBand(i + 1).WriteArray(Array[i]) DataSet.GetRasterBand(i + 1).SetNoDataValue(NDV) DataSet.FlushCache() return NewFileName
def array_to_raster(array, tx, prj, driver, out_path, dtype=None, nodata=None, silent=False): # From intersectMask.py ''' Save a numpy array as a new raster ''' if not silent: print 'Saving raster...' rows, cols = array.shape # Save new raster if not dtype: np_dtype = get_min_numpy_dtype(array) array = array.astype(np_dtype) dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np_dtype) if driver.ShortName == 'GTiff': out_ds = driver.Create(out_path, cols, rows, 1, dtype, ['TILED=YES']) else: out_ds = driver.Create(out_path, cols, rows, 1, dtype) if not out_ds: import pdb; pdb.set_trace() raise IOError('\nCould not create ' + out_path) # Write the data band = out_ds.GetRasterBand(1) band.WriteArray(array) # Flush data to disk band.FlushCache() if nodata != None: band.SetNoDataValue(nodata) # Georeference the image and set the projection out_ds.SetGeoTransform(tx) out_ds.SetProjection(prj) if not silent: print 'Raster written to:\n', out_path
def array2geotiff(array, outfile_name, no_data_value, xsize, ysize, originX, originY, pixelWidth, pixelHeight, compression='LZW'): """ This function writes a numpy array into a GeoTIFF-file. If compression is not set to anything else, the file is compressed with LZW. It is based on the gdal-package. """ # the array has to be flipped upside down if originY is at the bottom-left (equal to pixelHeight > 0) if pixelHeight > 0: array = np.flipud(array) # create raster DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype) driver = gdal.GetDriverByName('GTiff') if compression == None: compression = str(compression) compression = ['COMPRESS=' + compression] out_raster = driver.Create(outfile_name + '.tif', xsize, ysize, 1, DataType, options=compression) out_raster.SetGeoTransform((originX, pixelWidth, 0, originY, 0, pixelHeight)) out_raster_SRS = osr.SpatialReference() out_raster_SRS.ImportFromEPSG(4326) out_raster.SetProjection(out_raster_SRS.ExportToWkt()) out_raster.GetRasterBand(1).WriteArray(array) out_raster.GetRasterBand(1).SetNoDataValue(no_data_value)
def array2geotiff_rastercopy(array, outfile_name, raster, compression='LZW'): """ This function writes a numpy array into a GeoTIFF-file. Properties are copied from the blueprint raster provided. If compression is not set to anything else, the file is compressed with LZW. It is based on the gdal-package. """ # create raster DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype) driver = gdal.GetDriverByName('GTiff') if compression == None: compression = str(compression) compression = ['COMPRESS=' + compression] out_raster = driver.Create(outfile_name + '.tif', raster.RasterXSize, raster.RasterYSize, 1, DataType, options=compression) out_raster.SetGeoTransform(raster.GetGeoTransform()) out_raster_SRS = osr.SpatialReference() out_raster_SRS.ImportFromEPSG(4326) out_raster.SetProjection(out_raster_SRS.ExportToWkt()) out_raster.GetRasterBand(1).WriteArray(array) out_raster.GetRasterBand(1).SetNoDataValue(raster.GetRasterBand(1).GetNoDataValue())
def to_gdal_dataset(outpath, array): driver = gdal.GetDriverByName("GTiff") dtype = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype) length, width = array.shape dset = driver.Create(outpath, xsize=width, ysize=length, bands=1, eType=dtype) dset.GetRasterBand(1).WriteArray(array)
def dtype_np2gdal(dtype_np): # TODO: Write docstring. if dtype_np == np.bool: promote_dtype = np.uint8 elif dtype_np == np.int8: promote_dtype = np.int16 elif dtype_np == np.float16: promote_dtype = np.float32 else: promote_dtype = None if promote_dtype is not None: warn( "NumPy array data type ({}) does not have equivalent GDAL data type and is not " "supported, but can be safely promoted to {}".format( dtype_np, promote_dtype(1).dtype)) dtype_np = promote_dtype dtype_gdal = gdal_array.NumericTypeCodeToGDALTypeCode(dtype_np) if dtype_gdal is None: raise InvalidArgumentError( "NumPy array data type ({}) does not have equivalent " "GDAL data type and is not supported".format(dtype_np)) return dtype_gdal, promote_dtype
def write_pred_chips(output_path, base_raster, pred_struct, chip_key='predict', ref_shp=None, output_format='GTiff'): driver = gdal.GetDriverByName(output_format) base_ds = gdal.Open(base_raster) x_start, pixel_width, _, y_start, _, pixel_height = base_ds.GetGeoTransform() x_size = base_ds.RasterXSize y_size = base_ds.RasterYSize srs = osr.SpatialReference() srs.ImportFromWkt(base_ds.GetProjectionRef()) num_bands = pred_struct[chip_key][0].shape[-1] data_type = gdal_array.NumericTypeCodeToGDALTypeCode(pred_struct[chip_key][0].dtype) out_ds = driver.Create(output_path, x_size, y_size, num_bands, data_type) out_ds.SetGeoTransform((x_start, pixel_width, 0, y_start, 0, pixel_height)) out_ds.SetProjection(srs.ExportToWkt()) for i in range(1, num_bands + 1): out_band = out_ds.GetRasterBand(i) for idx in range(0, len(pred_struct[chip_key])): chip = pred_struct[chip_key][idx] chip_band = chip[:, :, i - 1] coord = pred_struct['coords'][idx] x_start = coord['upper_row'] + round(pred_struct['overlap'][0] / 2) y_start = coord['left_col'] + round(pred_struct['overlap'][1] / 2) out_band.WriteArray(chip_band, y_start, x_start) out_band.FlushCache() out_ds = None iutils.clip_img_by_network_output(output_path, pred_struct['overlap']) if ref_shp is not None: iutils.clip_by_aggregated_polygons(output_path, ref_shp, output_path, no_data=0)
def save_data(self): """ Saves data into a local GeoTiff file """ driver = gdal.GetDriverByName('GTiff') driver_options = [ "COMPRESS=LZW", "BIGTIFF=YES", "PREDICTOR=1", "TILED=YES", "BLOCKXSIZE=256", "BLOCKYSIZE=256", "INTERLEAVE=BAND" ] # Get GDAL datatype from NumPy datatype dtype = gdal_array.NumericTypeCodeToGDALTypeCode(self.array.dtype) # Create destination dataset if len(self.array.shape) == 3: # 3D array bands, rows, cols = self.array.shape else: # 2D array bands = 1 rows, cols = self.array.shape dst_ds = driver.Create(self.output_filename, cols, rows, bands, dtype, driver_options) # Set cartographic projection dst_ds.SetProjection(self.projection) dst_ds.SetGeoTransform(self.geotransform) # Write bands for band in range(bands): dst_ds.GetRasterBand(band + 1).WriteArray(self.array[band]) # Flush to disk dst_ds = None
def writeGTiff(dstImage, outputPath, projection, coordinates, dtype = None): """ @brief Writes a GeoTiff file created from an existing coordinate-system @Note Coordinates: [Top-Left X, W-E Resolution, 0, Top Left Y, 0, N-S Resolution] """ driver = gdal.GetDriverByName('GTiff') #Add dimension for a single band-image if(dstImage.ndim is 2): dstImage = dstImage[..., np.newaxis] #Set output dtype if not specified if(dtype == None): dtype = gdal_array.NumericTypeCodeToGDALTypeCode(dstImage.dtype) dataset = driver.Create(outputPath, dstImage.shape[1], dstImage.shape[0] , dstImage.shape[2], dtype) if(dataset == None): raise OSError ("GDAL Could not create {0}".format(outputPath)) if(not coordinates or len(coordinates) != 6): raise ValueError("Geotransform empty or unknown: {0}".format(coordinates)) dataset.SetGeoTransform(coordinates) if(not projection): raise ValueError("Projection empty or unknown: {0}".format(projection)) dataset.SetProjection(projection) for index in range(dstImage.shape[2]): dataset.GetRasterBand(index+1).WriteArray(dstImage[:,:,index]) dataset.FlushCache() # Write to disk. dataset = None driver = None return 0
def geotiff(outDir,outName,resolution, fill_value,ImageContainer, array): result_data_nn=array outputName = os.path.normpath(os.path.join(outDir, '{}_2100.tif'.format(outName))) # Generate output filename print(outputName) nRow, nCol = result_data_nn.shape # Define rows/cols from array size dataType = gdal_array.NumericTypeCodeToGDALTypeCode(result_data_nn.dtype) #result_data_nn.dtype # Define output data type or np.int16 for smaller files if dataType==3: fill_value=32767 driver = gdal.GetDriverByName('GTiff') outFile = driver.Create(outputName, nCol, nRow, 1, dataType) # Specify parameters of the GeoTIFF band = outFile.GetRasterBand(1) # Get band 1 band.WriteArray(result_data_nn) # Write data array to band 1 band.FlushCache # Export data band.SetNoDataValue(fill_value) uul=ImageContainer.geo_def.upper_left_extent # Set fill value geoInfo = (uul[0], resolution, 0, uul[1], 0, -resolution) # Define geotransform parameters outFile.SetGeoTransform(geoInfo) srs = osgeo.osr.SpatialReference() srs.ImportFromEPSG(2100) # Set Geotransform outFile.SetProjection(srs.ExportToWkt()) # Set projection outFile = None
def gdal_ds_from_array(arr): """ Returns an in-memory GDAL dataset that is a proxy to the given array http://www.gdal.org/frmt_mem.html """ # Ensure 3D arr = arr.reshape(arr.shape[0], arr.shape[1], -1) assert arr.flags.c_contiguous # http://stackoverflow.com/questions/11264838/how-to-get-the-memory-address-of-a-numpy-array-for-c pointer, read_only_flag = arr.__array_interface__['data'] gdal_dtype = gdal_array.NumericTypeCodeToGDALTypeCode(arr.dtype) print "arr dtype : ", arr.dtype, " => gdal dtype : ", \ gdal.GetDataTypeName(gdal_dtype) ds = gdal.Open("MEM:::" + ",".join([ "DATAPOINTER=%d" % pointer, "DATATYPE=%d" % gdal_dtype, "LINES=%d" % arr.shape[0], "PIXELS=%d" % arr.shape[1], "BANDS=%d" % arr.shape[2], "LINEOFFSET=%d" % arr.strides[0], "PIXELOFFSET=%d" % arr.strides[1], "BANDOFFSET=%d" % arr.strides[2] ])) assert ds is not None, "Failed to create in-memory dataset" # Kind of ugly hack to keep a reference on arr to avoid garbage collection ds._arr = arr return ds
def create_raster_dataset(data, coords, projection=None, nodata=-9999): """ Create In-Memory Raster Dataset Parameters ---------- data : :class:`numpy:numpy.ndarray` Array of shape (rows, cols) or (bands, rows, cols) containing the data values. coords : :class:`numpy:numpy.ndarray` Array of shape (nrows, ncols, 2) containing pixel center coordinates or Array of shape (nrows+1, ncols+1, 2) containing pixel edge coordinates projection : osr object Spatial reference system of the used coordinates, defaults to None. nodata : int Value of NODATA Returns ------- dataset : gdal.Dataset In-Memory raster dataset Note ---- The origin of the provided data and coordinates is UPPER LEFT. """ # align data data = data.copy() if data.ndim == 2: data = data[np.newaxis, ...] bands, rows, cols = data.shape # create In-Memory Raster with correct dtype mem_drv = gdal.GetDriverByName('MEM') gdal_type = gdal_array.NumericTypeCodeToGDALTypeCode(data.dtype) dataset = mem_drv.Create('', cols, rows, bands, gdal_type) # initialize geotransform x_ps, y_ps = coords[1, 1] - coords[0, 0] if data.shape[-2:] == coords.shape[0:2]: upper_corner_x = coords[0, 0, 0] - x_ps / 2 upper_corner_y = coords[0, 0, 1] - y_ps / 2 else: upper_corner_x = coords[0, 0, 0] upper_corner_y = coords[0, 0, 1] geotran = [upper_corner_x, x_ps, 0, upper_corner_y, 0, y_ps] dataset.SetGeoTransform(geotran) if projection: dataset.SetProjection(projection.ExportToWkt()) # set np.nan to nodata dataset.GetRasterBand(1).SetNoDataValue(nodata) for i, band in enumerate(data, start=1): dataset.GetRasterBand(i).WriteArray(band) return dataset
def create_dataset(array, geo_transform=None, projection=None, no_data_value=None): """ Create and return a gdal dataset. :param array: A numpy array. :param geo_transform: 6-tuple of floats :param projection: wkt projection string :param no_data_value: integer or float This is the fastest way to get a gdal dataset from a numpy array, but keep a reference to the array around, or a segfault will occur. Also, don't forget to call FlushCache() on the dataset after any operation that affects the array. """ # prepare dataset name pointing to array datapointer = array.ctypes.data bands, lines, pixels = array.shape datatypecode = gdal_array.NumericTypeCodeToGDALTypeCode(array.dtype.type) datatype = gdal.GetDataTypeName(datatypecode) bandoffset, lineoffset, pixeloffset = array.strides # if projection is wrong there will be a segfault in RasterizeLayer projection = osr.GetUserInputAsWKT(str(projection)) dataset_name_template = ("MEM:::" "DATAPOINTER={datapointer}," "PIXELS={pixels}," "LINES={lines}," "BANDS={bands}," "DATATYPE={datatype}," "PIXELOFFSET={pixeloffset}," "LINEOFFSET={lineoffset}," "BANDOFFSET={bandoffset}") dataset_name = dataset_name_template.format( datapointer=datapointer, pixels=pixels, lines=lines, bands=bands, datatype=datatype, pixeloffset=pixeloffset, lineoffset=lineoffset, bandoffset=bandoffset, ) # access the array memory as gdal dataset dataset = gdal.Open(dataset_name, gdal.GA_Update) # set additional properties from kwargs if geo_transform is not None: dataset.SetGeoTransform(geo_transform) if projection is not None: dataset.SetProjection(projection) if no_data_value is not None: for i in range(len(array)): dataset.GetRasterBand(i + 1).SetNoDataValue(no_data_value) return dataset
def SavePart(self, data, outOffsetYX, cOpts=None): if self._Properties is None: raise ValueError( "File properties must be set first using SetProperties(RasterProps)" ) rProps = self._Properties if outOffsetYX is None: outOffset = (0, 0) dataShape = data.shape currentShape = (rProps.height, rProps.width) if ((dataShape[0] + outOffsetYX[0]) > currentShape[0]) or ( (dataShape[1] + outOffsetYX[1]) > currentShape[1]): raise ValueError( "data + offset are larger than the specified image size") if dataShape[0] == rProps.height and dataShape[1] == rProps.width: isFull = True else: isFull = False if self._Exists: ds = gdal.Open(self._filePath, gdal.GA_Update) else: outDir = os.path.dirname(self._filePath) if not os.path.exists(outDir): os.makedirs(outDir) incomingType = gdal_array.NumericTypeCodeToGDALTypeCode(data.dtype) if incomingType > rProps.datatype: Warning( "Array has higher type than configured file output, values may be truncated" ) outDrv = gdal.GetDriverByName('GTiff') if cOpts is None: cOpts = [ "TILED=YES", "SPARSE_OK=FALSE", "BIGTIFF=YES", "COMPRESS=LZW", "PREDICTOR=2" ] if isFull: # seem to get corruption when writing subsets of files that seems to occur more when using multithreaded # writers, so use a single thread unless we are writing whole file cOpts.append("NUM_THREADS=ALL_CPUS") ds = outDrv.Create(self._filePath, rProps.width, rProps.height, 1, rProps.datatype, cOpts) if rProps.gt is not None: ds.SetGeoTransform(rProps.gt) if rProps.proj is not None: ds.SetProjection(rProps.proj) if rProps.ndv is not None: outBand = ds.GetRasterBand(1) outBand.SetNoDataValue(rProps.ndv) self._Exists = True outBand = ds.GetRasterBand(1) outBand.WriteArray(data, outOffsetYX[1], outOffsetYX[0]) outBand.FlushCache() ds = None
def array2geotiff(band_array, dst_filename, ref, out_datatype=None): """ Wrapper to GDAL to write an array to disk in GeoTiff format. Args: band_array: array that will be written to disk dst_filename: full path to the output GeoTiff ref: reference image with defined geotransform and SRS or a tuple of the form (geotransform, SRS_wkt) out_datatype: GDAL datatype for the output, if None the function tries to figure out the corresponding type automatically Returns: full path to the GeoTiff on disk. """ # DEBUG # band_array = band_corrected_array # dst_filename = dst_filename # ref = (out_gt, prj) # if the input array is a masked array this will set the masked values to zero np.ma.set_fill_value(band_array, 0) # figure out the output datatype according to the type of the input array if not out_datatype: out_datatype = gdal_array.NumericTypeCodeToGDALTypeCode(band_array.dtype) # from tuple if isinstance(ref, tuple): geotrans = ref[0] proj_info = ref[1] cols = band_array.shape[1] rows = band_array.shape[0] # or provided reference image else: ref_image = gdal.Open(ref) geotrans = ref_image.GetGeoTransform() proj_info = ref_image.GetProjection() cols = round(ref_image.RasterXSize) rows = round(ref_image.RasterYSize) driver = gdal.GetDriverByName('GTiff') driver.Create(dst_filename, cols, rows, 1, gdal.GDT_Byte) out_raster = driver.Create(dst_filename, cols, rows, 1, eType=out_datatype) out_raster.SetGeoTransform(geotrans) out_raster.SetProjection(proj_info) outband = out_raster.GetRasterBand(1) if hasattr(band_array, 'mask'): outband.WriteArray(band_array.filled()) else: outband.WriteArray(band_array) outband.FlushCache() out_raster = None ref_image = None return dst_filename
def gdal_write(drv_type, img, dst, projection, coordinates, **kwargs): """ General GDal Write function. Writes array `img` to `dst`. :param drv_type: The Driver type. E.g. "GTiff" or "MEM" :type drv_type: str :param img: The :class:`numpy.ndarray` :param dst: The destination path :param projection: A Gdal projection :type projection: str :param coordinates: A list of floats for the geotransform. See the description in :func:`write_geotiff` :type coordinates: List of float :keyword dtype: The desired gdal dtype :keyword nodata: Assign a nodata value :keyword options: Config options as a list of str, such as ["COMPRESS=DEFLATE"] :return: Writes array to `dst` and returns the dataset. :rtype: :class:`gdal.Dataset` """ dtype = kwargs.get("dtype", None) nodata = kwargs.get("nodata", None) options = kwargs.get("options", []) driver = gdal.GetDriverByName(drv_type) # Add dimension for a single band-image if img.ndim == 2: img = img[..., np.newaxis] # Set output dtype if not specified. GDAL cannot write GTiff as binary files, so convert to uint8: if img.dtype == np.bool: dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np.uint8) if img.dtype == np.int64: dtype = gdal_array.NumericTypeCodeToGDALTypeCode(np.int32) if not dtype: dtype = gdal_array.NumericTypeCodeToGDALTypeCode(img.dtype) img_h, img_w, n_bands = img.shape mem = driver.Create(dst, img_w, img_h, n_bands, dtype, options) mem.SetGeoTransform(coordinates) mem.SetProjection(projection) for bandIdx in range(n_bands): band = img[:, :, bandIdx] raster_band = mem.GetRasterBand(bandIdx + 1) raster_band.WriteArray(band) if nodata: raster_band.SetNoDataValue(nodata) mem.FlushCache() return mem
def create_geotiff(suffix, Array, NDV, xsize, ysize, GeoT, Projection, nc_data, filename): ''' 从数组中创建新的tiff图像 Create a new tiff image from the array ''' DataType = gdal_array.NumericTypeCodeToGDALTypeCode(Array.dtype) ### if type(DataType) != np.int: if DataType.startswith('gdal.GDT_') == False: DataType = eval('gdal.GDT_' + DataType) zsize = Array.shape[0] #create a driver driver = gdal.GetDriverByName('GTiff') #Set nans to the original No Data Value Array[np.isnan(Array)] = NDV #Set up the dataset with zsize #write each slice of the array along the zsize Array_shape_length = len(Array.shape) if Array_shape_length == 3: for i, image in enumerate(Array, 1): now_file = get_time(i - 1, nc_data, var_name, filename) # NewFileName = outpath + var_name + netCDF4文件 + 1999_12_31 + .tif NewFileName = suffix + '\\' + now_file + '.tif' print('Outpath:', NewFileName, '\n') DataSet = driver.Create(NewFileName, xsize, ysize, 1, DataType) DataSet.SetGeoTransform(GeoT) DataSet.SetProjection(Projection.ExportToWkt()) #判读数据的维度 #if Array_shape_length == 3: DataSet.GetRasterBand(1).WriteArray(image) #else: # 数据为n*7*11的矩阵,此代码取的为第0层,一共n层 #DataSet.GetRasterBand(1).WriteArray(image[0]) DataSet.GetRasterBand(1).SetNoDataValue(NDV) DataSet.FlushCache() DataSet = None # close the tif file print('The ' + now_file + '.tif' ' has finished!!!\n') else: for i, image in enumerate(Array, 1): now_file = get_time(i - 1, nc_data, var_name, filename) # NewFileName = outpath + var_name + netCDF4文件 + 1999_12_31 + .tif NewFileName = suffix + '\\' + now_file + '.tif' print('Outpath:', NewFileName, '\n') DataSet = driver.Create(NewFileName, xsize, ysize, 1, DataType) DataSet.SetGeoTransform(GeoT) DataSet.SetProjection(Projection.ExportToWkt()) #判读数据的维度 #数据为n*7*11的矩阵,此代码取的为第0层,一共n层 DataSet.GetRasterBand(1).WriteArray(image[0]) DataSet.GetRasterBand(1).SetNoDataValue(NDV) DataSet.FlushCache() DataSet = None # close the tif file print('The ' + now_file + '.tif' ' has finished!!!\n')
def cut_raster_yboundaries(raster, outfile_name, y_min_new, y_max_new): """ This function cuts a raster-file to y_min_new and y_max_new values and writes it into GeoTIFF-file. It is based on the gdal-package. For (in)rasters with the origin at y_min, the raster is flipped and the origin set to y_max. """ xSize_old = raster.RasterXSize ySize_old = raster.RasterYSize geotransform = raster.GetGeoTransform() x_min_old = geotransform[0] pixelWidth = geotransform[1] pixelHeight = geotransform[5] #x_max_old = x_min_old + xSize_old*pixelWidth if pixelHeight < 0: y_min_old = geotransform[3] + ySize_old * pixelHeight y_max_old = geotransform[3] else: y_max_old = geotransform[3] + ySize_old * pixelHeight y_min_old = geotransform[3] # calculate rows and columns of raster array to cut: #cut_left = abs(x_max_old - x_max)/geotransform[3] #cut_right = abs(x_min_old - x_min)/geotransform[3] cut_top = round(abs(round(y_max_old - y_max_new) / pixelHeight)) cut_bottom = round(abs(round(y_min_old - y_min_new) / pixelHeight)) array = raster.ReadAsArray() # the array has to be flipped upside down if originY is at the bottom-left (equal to pixelHeight > 0) if pixelHeight > 0: array = np.flipud(array) array_cut = array[cut_top:array.shape[0] - cut_bottom].copy() array = None ySize_new = ySize_old - cut_top - cut_bottom if pixelHeight > 0: pixelHeight = -pixelHeight no_data_value = raster.GetRasterBand(1).GetNoDataValue() DataType = gdal_array.NumericTypeCodeToGDALTypeCode(array_cut.dtype) driver = gdal.GetDriverByName('GTiff') out_raster_SRS = osr.SpatialReference() out_raster_SRS.ImportFromEPSG(4326) out_raster = driver.Create(outfile_name + '.tif', xSize_old, ySize_new, 1, DataType) out_raster.SetGeoTransform( (x_min_old, pixelWidth, 0, y_max_new, 0, pixelHeight)) out_raster.SetProjection(out_raster_SRS.ExportToWkt()) out_raster.GetRasterBand(1).WriteArray(array_cut) out_raster.GetRasterBand(1).SetNoDataValue(no_data_value) return out_raster array_cut = None
def processAlgorithm(self, parameters, context, feedback): entrada = self.parameterAsRasterLayer(parameters, self.INPUT, context) if entrada is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.INPUT)) n_banda = self.parameterAsInt(parameters, self.BAND, context) if n_banda is None: raise QgsProcessingException( self.invalidSourceError(parameters, self.BAND)) saida = self.parameterAsFileOutput(parameters, self.OUTPUT, context) Carregar = self.parameterAsBool(parameters, self.OPEN, context) # Abrir banda feedback.pushInfo( self.tr('Reading the selected band...', 'Lendo a banda selecionada...')) image = gdal.Open(entrada.dataProvider().dataSourceUri()) banda = image.GetRasterBand(n_banda).ReadAsArray() prj = image.GetProjection() geotransform = image.GetGeoTransform() # Criar objeto CRS CRS = osr.SpatialReference(wkt=prj) # Obter número de linhas e colunas cols = image.RasterXSize rows = image.RasterYSize image = None # fechar magem # Pegar tipo de dado do array GDT = gdal_array.NumericTypeCodeToGDALTypeCode(banda.dtype) # Criar imagem com uma única banda feedback.pushInfo( self.tr('Writing the selected band...', 'Escrevendo a banda selecionada...')) nova_imagem = gdal.GetDriverByName('GTiff').Create( saida, cols, rows, 1, GDT) nova_imagem.SetGeoTransform(geotransform) nova_imagem.SetProjection(CRS.ExportToWkt()) nova_imagem.GetRasterBand(1).WriteArray(banda) nova_imagem.FlushCache() # Escrever no disco nova_imagem = None # Salvar e fechar CRS = None feedback.pushInfo( self.tr('Operation completed successfully!', 'Operação finalizada com sucesso!')) feedback.pushInfo('Leandro França - Eng Cart') self.CAMINHO = saida self.CARREGAR = Carregar return {self.OUTPUT: saida}
def convert_numpy_type_to_gdal_type(array): typemap = {} for name in dir(np): obj = getattr(np, name) if hasattr(obj, 'dtype'): try: npn = obj(0) nat = np.asscalar(npn) if gdal_array.NumericTypeCodeToGDALTypeCode(npn.dtype.type): typemap[npn.dtype. name] = gdal_array.NumericTypeCodeToGDALTypeCode( npn.dtype.type) except: pass typemap['int64'] = 7 try: return typemap[array.dtype.name] except KeyError: raise KeyError('Unsupported or undetectable data type!')
def GDTNumCode(self, dtype): import numpy as np from osgeo import gdal, gdal_array typemap = {} for name in dir(np): obj = getattr(np, name) if hasattr(obj, 'dtype'): try: npn = obj(0) nat = np.asscalar(npn) if gdal_array.NumericTypeCodeToGDALTypeCode( npn.dtype.type): typemap[ npn.dtype. name] = gdal_array.NumericTypeCodeToGDALTypeCode( npn.dtype.type) except: pass return typemap[dtype]