def create_blank_file(input_filename, output_filename, value=255): ''' following example in http://geoexamples.blogspot.com/2012/12/raster-calculations-with-gdal-and-numpy.html Created GeoTiff format file called output_filename with same properties as input_filename. Limitations: this version limited to single band copy but could easily be extended by user input_filename : string. Name of input file output_filename : string. Name of output file ''' # open input and get data g = gdal.Open(input_filename, gdal.GA_ReadOnly) inband = g.GetRasterBand(1) indata = inband.ReadAsArray() # declare and open output and get data driver = gdal.GetDriverByName("GTiff") gOut = driver.Create(output_filename, \ g.RasterXSize, g.RasterYSize, \ 1, inband.DataType, options=['COMPRESS=LZW']) outband = gOut.GetRasterBand(1) # write value to output # and copy other info gdalnumeric.BandWriteArray(outband, value + indata * 0) gdalnumeric.CopyDatasetInfo(g, gOut) # close the file del gOut return (output_filename)
def create_images(): source_folder = 'source_tiffs' source_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), source_folder) if not os.path.exists(source_path): os.mkdir(source_path) gdal_driver = gdal.GetDriverByName(OUTPUT_FORMAT) for tile_name, tile_values in TILES.items(): output_file_name = os.path.join(source_folder, tile_name) if os.path.isfile(output_file_name): os.remove(output_file_name) output_file = gdal_driver.Create( output_file_name, tile_x, tile_y, tile_bands, gdal.GDT_Int16 # Int16 to enable NoData value of -999 ) output_file.SetGeoTransform(GEO_TRANSFORM[tile_name]) output_file.SetProjection(TileMerger.SOURCE_FILE_PROJECTION) target_band = output_file.GetRasterBand(tile_bands) target_band.SetNoDataValue(2550) # From MODSCAG spec gdalnumeric.BandWriteArray(target_band, tile_values) del target_band del output_file
def raster_file(tmp_input_path): file_name = str(tmp_input_path / FILE_NAME) output_file = GDAL_DRIVER.Create(file_name, BAND_VALUES.shape[1], BAND_VALUES.shape[0], gdal.GDT_Byte) output_file.SetGeoTransform(GEO_TRANSFORM) output_file.SetProjection(PROJECTION.ExportToWkt()) target_band = output_file.GetRasterBand(1) target_band.SetNoDataValue(NO_DATA_VALUE) gdalnumeric.BandWriteArray(target_band, BAND_VALUES) del target_band del output_file return file_name
def copy_into(self, output_file, source_band=1, target_band=1): """ Copy data to target file and filter according to the type given in the initializer. output_file -- gdal.Dataset object for the file into which some or all of this file may be copied. """ t_geotransform = output_file.GetGeoTransform() t_ulx = t_geotransform[0] t_uly = t_geotransform[3] t_pixel_width = t_geotransform[1] t_pixel_height = t_geotransform[5] # Intersection region tgw_ulx = max(t_ulx, self.ulx) if t_pixel_height < 0: tgw_uly = min(t_uly, self.uly) else: tgw_uly = max(t_uly, self.uly) # Target window in pixel coordinates. tw_xoff = int((tgw_ulx - t_ulx) / t_pixel_width + 0.1) tw_yoff = int((tgw_uly - t_uly) / t_pixel_height + 0.1) source_file = gdal.Open(self.filename, gdalconst.GA_ReadOnly) target_band = output_file.GetRasterBand(target_band) source_values = gdalnumeric.BandReadAsArray( source_file.GetRasterBand(source_band), buf_type=gdal.GDT_Float32 ) no_data_value = target_band.GetNoDataValue() # Filter by upper and lower band threshold values source_values[source_values < self.lower_limit] = no_data_value source_values[source_values > self.upper_limit] = no_data_value gdalnumeric.BandWriteArray( target_band, source_values, xoff=tw_xoff, yoff=tw_yoff ) del source_values del source_file
def __copy_band_data(self): target_band = self.output_file.GetRasterBand(self.BAND_NUMBER) target_band.SetNoDataValue(self.BAND_NO_DATA_VALUE) source_values = gdalnumeric.BandReadAsArray( self.mosaic_vrt.GetRasterBand(self.BAND_NUMBER), buf_type=self.BAND_DATA_TYPE, ) # Filter by upper and lower band threshold values source_values[(source_values < self.lower_limit) | ( source_values > self.upper_limit)] = self.BAND_NO_DATA_VALUE gdalnumeric.BandWriteArray(target_band, source_values) target_band.FlushCache() target_band.SetMetadata(self.BAND_METADATA[self.source_type]) del target_band del source_values
def merge_swe_with_sca(swe_file, sca_file): output_file_name = os.path.join(os.path.dirname(sca_file.GetDescription()), 'SWE_by_SCA.tif') swe_by_sca = gdal.GetDriverByName('MEM').CreateCopy( output_file_name, sca_file, 0) swe_by_sca_band = swe_by_sca.GetRasterBand(1) modis_band = sca_file.GetRasterBand(1) sca_data = np.ma.masked_values(modis_band.ReadAsArray(), modis_band.GetNoDataValue(), copy=False) sca_data = sca_data / 100 swe_band = swe_file.GetRasterBand(1) swe_data = np.ma.masked_values(swe_band.ReadAsArray(), swe_band.GetNoDataValue(), copy=False) gdalnumeric.BandWriteArray(swe_by_sca_band, (sca_data * swe_data).astype(np.int16)) swe_by_sca_band.SetMetadata({ 'Description': 'Snow Water Equivalent', 'Unit': 'mm' }) swe_by_sca_band.ComputeStatistics(0) swe_by_sca_band.FlushCache() del modis_band, sca_data del swe_band, swe_data del swe_by_sca_band # GDAL Translate is more efficient with compression for some unknown reason gdal.Translate(output_file_name, swe_by_sca, format='GTiff', creationOptions=[ "COMPRESS=LZW", "TILED=YES", "BIGTIFF=IF_SAFER", "NUM_THREADS=ALL_CPUS" ]) del swe_by_sca
def __hdf_to_tif(self): data = self.northern_swe() self._tif_file = self.GDAL_DRIVER.Create( os.path.join(self._file_dir, 'North_SWE_25k_nsidc.tif'), data.shape[1], data.shape[0], 1, gdalconst.GDT_Int16, ) self.tif_file.SetGeoTransform([ self.NSIDC_NORTH_UL_X, self.SOURCE_SPAT_RES, 0, self.NSIDC_NORTH_UL_Y, 0, -self.SOURCE_SPAT_RES ]) self.tif_file.SetProjection(self.NSIDC_EASE_GRID_NORTH.ExportToWkt()) band = self.tif_file.GetRasterBand(1) band.SetNoDataValue(self.NO_DATA_VALUE) gdalnumeric.BandWriteArray(band, data) band.FlushCache() del data del band
def writeRasterFileFromNumpy(self, pOutNumpy_, outFileName_, pInitRasterFile_): """ Program description: INPUT_PARAMETERS: inputValue_ - COMMENTS: """ #Write Gdal file from numpy array outRasterFileName = tkFileDialog.asksaveasfilename( defaultextension='TIFF', filetypes=[('TIFF', '*.tif')], initialdir=self.workspace, initialfile=outFileName_, parent=tkRoot, title='Save output raster file (GDAL)') #!!! Only for TIFF, one Numpy band and Float data implemented here pDriver = gdal.GetDriverByName("GTiff") pOutRasterDataset = pDriver.Create( outRasterFileName, pInitRasterFile_.RasterXSize, pInitRasterFile_.RasterYSize, 1, GDT_Float32) #New file, settings from original file gdalnumeric.CopyDatasetInfo( pInitRasterFile_, pOutRasterDataset ) #Copy metadata information from original file to new file gdalnumeric.BandWriteArray(pOutRasterDataset.GetRasterBand(1), pOutNumpy_) # Copy numpy-data to new file #Close datasets pOutRasterDataset = None return
def doit(opts, args): # pylint: disable=unused-argument if opts.debug: print("gdal_calc.py starting calculation %s" % (opts.calc)) # set up global namespace for eval with all functions of gdalnumeric global_namespace = dict([(key, getattr(gdalnumeric, key)) for key in dir(gdalnumeric) if not key.startswith('__')]) if opts.user_namespace: global_namespace.update(opts.user_namespace) if not opts.calc: raise Exception("No calculation provided.") elif not opts.outF and opts.format.upper() != 'MEM': raise Exception("No output file provided.") if opts.format is None: opts.format = GetOutputDriverFor(opts.outF) if not hasattr(opts, "color_table"): opts.color_table = None if not opts.extent: opts.extent = EXTENT_IGNORE else: opts.extent = parse_extent(opts.extent) compatible_gt_eps = 0.000001 gt_diff_support = { GT_INCOMPATIBLE_OFFSET: opts.extent != EXTENT_FAIL, GT_INCOMPATIBLE_PIXEL_SIZE: False, GT_INCOMPATIBLE_ROTATION: False, GT_NON_ZERO_ROTATION: False, } gt_diff_error = { GT_INCOMPATIBLE_OFFSET: 'different offset', GT_INCOMPATIBLE_PIXEL_SIZE: 'different pixel size', GT_INCOMPATIBLE_ROTATION: 'different rotation', GT_NON_ZERO_ROTATION: 'non zero rotation', } ################################################################ # fetch details of input layers ################################################################ # set up some lists to store data for each band myFileNames = [] # input filenames myFiles = [] # input DataSets myBands = [] # input bands myAlphaList = [] # input alpha letter that represents each input file myDataType = [] # string representation of the datatype of each input file myDataTypeNum = [] # datatype of each input file myNDV = [] # nodatavalue for each input file DimensionsCheck = None # dimensions of the output Dimensions = [] # Dimensions of input files ProjectionCheck = None # projection of the output GeoTransformCheck = None # GeoTransform of the output GeoTransforms = [] # GeoTransform of each input file GeoTransformDiffer = False # True if we have inputs with different GeoTransforms myTempFileNames = [] # vrt filename from each input file myAlphaFileLists = [] # list of the Alphas which holds a list of inputs # loop through input files - checking dimensions for alphas, filenames in opts.input_files.items(): if isinstance(filenames, (list, tuple)): # alpha is a list of files myAlphaFileLists.append(alphas) elif is_path_like(filenames) or isinstance(filenames, gdal.Dataset): # alpha is a single filename or a Dataset filenames = [filenames] alphas = [alphas] else: # I guess this alphas should be in the global_namespace, # It would have been better to pass it as user_namepsace, but I'll accept it anyway global_namespace[alphas] = filenames continue for alpha, filename in zip(alphas*len(filenames), filenames): if not alpha.endswith("_band"): # check if we have asked for a specific band... if "%s_band" % alpha in opts.input_files: myBand = opts.input_files["%s_band" % alpha] else: myBand = 1 myF_is_ds = not is_path_like(filename) if myF_is_ds: myFile = filename filename = None else: filename = str(filename) myFile = gdal.Open(filename, gdal.GA_ReadOnly) if not myFile: raise IOError("No such file or directory: '%s'" % filename) myFileNames.append(filename) myFiles.append(myFile) myBands.append(myBand) myAlphaList.append(alpha) dt = myFile.GetRasterBand(myBand).DataType myDataType.append(gdal.GetDataTypeName(dt)) myDataTypeNum.append(dt) myNDV.append(None if opts.hideNoData else myFile.GetRasterBand(myBand).GetNoDataValue()) # check that the dimensions of each layer are the same myFileDimensions = [myFile.RasterXSize, myFile.RasterYSize] if DimensionsCheck: if DimensionsCheck != myFileDimensions: GeoTransformDiffer = True if opts.extent in [EXTENT_IGNORE, EXTENT_FAIL]: raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i). Cannot proceed" % (filename, myFileDimensions[0], myFileDimensions[1], DimensionsCheck[0], DimensionsCheck[1])) else: DimensionsCheck = myFileDimensions # check that the Projection of each layer are the same myProjection = myFile.GetProjection() if ProjectionCheck: if opts.projectionCheck and ProjectionCheck != myProjection: raise Exception( "Error! Projection of file %s %s are different from other files %s. Cannot proceed" % (filename, myProjection, ProjectionCheck)) else: ProjectionCheck = myProjection # check that the GeoTransforms of each layer are the same myFileGeoTransform = myFile.GetGeoTransform(can_return_null=True) if opts.extent == EXTENT_IGNORE: GeoTransformCheck = myFileGeoTransform else: Dimensions.append(myFileDimensions) GeoTransforms.append(myFileGeoTransform) if not GeoTransformCheck: GeoTransformCheck = myFileGeoTransform else: my_gt_diff = gt_diff(GeoTransformCheck, myFileGeoTransform, eps=compatible_gt_eps, diff_support=gt_diff_support) if my_gt_diff not in [GT_SAME, GT_ALMOST_SAME]: GeoTransformDiffer = True if my_gt_diff not in [GT_COMPATIBLE_DIFF]: raise Exception( "Error! GeoTransform of file {} {} is incompatible ({}), first file GeoTransform is {}. Cannot proceed". format(filename, myFileGeoTransform, gt_diff_error[my_gt_diff], GeoTransformCheck)) if opts.debug: print("file %s: %s, dimensions: %s, %s, type: %s" % ( alpha, filename, DimensionsCheck[0], DimensionsCheck[1], myDataType[-1])) # process allBands option allBandsIndex = None allBandsCount = 1 if opts.allBands: if len(opts.calc) > 1: raise Exception("Error! --allBands implies a single --calc") try: allBandsIndex = myAlphaList.index(opts.allBands) except ValueError: raise Exception("Error! allBands option was given but Band %s not found. Cannot proceed" % (opts.allBands)) allBandsCount = myFiles[allBandsIndex].RasterCount if allBandsCount <= 1: allBandsIndex = None else: allBandsCount = len(opts.calc) if opts.extent not in [EXTENT_IGNORE, EXTENT_FAIL] and (GeoTransformDiffer or not isinstance(opts.extent, EXTENT)): raise Exception('Error! mixing different GeoTransforms/Extents is not supported yet.') ################################################################ # set up output file ################################################################ # open output file exists if opts.outF and os.path.isfile(opts.outF) and not opts.overwrite: if allBandsIndex is not None: raise Exception("Error! allBands option was given but Output file exists, must use --overwrite option!") if len(opts.calc) > 1: raise Exception("Error! multiple calc options were given but Output file exists, must use --overwrite option!") if opts.debug: print("Output file %s exists - filling in results into file" % (opts.outF)) myOut = gdal.Open(opts.outF, gdal.GA_Update) if myOut is None: error = 'but cannot be opened for update' elif [myOut.RasterXSize, myOut.RasterYSize] != DimensionsCheck: error = 'but is the wrong size' elif ProjectionCheck and ProjectionCheck != myOut.GetProjection(): error = 'but is the wrong projection' elif GeoTransformCheck and GeoTransformCheck != myOut.GetGeoTransform(can_return_null=True): error = 'but is the wrong geotransform' else: error = None if error: raise Exception("Error! Output exists, %s. Use the --overwrite option to automatically overwrite the existing file" % error) myOutB = myOut.GetRasterBand(1) myOutNDV = myOutB.GetNoDataValue() myOutType = myOutB.DataType else: if opts.outF: # remove existing file and regenerate if os.path.isfile(opts.outF): os.remove(opts.outF) # create a new file if opts.debug: print("Generating output file %s" % (opts.outF)) else: opts.outF = '' # find data type to use if not opts.type: # use the largest type of the input files myOutType = max(myDataTypeNum) else: myOutType = opts.type if isinstance(myOutType, str): myOutType = gdal.GetDataTypeByName(myOutType) # create file myOutDrv = gdal.GetDriverByName(opts.format) myOut = myOutDrv.Create( opts.outF, DimensionsCheck[0], DimensionsCheck[1], allBandsCount, myOutType, opts.creation_options) # set output geo info based on first input layer if not GeoTransformCheck: GeoTransformCheck = myFiles[0].GetGeoTransform(can_return_null=True) if GeoTransformCheck: myOut.SetGeoTransform(GeoTransformCheck) if not ProjectionCheck: ProjectionCheck = myFiles[0].GetProjection() if ProjectionCheck: myOut.SetProjection(ProjectionCheck) if opts.NoDataValue is None: myOutNDV = None if opts.hideNoData else DefaultNDVLookup[myOutType] # use the default noDataValue for this datatype elif isinstance(opts.NoDataValue, str) and opts.NoDataValue.lower() == 'none': myOutNDV = None # not to set any noDataValue else: myOutNDV = opts.NoDataValue # use the given noDataValue for i in range(1, allBandsCount + 1): myOutB = myOut.GetRasterBand(i) if myOutNDV is not None: myOutB.SetNoDataValue(myOutNDV) if opts.color_table: # set color table and color interpretation if is_path_like(opts.color_table): raise Exception('Error! reading a color table from a file is not supported yet') myOutB.SetRasterColorTable(opts.color_table) myOutB.SetRasterColorInterpretation(gdal.GCI_PaletteIndex) myOutB = None # write to band myOutTypeName = gdal.GetDataTypeName(myOutType) if opts.debug: print("output file: %s, dimensions: %s, %s, type: %s" % (opts.outF, myOut.RasterXSize, myOut.RasterYSize, myOutTypeName)) ################################################################ # find block size to chop grids into bite-sized chunks ################################################################ # use the block size of the first layer to read efficiently myBlockSize = myFiles[0].GetRasterBand(myBands[0]).GetBlockSize() # find total x and y blocks to be read nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0]) nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1]) myBufSize = myBlockSize[0] * myBlockSize[1] if opts.debug: print("using blocksize %s x %s" % (myBlockSize[0], myBlockSize[1])) # variables for displaying progress ProgressCt = -1 ProgressMk = -1 ProgressEnd = nXBlocks * nYBlocks * allBandsCount ################################################################ # start looping through each band in allBandsCount ################################################################ for bandNo in range(1, allBandsCount + 1): ################################################################ # start looping through blocks of data ################################################################ # store these numbers in variables that may change later nXValid = myBlockSize[0] nYValid = myBlockSize[1] # loop through X-lines for X in range(0, nXBlocks): # in case the blocks don't fit perfectly # change the block size of the final piece if X == nXBlocks - 1: nXValid = DimensionsCheck[0] - X * myBlockSize[0] # find X offset myX = X * myBlockSize[0] # reset buffer size for start of Y loop nYValid = myBlockSize[1] myBufSize = nXValid * nYValid # loop through Y lines for Y in range(0, nYBlocks): ProgressCt += 1 if 10 * ProgressCt / ProgressEnd % 10 != ProgressMk and not opts.quiet: ProgressMk = 10 * ProgressCt / ProgressEnd % 10 from sys import version_info if version_info >= (3, 0, 0): exec('print("%d.." % (10*ProgressMk), end=" ")') else: exec('print 10*ProgressMk, "..",') # change the block size of the final piece if Y == nYBlocks - 1: nYValid = DimensionsCheck[1] - Y * myBlockSize[1] myBufSize = nXValid * nYValid # find Y offset myY = Y * myBlockSize[1] # create empty buffer to mark where nodata occurs myNDVs = None # make local namespace for calculation local_namespace = {} val_lists = defaultdict(list) # fetch data for each input layer for i, Alpha in enumerate(myAlphaList): # populate lettered arrays with values if allBandsIndex is not None and allBandsIndex == i: myBandNo = bandNo else: myBandNo = myBands[i] myval = gdalnumeric.BandReadAsArray(myFiles[i].GetRasterBand(myBandNo), xoff=myX, yoff=myY, win_xsize=nXValid, win_ysize=nYValid) if myval is None: raise Exception('Input block reading failed from filename %s' % filename[i]) # fill in nodata values if myNDV[i] is not None: # myNDVs is a boolean buffer. # a cell equals to 1 if there is NDV in any of the corresponding cells in input raster bands. if myNDVs is None: # this is the first band that has NDV set. we initializes myNDVs to a zero buffer # as we didn't see any NDV value yet. myNDVs = numpy.zeros(myBufSize) myNDVs.shape = (nYValid, nXValid) myNDVs = 1 * numpy.logical_or(myNDVs == 1, myval == myNDV[i]) # add an array of values for this block to the eval namespace if Alpha in myAlphaFileLists: val_lists[Alpha].append(myval) else: local_namespace[Alpha] = myval myval = None for lst in myAlphaFileLists: local_namespace[lst] = val_lists[lst] # try the calculation on the array blocks calc = opts.calc[bandNo-1 if len(opts.calc) > 1 else 0] try: myResult = eval(calc, global_namespace, local_namespace) except: print("evaluation of calculation %s failed" % (calc)) raise # Propagate nodata values (set nodata cells to zero # then add nodata value to these cells). if myNDVs is not None and myOutNDV is not None: myResult = ((1 * (myNDVs == 0)) * myResult) + (myOutNDV * myNDVs) elif not isinstance(myResult, numpy.ndarray): myResult = numpy.ones((nYValid, nXValid)) * myResult # write data block to the output file myOutB = myOut.GetRasterBand(bandNo) if gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY) != 0: raise Exception('Block writing failed') myOutB = None # write to band # remove temp files for idx, tempFile in enumerate(myTempFileNames): myFiles[idx] = None os.remove(tempFile) gdal.ErrorReset() myOut.FlushCache() if gdal.GetLastErrorMsg() != '': raise Exception('Dataset writing failed') if not opts.quiet: print("100 - Done") return myOut
def doit(opts, args): # pylint: disable=unused-argument if opts.debug: print("gdal_calc.py starting calculation %s" % (opts.calc)) # set up global namespace for eval with all functions of gdalnumeric global_namespace = dict([(key, getattr(gdalnumeric, key)) for key in dir(gdalnumeric) if not key.startswith('__')]) if not opts.calc: raise Exception("No calculation provided.") elif not opts.outF: raise Exception("No output file provided.") if opts.format is None: opts.format = GetOutputDriverFor(opts.outF) ################################################################ # fetch details of input layers ################################################################ # set up some lists to store data for each band myFiles = [] myBands = [] myAlphaList = [] myDataType = [] myDataTypeNum = [] myNDV = [] DimensionsCheck = None # loop through input files - checking dimensions for myI, myF in opts.input_files.items(): if not myI.endswith("_band"): # check if we have asked for a specific band... if "%s_band" % myI in opts.input_files: myBand = opts.input_files["%s_band" % myI] else: myBand = 1 myFile = gdal.Open(myF, gdal.GA_ReadOnly) if not myFile: raise IOError("No such file or directory: '%s'" % myF) myFiles.append(myFile) myBands.append(myBand) myAlphaList.append(myI) myDataType.append(gdal.GetDataTypeName(myFile.GetRasterBand(myBand).DataType)) myDataTypeNum.append(myFile.GetRasterBand(myBand).DataType) myNDV.append(myFile.GetRasterBand(myBand).GetNoDataValue()) # check that the dimensions of each layer are the same if DimensionsCheck: if DimensionsCheck != [myFile.RasterXSize, myFile.RasterYSize]: raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i). Cannot proceed" % (myF, myFile.RasterXSize, myFile.RasterYSize, DimensionsCheck[0], DimensionsCheck[1])) else: DimensionsCheck = [myFile.RasterXSize, myFile.RasterYSize] if opts.debug: print("file %s: %s, dimensions: %s, %s, type: %s" % (myI, myF, DimensionsCheck[0], DimensionsCheck[1], myDataType[-1])) # process allBands option allBandsIndex = None allBandsCount = 1 if opts.allBands: try: allBandsIndex = myAlphaList.index(opts.allBands) except ValueError: raise Exception("Error! allBands option was given but Band %s not found. Cannot proceed" % (opts.allBands)) allBandsCount = myFiles[allBandsIndex].RasterCount if allBandsCount <= 1: allBandsIndex = None ################################################################ # set up output file ################################################################ # open output file exists if os.path.isfile(opts.outF) and not opts.overwrite: if allBandsIndex is not None: raise Exception("Error! allBands option was given but Output file exists, must use --overwrite option!") if opts.debug: print("Output file %s exists - filling in results into file" % (opts.outF)) myOut = gdal.Open(opts.outF, gdal.GA_Update) if [myOut.RasterXSize, myOut.RasterYSize] != DimensionsCheck: raise Exception("Error! Output exists, but is the wrong size. Use the --overwrite option to automatically overwrite the existing file") myOutB = myOut.GetRasterBand(1) myOutNDV = myOutB.GetNoDataValue() myOutType = gdal.GetDataTypeName(myOutB.DataType) else: # remove existing file and regenerate if os.path.isfile(opts.outF): os.remove(opts.outF) # create a new file if opts.debug: print("Generating output file %s" % (opts.outF)) # find data type to use if not opts.type: # use the largest type of the input files myOutType = gdal.GetDataTypeName(max(myDataTypeNum)) else: myOutType = opts.type # create file myOutDrv = gdal.GetDriverByName(opts.format) myOut = myOutDrv.Create( opts.outF, DimensionsCheck[0], DimensionsCheck[1], allBandsCount, gdal.GetDataTypeByName(myOutType), opts.creation_options) # set output geo info based on first input layer myOut.SetGeoTransform(myFiles[0].GetGeoTransform()) myOut.SetProjection(myFiles[0].GetProjection()) if opts.NoDataValue is not None: myOutNDV = opts.NoDataValue else: myOutNDV = DefaultNDVLookup[myOutType] for i in range(1, allBandsCount + 1): myOutB = myOut.GetRasterBand(i) myOutB.SetNoDataValue(myOutNDV) # write to band myOutB = None if opts.debug: print("output file: %s, dimensions: %s, %s, type: %s" % (opts.outF, myOut.RasterXSize, myOut.RasterYSize, myOutType)) ################################################################ # find block size to chop grids into bite-sized chunks ################################################################ # use the block size of the first layer to read efficiently myBlockSize = myFiles[0].GetRasterBand(myBands[0]).GetBlockSize() # find total x and y blocks to be read nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0]) nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1]) myBufSize = myBlockSize[0] * myBlockSize[1] if opts.debug: print("using blocksize %s x %s" % (myBlockSize[0], myBlockSize[1])) # variables for displaying progress ProgressCt = -1 ProgressMk = -1 ProgressEnd = nXBlocks * nYBlocks * allBandsCount ################################################################ # start looping through each band in allBandsCount ################################################################ for bandNo in range(1, allBandsCount + 1): ################################################################ # start looping through blocks of data ################################################################ # store these numbers in variables that may change later nXValid = myBlockSize[0] nYValid = myBlockSize[1] # loop through X-lines for X in range(0, nXBlocks): # in case the blocks don't fit perfectly # change the block size of the final piece if X == nXBlocks - 1: nXValid = DimensionsCheck[0] - X * myBlockSize[0] # find X offset myX = X * myBlockSize[0] # reset buffer size for start of Y loop nYValid = myBlockSize[1] myBufSize = nXValid * nYValid # loop through Y lines for Y in range(0, nYBlocks): ProgressCt += 1 if 10 * ProgressCt / ProgressEnd % 10 != ProgressMk and not opts.quiet: ProgressMk = 10 * ProgressCt / ProgressEnd % 10 from sys import version_info if version_info >= (3, 0, 0): exec('print("%d.." % (10*ProgressMk), end=" ")') else: exec('print 10*ProgressMk, "..",') # change the block size of the final piece if Y == nYBlocks - 1: nYValid = DimensionsCheck[1] - Y * myBlockSize[1] myBufSize = nXValid * nYValid # find Y offset myY = Y * myBlockSize[1] # create empty buffer to mark where nodata occurs myNDVs = None # make local namespace for calculation local_namespace = {} # fetch data for each input layer for i, Alpha in enumerate(myAlphaList): # populate lettered arrays with values if allBandsIndex is not None and allBandsIndex == i: myBandNo = bandNo else: myBandNo = myBands[i] myval = gdalnumeric.BandReadAsArray(myFiles[i].GetRasterBand(myBandNo), xoff=myX, yoff=myY, win_xsize=nXValid, win_ysize=nYValid) # fill in nodata values if myNDV[i] is not None: if myNDVs is None: myNDVs = numpy.zeros(myBufSize) myNDVs.shape = (nYValid, nXValid) myNDVs = 1 * numpy.logical_or(myNDVs == 1, myval == myNDV[i]) # add an array of values for this block to the eval namespace local_namespace[Alpha] = myval myval = None # try the calculation on the array blocks try: myResult = eval(opts.calc, global_namespace, local_namespace) except: print("evaluation of calculation %s failed" % (opts.calc)) raise # Propagate nodata values (set nodata cells to zero # then add nodata value to these cells). if myNDVs is not None: myResult = ((1 * (myNDVs == 0)) * myResult) + (myOutNDV * myNDVs) elif not isinstance(myResult, numpy.ndarray): myResult = numpy.ones((nYValid, nXValid)) * myResult # write data block to the output file myOutB = myOut.GetRasterBand(bandNo) gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY) if not opts.quiet: print("100 - Done")
def main(): # initiate the parser parser = argparse.ArgumentParser( description='Summarize a set of rasters layers.') parser.add_argument('files', nargs='+', help='input raster file(s)') parser.add_argument('--outfile', '-o', required=True, help='output raster') band_help = 'bands to summarize. ' + \ 'single file: bands in this file to summarize (default all bands); ' + \ 'multiple files: bands in corresponding files to summarize (default = 1)' parser.add_argument('--bands', '-b', nargs='+', type=int, help=band_help) function_help = 'function to apply to cell values across layers.' + \ 'meannz gives a mean of the non-zero values.' + \ 'count counts the number layers with non-negative values for each cell.' + \ 'richness counts the number of layers with positive values for each cell.' parser.add_argument('--function', '-f', dest='summary_function', default='mean', choices=[ 'mean', 'median', 'max', 'sum', 'meannz', 'count', 'richness' ], help="summarization function (default = 'mean')") parser.add_argument( '--block_size', '-s', nargs=2, type=int, help='x and y dimensions of blocks to process (default based on input)' ) parser.add_argument( '--nrows', '-n', type=int, help= 'number of rows to process in a single block (block_size ignored if provided)' ) parser.add_argument('--overwrite', '-w', action="store_true", help='overwrite existing file') parser.add_argument( '--creation-option', '--co', dest='creation_options', default=[], action='append', help= 'passes one or more creation options to the output format driver multiple' ) parser.add_argument('--quiet', '-q', action="store_true", help='supress messages') # read arguments from the command line args = parser.parse_args() # summarize multiple bands of same file or bands across files if len(args.files) == 1: # use all bands if not specified if not args.bands: b = gdal.Open(args.files[0], gdal.GA_ReadOnly).RasterCount args.bands = [i for i in range(1, b + 1)] # elif len(args.bands) == 1: # raise Exception('For a single input file, provide multiple bands to summarize over.') args.files = [args.files[0]] * len(args.bands) else: # use band 1 if not specified if not args.bands: args.bands = [1] * len(args.files) elif len(args.bands) == 1: args.bands = [args.bands[0]] * len(args.files) elif len(args.bands) != len(args.files): raise Exception( 'The number of bands must be 1 or equal to the number of input files.' ) # set up some default nodatavalues for each datatype ndv_lookup = { 'Byte': 255, 'UInt16': 65535, 'Int16': -32767, 'UInt32': 4294967293, 'Int32': -2147483647, 'Float32': 3.402823466E+38, 'Float64': 1.7976931348623158E+308 } stack = [] in_type = [] in_ndv = [] raster_dim = None block_size = None out_transform = None out_projection = None # pass over files to get metadata and check arguments for i in range(len(args.files)): f = args.files[i] b = args.bands[i] s = gdal.Open(f, gdal.GA_ReadOnly) # check that file exists if not s: raise IOError('No such file or directory: {}'.format(f)) # check that band is valid if b > s.RasterCount: raise IOError('Invalid band number ({}) for file: {}'.format(b, f)) # get specified band r = s.GetRasterBand(b) # store raster file stack.append(s) # metadata in_type.append(r.DataType) dt_name = gdal.GetDataTypeName(r.DataType).lower() in_ndv.append(np.float64(r.GetNoDataValue()).astype(dt_name)) # check that the dimensions of each layer are the same if raster_dim: if raster_dim != [s.RasterXSize, s.RasterYSize]: raise Exception('Input files have different dimensions.') else: raster_dim = [s.RasterXSize, s.RasterYSize] # block size to chop grids into bite-sized chunks if not block_size: # use the block size of the first layer to read efficiently # or use user provided block size if not args.nrows: if not args.block_size: block_size = s.GetRasterBand(1).GetBlockSize() else: # block size can't be larger than raster dimensions block_size = np.minimum(args.block_size, raster_dim).tolist() else: block_size = [raster_dim[0], min(raster_dim[1], args.nrows)] # get geo info from first layer if not out_transform: out_transform = s.GetGeoTransform() if not out_projection: out_projection = s.GetProjection() # prepare output file if os.path.isfile(args.outfile) and not args.overwrite: raise Exception( "Output exists, use the --overwrite to overwrite the existing file" ) else: # remove existing file and regenerate if os.path.isfile(args.outfile): os.remove(args.outfile) # for sum use the largest type of the input files # otherise use a value suitable for the function if args.summary_function == 'sum': out_type = gdal.GetDataTypeName(max(in_type)) out_type_np = out_type.lower() np_nan = 0 elif args.summary_function == 'mean': out_type = 'Float32' out_type_np = out_type.lower() np_nan = np.nan elif args.summary_function == 'median': out_type = 'Float32' out_type_np = out_type.lower() np_nan = np.nan elif args.summary_function == 'max': out_type = 'Float32' out_type_np = out_type.lower() np_nan = np.nan elif args.summary_function == 'meannz': out_type = 'Float32' out_type_np = out_type.lower() np_nan = np.nan elif args.summary_function == 'count': out_type = 'Int16' out_type_np = out_type.lower() np_nan = -1 elif args.summary_function == 'richness': out_type = 'Int16' out_type_np = out_type.lower() np_nan = -1 # create file out_driver = gdal.GetDriverByName('GTiff') r_out = out_driver.Create(args.outfile, raster_dim[0], raster_dim[1], 1, gdal.GetDataTypeByName(out_type), args.creation_options) # set output geo info based on first input layer r_out.SetGeoTransform(out_transform) r_out.SetProjection(out_projection) # set no data value out_ndv = ndv_lookup[out_type] out_ndv_np = np.float64(out_ndv).astype(out_type_np) r_out.GetRasterBand(1).SetNoDataValue(out_ndv) # find total x and y blocks to be read xblocks = math.ceil(raster_dim[0] / block_size[0]) yblocks = math.ceil(raster_dim[1] / block_size[1]) # loop through blocks of data # store these numbers in variables that may change later xvalid = block_size[0] yvalid = block_size[1] # variables for displaying progress progress_cnt = -1 progress_stp = 0 progress_end = xblocks * yblocks progress_stps = [round(progress_end * i / 100) for i in range(0, 101, 10)] # message if not args.quiet: m = "Processing {} X {} raster (cols X rows) in {} blocks of {} X {}" m = m.format(raster_dim[0], raster_dim[1], xblocks * yblocks, block_size[0], block_size[1]) print(m) # loop through x dimension for x in range(0, xblocks): # in case the blocks don't fit perfectly # change the block size of the final piece if x == xblocks - 1: xvalid = raster_dim[0] - x * block_size[0] # find x offset x_off = x * block_size[0] # reset buffer size for start of Y loop yvalid = block_size[1] # loop through y dimension for y in range(0, yblocks): # progress bar progress_cnt += 1 if progress_cnt == progress_stps[progress_stp] and not args.quiet: print('%d...' % (10 * progress_stp), end="", flush=True) progress_stp += 1 # change the block size of the final piece if y == yblocks - 1: yvalid = raster_dim[1] - y * block_size[1] # find y offset y_off = y * block_size[1] # create empty buffer to mark where nodata occurs ndv_buffer = None # make array to store block block = np.empty(shape=(len(stack), yvalid, xvalid), dtype='float32') # fetch data for each input layer for i in range(len(stack)): vals = gdalnumeric.BandReadAsArray(stack[i].GetRasterBand( args.bands[i]), xoff=x_off, yoff=y_off, win_xsize=xvalid, win_ysize=yvalid) if out_type != "Int16": vals = vals.astype(out_type_np) # fill in nodata values if in_ndv[i] is not None: vals[vals == in_ndv[i]] = np_nan # add block to array block[i] = vals vals = None # ignore empty slice warnings with warnings.catch_warnings(): warnings.simplefilter('ignore', category=RuntimeWarning) if args.summary_function == 'sum': result = np.nansum(block, axis=0) elif args.summary_function == 'mean': result = np.nanmean(block, axis=0) elif args.summary_function == 'median': result = np.nanmedian(block, axis=0) elif args.summary_function == 'max': result = np.nanmax(block, axis=0) elif args.summary_function == 'meannz': block = np.ma.masked_equal(block, 0) result = np.nanmean(block, axis=0) elif args.summary_function == 'count': result = np.nansum(block >= 0, axis=0) elif args.summary_function == 'richness': result = np.nansum(block > 0, axis=0) # replace nan with no data value result[np.isnan(result)] = out_ndv_np # write data block to the output file gdalnumeric.BandWriteArray(r_out.GetRasterBand(1), result, xoff=x_off, yoff=y_off) # end progress bar if not args.quiet: print('100 - Done')
def run(self): self._abort = False self.progress.emit("Starting RasterBender", float(0), float(0)) ##################################### # Step 1 : create the delaunay mesh # ##################################### self.progress.emit("Loading delaunay mesh...", float(0), float(0)) # Create the delaunay triangulation triangles, pointsA, pointsB, hull, constraints = triangulate.triangulate( self.pairsLayer, self.pairsLimitToSelection, self.constraintsLayer, self.constraintsLimitToSelection, self.bufferValue) ############################### # Step 2. Opening the dataset # ############################### self.progress.emit( "Opening the dataset... This shouldn't be too long...", float(0), float(0)) #Open the dataset gdal.UseExceptions() # Read the source data into numpy arrays dsSource = gdal.Open(self.sourcePath, gdal.GA_ReadOnly) sourceDataR = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(1)) sourceDataG = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(2)) sourceDataB = gdalnumeric.BandReadAsArray(dsSource.GetRasterBand(3)) # Get the transformation pixW = float(dsSource.RasterXSize - 1) #width in pixel pixH = float(dsSource.RasterYSize - 1) #width in pixel mapW = float(dsSource.RasterXSize) * dsSource.GetGeoTransform()[ 1] #width in map units mapH = float(dsSource.RasterYSize) * dsSource.GetGeoTransform()[ 5] #width in map units offX = dsSource.GetGeoTransform()[0] #offset in map units offY = dsSource.GetGeoTransform()[3] #offset in map units # Open the target into numpy array #dsTarget = gdal.Open(self.targetPath, gdal.GA_Update ) driver = gdal.GetDriverByName("GTiff") dsTarget = driver.CreateCopy(self.targetPath, dsSource, 0) #dsTarget.SetGeoTransform( dsSource.GetGeoTransform() ) dsTarget = None #close def xyToQgsPoint(x, y): return QgsPoint(offX + mapW * (x / pixW), offY + mapH * (y / pixH)) def qgsPointToXY(qgspoint): return (int((qgspoint.x() - offX) / mapW * pixW), int((qgspoint.y() - offY) / mapH * pixH)) ####################################### # Step 3A. Looping through the blocks # ####################################### #Loop through every block blockCountX = dsSource.RasterXSize // self.blockSize + 1 blockCountY = dsSource.RasterYSize // self.blockSize + 1 blockCount = blockCountX * blockCountY blockI = 0 displayTotal = dsSource.RasterXSize * dsSource.RasterYSize displayStep = min((self.blockSize**2) / 20, 10000) # update gui every n steps self.progress.emit("Starting computation... This can take a while...", float(0), float(0)) for blockNumY in range(0, blockCountY): blockOffsetY = blockNumY * self.blockSize blockH = min(self.blockSize, dsSource.RasterYSize - blockOffsetY) if blockH <= 0: continue for blockNumX in range(0, blockCountX): blockOffsetX = blockNumX * self.blockSize blockW = min(self.blockSize, dsSource.RasterXSize - blockOffsetX) if blockW <= 0: continue blockI += 1 pixelCount = blockW * blockH pixelI = 0 blockRectangle = QgsRectangle( xyToQgsPoint(blockOffsetX, blockOffsetY), xyToQgsPoint(blockOffsetX + blockW, blockOffsetY + blockH) ) # this is the shape of the block, used for optimization # We check if the block intersects the hull, if not, we skip it if not hull.intersects(blockRectangle): self.progress.emit( "Block %i out of %i is out of the convex hull, we skip it..." % (blockI, blockCount), float(0), float(blockI / float(blockCount))) continue # We create the trifinder for the block blockTrifinder = trifinder.Trifinder(pointsB, triangles, blockRectangle) targetDataR = gdalnumeric.BandReadAsArray( dsSource.GetRasterBand(1), blockOffsetX, blockOffsetY, blockW, blockH) targetDataG = gdalnumeric.BandReadAsArray( dsSource.GetRasterBand(2), blockOffsetX, blockOffsetY, blockW, blockH) targetDataB = gdalnumeric.BandReadAsArray( dsSource.GetRasterBand(3), blockOffsetX, blockOffsetY, blockW, blockH) ####################################### # Step 3B. Looping through the pixels # ####################################### # Loop through every pixel for y in range(0, blockH): for x in range(0, blockW): # If abort was called, we finish the process if self._abort: self.error.emit( "Aborted on pixel %i out of %i on block %i out of %i..." % (pixelI, pixelCount, blockI, blockCount), float(0), float(0)) return pixelI += 1 # Ever now and then, we update the status if pixelI % displayStep == 0: self.progress.emit( "Working on pixel %i out of %i on block %i out of %i... Trifinder has %i triangles" % (pixelI, pixelCount, blockI, blockCount, len(blockTrifinder.triangles)), float(pixelI) / float(pixelCount), float(blockI) / float(blockCount)) # We find in which triangle the point lies using the trifinder. p = xyToQgsPoint(blockOffsetX + x, blockOffsetY + y) tri = blockTrifinder.find(p) if tri is None: # If it's in no triangle, we don't change it continue # If it's in a triangle, we transform the coordinates newP = trimapper.map(p, pointsB[tri[0]], pointsB[tri[1]], pointsB[tri[2]], pointsA[tri[0]], pointsA[tri[1]], pointsA[tri[2]]) newX, newY = qgsPointToXY(newP) # TODO : this would maybe get interpolated results #ident = sourceRaster.dataProvider().identify( pt, QgsRaster.IdentifyFormatValue) #targetDataR[y][x] = ident.results()[1] #targetDataG[y][x] = ident.results()[2] #targetDataB[y][x] = ident.results()[3] try: if newY < 0 or newX < 0: raise IndexError() #avoid looping targetDataR[y][x] = sourceDataR[newY][newX] targetDataG[y][x] = sourceDataG[newY][newX] targetDataB[y][x] = sourceDataB[newY][newX] except IndexError, e: targetDataR[y][x] = 0 targetDataG[y][x] = 0 targetDataB[y][x] = 0 # Write to the image dsTarget = gdal.Open(self.targetPath, gdal.GA_Update) gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(1), targetDataR, blockOffsetX, blockOffsetY) gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(2), targetDataG, blockOffsetX, blockOffsetY) gdalnumeric.BandWriteArray(dsTarget.GetRasterBand(3), targetDataB, blockOffsetX, blockOffsetY) dsTarget = None
def files_mean(file_array, filename_out): myFiles=[] myNDV=[] DimensionsCheck=None allBandsCount=1 myOutNDV=-32767 for (i, filename) in enumerate(file_array): if os.path.isfile(filename): myFile = gdal.Open(filename, gdal.GA_ReadOnly) if not myFile: raise IOError("No such file or directory: '%s'" % myFile) myFiles.append(myFile) myNDV.append(myFile.GetRasterBand(1).GetNoDataValue()) if DimensionsCheck: if DimensionsCheck != [myFile.RasterXSize, myFile.RasterYSize]: raise Exception("Error! Dimensions of file %s (%i, %i) are different from other files (%i, %i). Cannot proceed" % (myF, myFile.RasterXSize, myFile.RasterYSize, DimensionsCheck[0], DimensionsCheck[1])) else: DimensionsCheck = [myFile.RasterXSize, myFile.RasterYSize] if os.path.isfile(filename_out): os.remove(filename_out) myBlockSize=myFiles[0].GetRasterBand(1).GetBlockSize(); # store these numbers in variables that may change later nXValid = myBlockSize[0] nYValid = myBlockSize[1] # find total x and y blocks to be read nXBlocks = (int)((DimensionsCheck[0] + myBlockSize[0] - 1) / myBlockSize[0]); nYBlocks = (int)((DimensionsCheck[1] + myBlockSize[1] - 1) / myBlockSize[1]); myBufSize = myBlockSize[0]*myBlockSize[1] myOutDrv = gdal.GetDriverByName('GTiff') myOut = myOutDrv.Create(filename_out, DimensionsCheck[0], DimensionsCheck[1], 1,gdal.GDT_Float32) # set output geo info based on first input layer myOut.SetGeoTransform(myFiles[0].GetGeoTransform()) myOut.SetProjection(myFiles[0].GetProjection()) for bandNo in range(1,allBandsCount+1): for X in range(0,nXBlocks): if X==nXBlocks-1: nXValid = DimensionsCheck[0] - X * myBlockSize[0] myBufSize = nXValid*nYValid # find X offset myX=X*myBlockSize[0] # reset buffer size for start of Y loop nYValid = myBlockSize[1] myBufSize = nXValid*nYValid # loop through Y lines for Y in range(0,nYBlocks): # change the block size of the final piece if Y==nYBlocks-1: nYValid = DimensionsCheck[1] - Y * myBlockSize[1] myBufSize = nXValid*nYValid # find Y offset myY=Y*myBlockSize[1] # create empty buffer to mark where nodata occurs myNDVs = None # make local namespace for calculation local_namespace = [] for (i, myFile) in enumerate(myFiles): myval=gdalnumeric.BandReadAsArray(myFile.GetRasterBand(1), xoff=myX, yoff=myY, win_xsize=nXValid, win_ysize=nYValid) # fill in nodata values if myNDV[i] is not None: if myNDVs is None: myNDVs = numpy.zeros(myBufSize) myNDVs.shape=(nYValid,nXValid) myNDVs=1*numpy.logical_or(myNDVs==1, myval==myNDV[i]) local_namespace.append(myval) myval=None # calculate mean between bands using Numpy myResult = numpy.mean(local_namespace, axis=0) if myNDVs is not None: myResult = ((1*(myNDVs==0))*myResult) + (myOutNDV*myNDVs) elif not isinstance(myResult, numpy.ndarray): myResult = numpy.ones( (nYValid,nXValid) ) * myResult myOutB=myOut.GetRasterBand(bandNo) gdalnumeric.BandWriteArray(myOutB, myResult, xoff=myX, yoff=myY) return # how to use it files_mean(['./input_01.tif', './input_02.tif', './input_02.tif', ... './input_n.tif',],'./output.tif')
def write_tif(self, outname, data2write= False, dtype = 1, nodata = False, option = 'COMPRESS=DEFLATE'): '''dtype: .... if nodata set to True the orig nodata value will be assigned to the raster, if it is not a double ( in this case no nodata will be assigned) write_tif(outname, data2write=False, dtype=1, nodata=False, option='Compress=Deflate') dtypes: 0 --> Int16 1 --> Int32 2 --> UIit16 3 --> UInt32 4 --> Float32 5 --> Float64 6 --> UInt8 ''' dtypeL = [zz_gdalcon.GDT_Int16, zz_gdalcon.GDT_Int32, zz_gdalcon.GDT_UInt16, zz_gdalcon.GDT_UInt32, zz_gdalcon.GDT_Float32, zz_gdalcon.GDT_Float64, zz_gdalcon.GDT_Byte] try: if type(data2write) != type(self.data): data2write = self.data if len(data2write.shape)==3: nr_of_bands = data2write.shape[0] elif len(data2write.shape)==2: nr_of_bands = 1 else: raise NameError('ERROR: in Number of Bands') if not 'int' in str(np.result_type(data2write)): dataOut = self.driver.Create(outname, self.columns, self.rows, nr_of_bands, dtypeL[dtype]) else: dataOut = self.driver.Create(outname, self.columns, self.rows, nr_of_bands, dtypeL[dtype], options=[option]) #dataOut.SetGeoTransform(self.intif.GetGeoTransform()) zz_gdalnum.CopyDatasetInfo(self.intif, dataOut) for band in range(nr_of_bands): bandOut = dataOut.GetRasterBand(band+1) if nodata: #test if nodate can be set if isinstance(nodata, bool) and 'e' not in str(self.nodata): nodata = self.nodata if 'e' in str(nodata): nodata = False if nodata: bandOut.SetNoDataValue(nodata) if nr_of_bands==1: zz_gdalnum.BandWriteArray(bandOut,data2write) else: zz_gdalnum.BandWriteArray(bandOut,data2write[band,:,:]) bandOut = None dataOut = None #print 0 except IOError as e: print "I/O error({0}): {1}".format(e.errno, e.strerror) except ValueError: print ("Could not write the nodata value") except: print "Unexpected error:", sys.exc_info()
def write_tif(file_with_srid,full_output_name, data, dtype= 1, nodata=None, option=False ): ''' write data to tif >>> write_tif(file_with_srid, full_output_name, data, 1, nodata=None, option=False) file_wite_srid --> the original file with spatial infromations full_output_name --> path + filename + tile type e.g.: r'c:\\temp\\file1.tif' data --> data you want to write to tif dtype --> Output data type (int, float ...) input number between 0 and 5: - 0 --> Int16 - 1 --> Int32 - 2 --> UInt16 - 3 --> UInt32 - 4 --> Float32 - 5 --> Float64 - 6 --> UInt8 --> default is Int32 nodata --> by default there will be no NoData Value asigned if True: it will put the max Value for Unsigned Integers it will put the min Value for signed Integers and floats if you put a Value --> this Value will be the NoData Value option --> "COMPRESS=DEFLATE" if data is a 3d array it will write all bands to the tif (in single bands) ''' dtypeL = [zz_gdalcon.GDT_Int16, zz_gdalcon.GDT_Int32, zz_gdalcon.GDT_UInt16, zz_gdalcon.GDT_UInt32, zz_gdalcon.GDT_Float32, zz_gdalcon.GDT_Float64, zz_gdalcon.GDT_Byte] try: inTiff, driver, inCols, inRows = read_tif_info(file_with_srid) if len(data.shape)==3: nr_of_bands = data.shape[0] elif len(data.shape)==2: nr_of_bands = 1 else: print('error in Bands') sys.exit(1) #print(nr_of_bands) if option: dataOut = driver.Create(full_output_name,inCols,inRows,nr_of_bands, dtypeL[dtype],options=[option]) else: dataOut = driver.Create(full_output_name,inCols,inRows,nr_of_bands, dtypeL[dtype]) zz_gdalnum.CopyDatasetInfo(inTiff,dataOut) for band in range(nr_of_bands): bandOut = dataOut.GetRasterBand(band+1) if nodata is not None: bandOut.SetNoDataValue(nodata) if nr_of_bands==1: zz_gdalnum.BandWriteArray(bandOut,data) else: zz_gdalnum.BandWriteArray(bandOut,data[band,:,:]) bandOut = None dataOut = None except IOError as e: print "I/O error({0}): {1}".format(e.errno, e.strerror) except ValueError: print ("Could not write the nodata value") except: print "Unexpected error:", sys.exc_info()
def compare ( TET_tem_path, SST_tem_path, outputFile ): if os.path.exists(outputFile) == False: os.mkdir(outputFile) elif os.path.exists(outputFile) == True: return os.chdir(outputFile) TET_tem = gdal.Open(TET_tem_path) SST_tem = gdal.Open(SST_tem_path) MIR_band = TET_tem.GetRasterBand(1) TIR_band = TET_tem.GetRasterBand(2) SST_band = SST_tem.GetRasterBand(1) MIR_data = MIR_band.ReadAsArray() TIR_data = TIR_band.ReadAsArray() SST_data = SST_band.ReadAsArray() default_tem = 274.15 * np.ones(SST_data.shape) # MIR_deg = MIR_data + default_tem # TIR_deg = TIR_data + default_tem SST_K = SST_data + default_tem diff_MIR = MIR_data - SST_K diff_TIR = TIR_data - SST_K logic1 = np.where(np.absolute(diff_MIR)>50) diff_MIR[logic1] = 0 logic2 = np.where(np.absolute(diff_TIR)>50) diff_TIR[logic2] = 0 diff_MIR_max = diff_MIR.max() diff_TIR_max = diff_TIR.max() diff_MIR_min = diff_MIR.min() diff_TIR_min = diff_TIR.min() diff_MIR_mean = diff_MIR.mean() diff_TIR_mean = diff_TIR.mean() diff_MIR_std = diff_MIR.std() diff_TIR_std = diff_TIR.std() diff_MIR_median = np.median(diff_MIR[diff_MIR.nonzero()]) diff_TIR_median = np.median(diff_TIR[diff_TIR.nonzero()]) abs_diff_MIR = np.absolute(diff_MIR) abs_diff_TIR = np.absolute(diff_TIR) abs_diff_MIR_mean = abs_diff_MIR.mean() abs_diff_TIR_mean = abs_diff_TIR.mean() abs_diff_MIR_std = abs_diff_MIR.std() abs_diff_TIR_std = abs_diff_TIR.std() f = open( os.path.join(outputFile, 'statistics_info.txt'), 'w' ) f.write('Difference between SST and TET temperature.\n') f.write('MIR band.\tUnit: degrees Celsius.\n') f.write('Maximum: %s.\nMinimum: %s.\n' %(str(diff_MIR_max), str(diff_MIR_min))) f.write('Mean: %s.\nStandard Deviation: %s.\nMedian Value: %s.\n' %(str(diff_MIR_mean), str(diff_MIR_std), str(diff_MIR_median))) f.write('Absolute Mean: %s.\nAbsolute Standard Deviation: %s.\n\n' %(str(abs_diff_MIR_mean), str(abs_diff_MIR_std))) f.write('Difference between SST and TET temperature.\n') f.write('TIR band.\tUnit: degrees Celsius.\n') f.write('Maximum: %s.\nMinimum: %s.\n' %(str(diff_TIR_max), str(diff_TIR_min))) f.write('Mean: %s.\nStandard Deviation: %s.\nMedian Value: %s.\n' %(str(diff_TIR_mean), str(diff_TIR_std), str(diff_TIR_median))) f.write('Absolute Mean: %s.\nAbsolute Standard Deviation: %s.\n' %(str(abs_diff_TIR_mean), str(abs_diff_TIR_std))) f.close() driver = gdal.GetDriverByName('GTiff') MIR_out = driver.Create('diff_MIR.tif', TET_tem.RasterXSize, TET_tem.RasterYSize, 1, MIR_band.DataType) gdalnumeric.CopyDatasetInfo(TET_tem, MIR_out) MIR_bandOut = MIR_out.GetRasterBand(1) MIR_bandOut.SetNoDataValue(0.0) gdalnumeric.BandWriteArray(MIR_bandOut, diff_MIR) TIR_out = driver.Create('diff_TIR.tif', TET_tem.RasterXSize, TET_tem.RasterYSize, 1, TIR_band.DataType) gdalnumeric.CopyDatasetInfo(TET_tem, TIR_out) TIR_bandOut = TIR_out.GetRasterBand(1) TIR_bandOut.SetNoDataValue(0.0) gdalnumeric.BandWriteArray(TIR_bandOut, diff_TIR) print 'end'