def single_bands_to_multiband(gdal_bands_list, output=None): """ Convert several gdal single file to a single gdal datasource""" # Get mask # src_ds = gdal.OpenShared(gdal_bands_list[0]) src_ds = GdalReader().gdal2ds(gdal_bands_list[0]) # src_ds.SetMetadataItem('FilePath', gdal_bands_list[0]) # Get output if not output: output = 'image_multiband' # Create new ds # tmp_ds = gdal.GetDriverByName('MEM').CreateCopy('', src_ds, 0) out_ds = gdalr.GdalReader().create_ds(output, src_ds.RasterXSize, src_ds.RasterYSize, len(gdal_bands_list), src_ds.GetRasterBand(1).DataType) out_ds.SetProjection(src_ds.GetProjection()) out_ds.SetGeoTransform(src_ds.GetGeoTransform()) i = 0 for band_dataset in gdal_bands_list: i = i + 1 band_ds = GdalReader().gdal2ds(band_dataset) # mask_ds = gdal.OpenShared(band_dataset) array_i = band_ds.GetRasterBand(1).ReadAsArray() out_ds.GetRasterBand(i).WriteArray(array_i) band_ds = None del array_i if GdalReader().isvalid(out_ds): return out_ds
def merge(src_ds_list, outname, smooth_edges=False): # First layer metadata src_ds = GdalReader().gdal2ds(src_ds_list[0]) src_ds_list = [GdalReader().gdal2ds(r) for r in src_ds_list] geotransform = src_ds.GetGeoTransform() xres = geotransform[1] yres = geotransform[5] projection = src_ds.GetProjection() nodata = src_ds.GetRasterBand(1).GetNoDataValue() # Get common extent xmin, xmax, ymin, ymax = GdalReader().get_extent(src_ds) bands = src_ds.RasterCount for src_i in src_ds_list: xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i) xmax = max(xmax, xmax_i) xmin = min(xmin, xmin_i) ymax = max(ymax, ymax_i) ymin = min(ymin, ymin_i) bands = max(bands, src_i.RasterCount) # Aligne Pixels xmin = math.floor(xmin / xres) * xres xmax = math.ceil(xmax / xres) * xres ymin = math.floor(ymin / -yres) * -yres ymax = math.ceil(ymax / -yres) * -yres # Create output if it does not already exist. geotransform = [xmin, xres, 0, ymax, 0, yres] xsize = int(math.ceil((xmax - xmin) / xres)) ysize = int(math.ceil((ymin - ymax) / yres)) # Copy data from source files into output file 1. out_array = np.empty((ysize, xsize)) out_array[:] = np.nan borders = [] for src_i in src_ds_list: for band in xrange(1, src_ds.RasterCount + 1): geotransform_i = src_i.GetGeoTransform() if not int(xres) == int(geotransform_i[1]) or not int(yres) == int( geotransform_i[5]): logging.error( 'Merge cannot be performed because the layer resolution are different: ' + str(xres) + ',' + str(yres) + ' vs. ' + str(geotransform_i[1]) + ',' + str(geotransform_i[5])) continue xmin_i, xmax_i, ymin_i, ymax_i = GdalReader().get_extent(src_i) xoff = int(math.ceil((xmin_i - xmin) / xres)) yoff = int(math.ceil((ymax_i - ymax) / yres)) x_size_i = src_i.RasterXSize y_size_i = src_i.RasterYSize array_i = GdalReader().ds2array(src_i) out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = array_i #slice_i = out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] #out_array[yoff:yoff + y_size_i, xoff:xoff + x_size_i] = np.where( # np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])), slice_i, array_i[band - 1]) # Edges smoothing if smooth_edges: mask = np.where( np.ma.getmask(np.ma.masked_invalid(array_i[band - 1])), np.nan, 1) if smooth_edges: borders_i = [ ([i + yoff, j + xoff] if 0 < [ mask[i - 1, j], mask[i + 1, j], mask[i, j - 1], mask[i, j + 1] ].count(1) < 4 else None) if (1 <= i < mask.shape[0] - 1) and (1 <= j < mask.shape[1] - 1) else None # ([i+yoff, j+xoff] if mask[i, j] == 1 else None) for i, j in np.ndindex(mask.shape) ] borders = borders + borders_i # Edges smoothing if smooth_edges: for k in borders: if k: out_array[k[0], k[1]] = np.nanmean(out_array[k[0] - 1:k[0] + 1, k[1] - 1:k[1] + 1]) return GdalReader().array2ds(src_array=out_array, output=outname, projection=projection, geotransform=geotransform, nodata=nodata)