def main(): # parameters if ria > 80 or ria < 10: progress.setText( "Error: Reference incidence angle cannot greater than 80 or less than 10!" ) return output_dir = os.path.dirname(output_raster) if not os.path.exists(sigma0): progress.setText("Error: sigma0 image does not exist!") return if not os.path.exists(local_incidence_angle): progress.setText("Error: local incidence angle image does not exist!") return temp_slope_path = os.path.join( output_dir, "__temp_slope_{}.tif".format( datetime.datetime.now().strftime("%Y%m%d%H%M%S"))) if not get_slope(sigma0, parameter_database, temp_slope_path): progress.setText( "Error: Cannot get the slope from parameter database!") return # sigma sigma0_ds = gdalport.open_image(sigma0) sigma0_arr = sigma0_ds.read_band(1) lia = gdalport.open_image(local_incidence_angle).read_band(1) slope = gdalport.open_image(temp_slope_path).read_band(1) # mask the invalid region #idx = (sigma0_arr != Sigma0_Nodata_value) & (lia != Lia_Nodata_value) & (slope!=-9999) idx = (np.abs(sigma0_arr - Sigma0_Nodata_value) > 0.000001) & ( np.abs(lia - Lia_Nodata_value) > 0.000001) & (slope != -9999) normalization = np.empty_like(sigma0_arr) normalization[:] = -9999 #Sigma0_Nodata_value normalization[idx] = sigma0_arr[idx] - slope[idx] * (lia[idx] - ria) # ouput gdalport.write_image(normalization, output_raster, nodata=[-9999], geotransform=sigma0_ds.geotransform(), projection=sigma0_ds.projection(), option=["COMPRESS=LZW"]) sigma0_ds = None os.remove(temp_slope_path) progress.setText("Done!")
def get_parameter(sigma0, p_db, param_name, outfilename, compress=True): if param_name.startswith("MASK"): param_path = os.path.join(p_db, "datasets", "par_extr") else: param_path = os.path.join(p_db, "datasets", "par_sgrt") # get needed information from dataset temp_ds = gdalport.open_image(sigma0) extent = temp_ds.get_extent() project = temp_ds.projection() geot = temp_ds.geotransform() # create grid system grid = Equi7Grid.Equi7Grid() area = [(extent[0], extent[1]), (extent[2], extent[1]), (extent[2], extent[3]), (extent[0], extent[3])] # close dataset temp_ds = None # file tiles found_tiles = None tiles = grid.search_tiles(area, project, res=500) exist_status = [ os.path.exists(os.path.join(param_path, "EQUI7_AF500M", tile[7:])) for tile in tiles ] if all(exist_status): param_tiles = [ glob.glob( os.path.join(param_path, "EQUI7_AF500M", tile[7:], "*{}*_{}.tif".format(param_name, tile))) for tile in tiles ] if all(param_tiles): found_tiles = [tiles[0] for tiles in param_tiles] if found_tiles is None: progress.setText( "Error: {} parameters are not available in the current parameter database!" .format(param_name)) return False options = {} #if compress: # options["co"] = "COMPRESS=LZW" options["srcnodata"] = -9999 options["dstnodata"] = -9999 ret, info = gdalport.call_gdalwarp(found_tiles, outfilename, t_srs=project, te=" ".join(map(str, extent)), tr="{} {}".format(geot[1], geot[5]), of="GTiff", r="bilinear", **options) if not ret: progress.setText("ERROR: \n" + info) return ret
def warp2tiledgeotiff(TPS, image, output_dir, gdal_path=None, subgrid_ids=None, accurate_boundary=True, e7_folder=True, ftiles=None, roi=None, coverland=True, outshortname=None, withtilenameprefix=False, withtilenamesuffix=True, compress=True, compresstype="LZW", resampling_type="near", overwrite=False, image_nodata=None, tile_nodata=None, tiledtiff=True, blocksize=512): """warp the image to tiles in target TPS. Parameters ---------- grid : TiledProjectionSystem a compatible TPS object, e.g. a Equi7Grid(500) object. image : string Image file path. ouput_dir : string Output directory path. e7_folder: boolean if set (default), the output data will be stored in equi7 folder structure gdal_path : string Gdal utilities location. subgrid_ids : list Only resample to the specified continents, default is to resample to all continents. roi : OGRGeometry Region of interest. The roi will beignored if ftiles keyword is provided ftiles : list of tile names full name of tiles to which data should be resampled coverland : bool Only resample to the tiles that cover land. outshortname : string The short name will be main part of the output tile name. withtilenameprefix : bool Prepend the tile name in the tile file name. withtilenamesuffix : bool Append the tile name in the tile file name. compress : bool The output tiles is compressed or not. resampling_type : string Resampling method. overwrite : bool Overwrite the old tile or not. image_nodata : double The nodata value of input images. tile_nodata : double The nodata value of tile. tiledtiff : bool Set to yes for tiled geotiff output blocksize: integer sets tile width, in x and y direction """ # get the output shortname if not provided grid = TPS if not outshortname: outshortname = os.path.splitext(os.path.basename(image))[0] # find overlapping tiles if ftiles is None: if roi is None: if accurate_boundary: try: roi_geom = gdalport.retrieve_raster_boundary( image, gdal_path=gdal_path, nodata=image_nodata) except Exception as e: print("retrieve_raster_boundary failed:", str(e)) roi_geom = None else: roi_geom = None if roi_geom: ftiles = grid.search_tiles_in_geo_roi(geom_area=roi_geom, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: ds = gdalport.open_image(image) img_extent = ds.get_extent() geo_extent = geometry.extent2polygon(img_extent) geo_sr = osr.SpatialReference() geo_sr.ImportFromWkt(ds.projection()) geo_extent.AssignSpatialReference(geo_sr) ftiles = grid.search_tiles_in_geo_roi(geom_area=geo_extent, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: ftiles = grid.search_tiles_in_geo_roi(geom_area=roi, subgrid_ids=subgrid_ids, coverland=coverland, gdal_path=gdal_path) else: if type(ftiles) != list: ftiles = [ftiles] # keep the full path of the output(resampled) files dst_file_names = [] # resample for each tile sequentially for ftile in ftiles: # create grid folder if e7_folder: grid_folder = "EQUI7_{}".format(ftile[0:6]) tile_path = os.path.join(output_dir, grid_folder, ftile[7:]) if not os.path.exists(tile_path): makedirs(tile_path) else: tile_path = output_dir # make output filename outbasename = outshortname if withtilenameprefix: outbasename = "_".join((ftile, outbasename)) if withtilenamesuffix: outbasename = "_".join((outbasename, ftile)) filename = os.path.join(tile_path, "".join((outbasename, ".tif"))) # get grid tile object # TODO Generalise! Now only the Equi7Grid case is consideres (2 digits for subgrid) gridtile = getattr(grid, ftile[0:2]).tilesys.create_tile(ftile) # prepare options for gdalwarp options = { '-t_srs': gridtile.core.projection.wkt, '-of': 'GTiff', '-r': resampling_type, '-te': " ".join(map(str, gridtile.limits_m())), '-tr': "{} -{}".format(grid.core.res, grid.core.res) } options["-co"] = list() if compress: options["-co"].append("COMPRESS={0}".format(compresstype)) if image_nodata != None: options["-srcnodata"] = image_nodata if tile_nodata != None: options["-dstnodata"] = tile_nodata if overwrite: options["-overwrite"] = " " if tiledtiff: options["-co"].append("TILED=YES") options["-co"].append("BLOCKXSIZE={0}".format(blocksize)) options["-co"].append("BLOCKYSIZE={0}".format(blocksize)) # call gdalwarp for resampling succeed, _ = gdalport.call_gdal_util('gdalwarp', src_files=image, dst_file=filename, gdal_path=gdal_path, options=options) # full path to the output(resampled) files if succeed: dst_file_names.extend([filename]) return dst_file_names
def resample(self, image, res, output_dir, grids=None, roi=None, outshortname=None, withtilenameprefix=True, withtilenamesuffix=False, compress=True, resampling_type="bilinear", image_nodata=None, tile_nodata=None): """Resample the image to tiles. Parameters ---------- image : string Image file path. res : int Resolution of output tiles. ouput_dir : string output path. outshortname : string The short name will be included in the output tiles. compress : bool The output tiles is compressed or not. resampling_type : string resampling method. tile_nodata: double The nodata value of tile. """ if not outshortname: outshortname = os.path.splitext(os.path.basename(image))[0] ds = gdalport.open_image(image) proj = ds.projection() if not roi: extent = ds.get_extent() area = [(extent[0], extent[1]), (extent[2], extent[1]), (extent[2], extent[3]), (extent[0], extent[3])] tiles = self.search_tiles(area, proj, grids=grids, res=res) else: tiles = self.search_tiles(roi, proj, grids=grids, res=res) for tile in tiles: tile_path = os.path.join(output_dir, tile) if not os.path.exists(tile_path): os.mkdir(tile_path) # make output filename outbasename = outshortname if withtilenameprefix: outbasename = "_".join((tile.split("_")[1], outshortname)) if withtilenamesuffix: outbasename = "_".join((outshortname, tile.split("_")[1])) filename = os.path.join(tile_path, "".join((outbasename, ".tif"))) # using python api to resample # if compress: # option = ["COMPRESS=LZW"] # datatype = ds.get_raster_dtype(1) # tile_ds = self.create_dummy_dataset(tile, filename, datatype, options=option) # if tile_nodata: # tile_ds.GetRasterBand(1).SetNoDataValue(tile_nodata) # gdal.ReprojectImage(ds.dataset, tile_ds, ds.projection(), tile_ds.GetProjection(), # gdalport.get_gdal_resampling_type(resampling_type)) # using gdalwarp to resample tile_extent = self.get_tile_extent(tile) tile_project = self.get_projection(tile[0:2]) options = {} if compress: options["co"] = "COMPRESS=LZW" if image_nodata: options["srcnodata"] = image_nodata if tile_nodata: options["dstnodata"] = tile_nodata gdalport.call_gdalwarp([image], filename, t_srs=tile_project, te=" ".join(map(str, tile_extent)), tr="{} -{}".format(res, res), of="GTiff", r=resampling_type, **options)
def retrieve_surface_soil_moisture(sigma0_path, sigma0_nodata, lia_path, lia_nodata, sensor, para_db_path, outfilename): ssm_res = 0.00416667 default_nodata = -9999 # make temp dir temp_dir = os.path.join( os.path.dirname(outfilename), "__temp_{}".format(datetime.datetime.now().strftime("%Y%m%d%H%M%S"))) if not os.path.exists(temp_dir): os.mkdir(temp_dir) #para_db_path = os.path.join(para_db_path, "EQUI7", "params_sgrt") # resample image to 500 Meter(0.00416667 degree) progress.setText("Resampling ... ") sigma0_ds = gdalport.open_image(sigma0_path) extent = sigma0_ds.get_extent() project = sigma0_ds.projection() options = {} options["co"] = "COMPRESS=LZW" options["srcnodata"] = sigma0_nodata options["dstnodata"] = sigma0_nodata temp_sigma0 = os.path.join( temp_dir, "__temp_{}.tif".format(os.path.basename(sigma0_path))) gdalport.call_gdalwarp([sigma0_path], temp_sigma0, t_srs=project, te=" ".join(map(str, extent)), tr="{} {}".format(ssm_res, -ssm_res), of="GTiff", r="average", **options) temp_lia = os.path.join(temp_dir, "__temp_{}.tif".format(os.path.basename(lia_path))) options["srcnodata"] = lia_nodata options["dstnodata"] = lia_nodata gdalport.call_gdalwarp([lia_path], temp_lia, t_srs=project, te=" ".join(map(str, extent)), tr="{} {}".format(ssm_res, -ssm_res), of="GTiff", r="average", **options) # print info progress.setText("Retrieving SSM ... ") # get the parameters dry_path = os.path.join( temp_dir, "__temp_dry_{}".format(os.path.basename(sigma0_path))) if not get_parameter( temp_sigma0, para_db_path, "DRY30", dry_path, compress=True): shutil.rmtree(temp_dir) return wet_path = os.path.join( temp_dir, "__temp_wet_{}".format(os.path.basename(sigma0_path))) if not get_parameter( temp_sigma0, para_db_path, "WET30", wet_path, compress=True): shutil.rmtree(temp_dir) return slope_path = os.path.join( temp_dir, "__temp_slope_{}".format(os.path.basename(sigma0_path))) if not get_parameter( temp_sigma0, para_db_path, "SLOPE", slope_path, compress=True): shutil.rmtree(temp_dir) return # soil moisture retrieval sigma0 = gdalport.open_image(temp_sigma0).read_band(1) plia = gdalport.open_image(temp_lia).read_band(1) slope = gdalport.open_image(slope_path).read_band(1) dry = gdalport.open_image(dry_path).read_band(1) wet = gdalport.open_image(wet_path).read_band(1) idx = (np.abs(sigma0 - sigma0_nodata) > 0.000001) & (np.abs(plia - lia_nodata) > 0.000001) \ & (slope != default_nodata) & (dry != default_nodata) & (wet != default_nodata) if sensor == "ASAR": sigma0[idx] = sigma0[idx] - slope[idx] * (plia[idx] - 30) else: dry[idx] = dry[idx] + slope[idx] * (plia[idx] - 30) wet[idx] = wet[idx] + slope[idx] * (plia[idx] - 30) ssm = np.empty_like(sigma0, dtype=np.float32) ssm[:] = default_nodata ssm[idx] = 100 * (sigma0[idx] - dry[idx]) / (wet[idx] - dry[idx]) # handle values out of 0-100 ssm[(ssm < 0) & (ssm != default_nodata)] = 0 ssm[(ssm > 100) & (ssm != default_nodata)] = 100 #mask mask1_path = os.path.join( temp_dir, "__temp_mask1_{}".format(os.path.basename(sigma0_path))) if get_parameter(temp_sigma0, para_db_path, "MASK1", mask1_path, compress=True): mask = gdalport.open_image(mask1_path).read_band(1) mask_idx = mask != 0 ssm[mask_idx] = default_nodata else: progress.setText( "Error: Mask does not exist in the parameter database!") shutil.rmtree(temp_dir) return # encoding ssm_en = np.empty_like(ssm, dtype=np.uint8) ssm_en[:] = 255 ssm_en[ssm != default_nodata] = ssm[ssm != default_nodata] # ouput the ssm geot = sigma0_ds.geotransform() new_geot = [geot[0], ssm_res, 0, geot[3], 0, -ssm_res] gdalport.write_image(ssm_en, outfilename, geotransform=new_geot, nodata=[255], projection=sigma0_ds.projection(), option=["COMPRESS=LZW"]) # progress.setText("Done!") sigma0_ds = None shutil.rmtree(temp_dir)
def get_slope(sigma0, p_db, temp_slope, compress=True): # obtian soft Id ws_softId, gm_softId = get_latest_pdb(p_db) #parameter_path = os.path.join(parameter_database, "EQUI7", "par_sgrt") gm_param_path = os.path.join(p_db, "Envisat_ASAR", "GM", "parameters", gm_softId, "datasets", "par_sgrt") ws_param_path = os.path.join(p_db, "Envisat_ASAR", "WS", "parameters", ws_softId, "datasets", "par_sgrt") if not os.path.exists(gm_param_path) and not os.path.exists(ws_param_path): progress.setText( "Error: cannot find valid parameters in the parameter database!") return False # get needed information from dataset temp_ds = gdalport.open_image(sigma0) extent = temp_ds.get_extent() project = temp_ds.projection() geot = temp_ds.geotransform() # create grid system grid = Equi7Grid() area = [(extent[0], extent[1]), (extent[2], extent[1]), (extent[2], extent[3]), (extent[0], extent[3])] # get the resolution of reprojected sigma0 sigma_sr = osr.SpatialReference() sigma_sr.ImportFromWkt(project) para_sr = osr.SpatialReference() para_sr.ImportFromWkt(grid.get_projection("AF")) tx = osr.CoordinateTransformation(sigma_sr, para_sr) x1, _, _ = tx.TransformPoint(geot[0], geot[3]) x2, _, _ = tx.TransformPoint(geot[0] + geot[1], geot[3]) res_in_meter = np.abs(x2 - x1) # close dataset temp_ds = None # search subfolder for different resolutions found_tiles = None #subfolders = [ x for x in os.listdir(p_db) if os.path.isdir(os.path.join(p_db, x)) and x.startswith("AF")] subfolders = [ os.path.join(ws_param_path, "EQUI7_AF075M"), os.path.join(gm_param_path, "EQUI7_AF500M") ] # sort the subfolder in a certain order best_subfolder_index = np.argmin( [np.fabs(res_in_meter - int(x[-4:-1])) for x in subfolders]) subfolders[0:best_subfolder_index + 1] = subfolders[best_subfolder_index::-1] for subfolder in subfolders: # file tiles res = int(subfolder[-4:-1]) tiles = grid.search_tiles(area, project, res=res) exist_status = [ os.path.exists(os.path.join(subfolder, tile[7:])) for tile in tiles ] if all(exist_status): corr_tiles = [ glob.glob( os.path.join(subfolder, tile[7:], "*SLOPE*_{}.tif".format(tile))) for tile in tiles ] if all(corr_tiles): found_tiles = [tiles[0] for tiles in corr_tiles] break if found_tiles is None: progress.setText( "Error: cannot find appropriate slope in the current parameter database!" ) return False options = {} #if compress: # options["co"] = "COMPRESS=LZW" options["srcnodata"] = -9999 options["dstnodata"] = -9999 ret, info = gdalport.call_gdalwarp(found_tiles, temp_slope, t_srs=project, te=" ".join(map(str, extent)), tr="{} {}".format(geot[1], geot[5]), of="GTiff", r="bilinear", **options) if not ret: progress.setText("ERROR: \n" + info) return ret