def write_gauge_stage_all_cells(reccsv, dirtif, wdttif, gaugelfp, stagelfp): print(" writing gauge and stage files...") # Reading rec file rec = pd.read_csv(reccsv) # Create a width dataframe dat = gdalutils.get_data(wdttif) geo = gdalutils.get_geo(wdttif) wdt = gdalutils.array_to_pandas(dat, geo, 0, 'gt') wdt.columns = ['x', 'y', 'width'] # Create directions dataframe dat = gdalutils.get_data(dirtif) geo = gdalutils.get_geo(dirtif) drc = gdalutils.array_to_pandas(dat, geo, 0, 'gt') drc.columns = ['x', 'y', 'direction'] # Find widths and directions for every lon, lat in river network gdalutils.assign_val(df2=rec, df2_x='lon', df2_y='lat', df1=wdt, df1_x='x', df1_y='y', label='width', copy=False) gdalutils.assign_val(df2=rec, df2_x='lon', df2_y='lat', df1=drc, df1_x='x', df1_y='y', label='direction', copy=False) # Change numbers (1,2,3,4,5,6,7) to letters (N,S,E,W) rec['direction_let'] = rec['direction'].apply(getdirletter) # Writing .gauge file with open(gaugelfp, 'w') as f: f.write(str(rec.shape[0]) + '\n') rec[['lon', 'lat', 'direction_let', 'width']].to_csv(gaugelfp, index=False, sep=' ', header=False, float_format='%.7f', mode='a') # Writing .stage file with open(stagelfp, 'w') as f: f.write(str(rec.shape[0]) + '\n') rec[['lon', 'lat']].to_csv(stagelfp, index=False, sep=' ', header=False, float_format='%.7f', mode='a')
def multiply_rasters(rast1, rast2, out): dat1 = gdalutils.get_data(rast1) dat2 = gdalutils.get_data(rast2) geo1 = gdalutils.get_geo(rast1) geo2 = gdalutils.get_geo(rast2) dat_masked1 = np.ma.masked_where(dat1 == geo1[11], dat1) dat_masked2 = np.ma.masked_where(dat2 == geo2[11], dat2) res = dat_masked1 * dat_masked2 res.set_fill_value(-9999) gdalutils.write_raster(res.filled(), out, geo1, "Float32", -9999)
def write_tiles_layout(mylist, outfile): codes = [] xmins = [] ymins = [] for tile in mylist: geo = gu.get_geo(tile) xmin = np.round(geo[0]) ymin = np.round(geo[1]) xmins.append(xmin) ymins.append(ymin) codes.append(return_code(xmin, ymin)) xmins = np.unique(np.round(xmins)).astype(int) ymins = np.unique(np.round(ymins)).astype(int) resx = abs(xmins[0] - xmins[1]) resy = abs(ymins[1] - ymins[0]) with open(outfile, 'w') as fout: for y in reversed(range(min(ymins), max(ymins) + resy, resy)): for x in range(min(xmins), max(xmins) + resx, resx): mycode = return_code(x, y) if mycode in codes: idx = np.where(np.array(codes) == mycode)[0][0] fout.write(mylist[idx] + ',') else: fout.write(' ' * 15 + ',') fout.write('\n')
def get_ascii_geo(filename, proj4=None): """ Reads LISFLOOD-FP outputs either in gz or wd file extension GEO info Assumes WGS_84 projection by default """ ext = os.path.basename(filename).split('.')[-1] if ext == 'gz': file = _uncompress_gz(filename) geo = gdalutils.get_geo(file, proj4=proj4) os.remove(file) else: geo = gdalutils.get_geo(filename, proj4=proj4) return geo
def run_simulation(reccsv, dirtif, widthtif, bedtif, runoffcsv, date1, date2, lisfloodfp, outfolder): # Determine end of the simulation, how many days t = (pd.to_datetime(date2, format='%Y-%m-%d') - pd.to_datetime(date1, format='%Y-%m-%d')).days + 1 # Create 1D DEM, synthetic demtif = outfolder + 'dem1d.tif' wdt = gu.get_data(widthtif) geo = gu.get_geo(widthtif) dem = np.where(wdt > 0, 10000, 0) gu.write_raster(dem, demtif, geo, 'Int16', 0) # Convert input files to ASCII widthasc = outfolder + 'width.asc' call(['gdal_translate', '-of', 'AAIGRID', widthtif, widthasc]) demasc = outfolder + 'dem.asc' call(['gdal_translate', '-of', 'AAIGRID', demtif, demasc]) bedasc = outfolder + 'bed.asc' call(['gdal_translate', '-of', 'AAIGRID', bedtif, bedasc]) # Write LISFLOOD-FP files bcilfp = outfolder + 'lfp.bci' write_bci(bcilfp, runoffcsv) bdylfp = outfolder + 'lfp.bdy' write_bdy(bdylfp, runoffcsv, t) evaplfp = outfolder + 'lfp.evap' write_evap(evaplfp, t) gaugelfp = outfolder + 'lfp.gauge' stagelfp = outfolder + 'lfp.stage' write_gauge_stage_all_cells(reccsv, dirtif, widthtif, gaugelfp, stagelfp) parlfp = outfolder + 'lfp.par' write_par(parlfp=parlfp, bcilfp=bcilfp, bdylfp=bdylfp, evaplfp=evaplfp, gaugelfp=gaugelfp, stagelfp=stagelfp, dembnktif=demasc, wdttif=widthasc, bedtif=bedasc, t=t) # Run simulation call([lisfloodfp, '-v', 'lfp.par'], cwd=outfolder)
def create_dir_d4(dirtaud4, dirtaud8, dirtau_maskd4): dat1 = gdalutils.get_data(dirtaud8) dat2 = gdalutils.get_data(dirtau_maskd4) geo = gdalutils.get_geo(dirtaud8) A = np.where(dat2 > 0) dat1[A] = dat2[A] gdalutils.write_raster(dat1, dirtaud4, geo, "Int16", -32768)
def d82d4(filedir, filediro, fileneto): """ Returns direction and river netwrok maps in D4 """ nodata = -32768. dirdata = gdalutils.get_data(filedir) dirgeo = gdalutils.get_geo(filedir) data, net = cy_d82d4(np.int16(dirdata), np.int16(nodata)) gdalutils.write_raster(np.int16(data), filediro, dirgeo, "Int16", nodata) gdalutils.write_raster(np.int16(net), fileneto, dirgeo, "Int16", nodata)
def rastermask(file, mask, fmt, outp): """ Mask input array following a defined mask (1,0) """ nodata = -32768 filedata = gdalutils.get_data(file) maskdata = gdalutils.get_data(mask) filegeo = gdalutils.get_geo(file) data = cy_rastermask(np.float64(filedata), np.int16(maskdata)) gdalutils.write_raster(np.float64(data), outp, filegeo, fmt, nodata)
def rasterthreshold(file, thres, fmt, outp): """ Output a raster based on a threshold (larger-equal-than) """ nodata = -1 filedata = gdalutils.get_data(file) filegeo = gdalutils.get_geo(file) data = cy_rasterthreshold(np.float64(filedata), np.float64(thres), np.float64(nodata)) gdalutils.write_raster(np.float64(data), outp, filegeo, fmt, nodata)
def step_04(): A = gu.get_data('delta_surf_interp.tif') B = gu.get_data(fill_demf) C = gu.get_data(void_demf) geo = gu.get_geo(void_demf) mysum = A+B final = np.where(C==nodata,mysum,C) final[(final>=8000) | (final<=-8000)] = nodata gu.write_raster(final,'dem.tif',geo,'Float64',nodata)
def calculate_area(filename, output): geo = gdalutils.get_geo(filename) nx = np.int32(geo[4]) ny = np.int32(geo[5]) resx = np.float32(geo[6]) resy = np.float32(geo[7]) x = np.float32(geo[8]) y = np.float32(geo[9]) dat = calc_area(nx, ny, resx, resy, x, y) gdalutils.write_raster(np.array(dat), output, geo, "Float32", -9999)
def step_01(): geo = gu.get_geo(void_demf) void_dem = gu.get_data(void_demf) fill_dem = gu.get_data(fill_demf) delta_surf = void_dem - fill_dem delta_surf[(delta_surf>=8000) | (delta_surf<=-8000)] = nodata delta_surf[delta_surf==0] = nodata gu.write_raster(delta_surf,'delta_surf_wt_voids.tif',geo,'Float64',nodata)
def burn_banks_dem(dembnktif, demtif, fixbnktif): print(" burning banks in dem...") nodata = -9999 fout = dembnktif base = gdalutils.get_data(demtif) basegeo = gdalutils.get_geo(demtif) new = gdalutils.get_data(fixbnktif) out = np.where(new > 0, new, base) gdalutils.write_raster(out, fout, basegeo, "Float32", nodata)
def get_tiles_by_extent(xmin, ymin, xmax, ymax, tilesdir): # Reading tiles filenames, assuming they are tif files mylist = sorted(glob(tilesdir + '/*')) mylist_area = [] for tile in mylist: geo = gu.get_geo(tile) if (geo[0] >= xmin) & (geo[1] >= ymin) & (geo[2] <= xmax) & (geo[3] <= ymax): mylist_area.append(tile) return mylist_area
def burn_banks_dem_1D(dembnktif, demtif, fixbnktif): print(" burning banks in dem 1D...") nodata = -9999 fout = dembnktif base = gdalutils.get_data(demtif) basegeo = gdalutils.get_geo(demtif) new = (np.ma.masked_values(gdalutils.get_data(fixbnktif), nodata) + 10000).filled(nodata) out = np.where(new > 0, new, base) gdalutils.write_raster(out, fout, basegeo, "Float32", nodata)
def write_outlets(outshp, dirtif_mask): proj = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' dat = gdalutils.get_data(dirtif_mask) geo = gdalutils.get_geo(dirtif_mask) rows, cols = np.where(dat > 0) x = [] y = [] for row, col in zip(rows, cols): A = find_neighbours(dat, row, col) if np.any(A < 0): x.append(geo[8][col]) y.append(geo[9][row]) # Initiate shapefile w = shapefile.Writer(shapefile.POINT) w.field('x') w.field('y') w.field('id') # Write coordinate points in shapefile for i in range(len(x)): w.point(x[i], y[i]) w.record(x[i], y[i], i) w.save(outshp) fname = os.path.dirname(outshp)+'/' + \ os.path.basename(outshp).split('.')[0] + '.prj' prj = open(fname, "w") srs = osr.SpatialReference() srs.ImportFromProj4(proj) prj.write(srs.ExportToWkt()) prj.close() typ = "Byte" fmt = "GTiff" nodata = 0 name1 = os.path.dirname(outshp)+'/' + \ os.path.basename(outshp).split('.')[0] + '.shp' name2 = os.path.dirname(outshp)+'/' + \ os.path.basename(outshp).split('.')[0] + '.tif' subprocess.call([ "gdal_rasterize", "-a_nodata", str(nodata), "-ot", typ, "-of", fmt, "-tr", str(geo[6]), str(geo[7]), "-burn", "1", "-a_srs", proj, "-te", str(geo[0]), str(geo[1]), str(geo[2]), str(geo[3]), name1, name2 ])
def getdir(rec, dirtif): dat = gdalutils.get_data(dirtif) geo = gdalutils.get_geo(dirtif) dirdf = gdalutils.array_to_pandas(dat, geo, 0, 'gt') recdf = gdalutils.assign_val(df2=rec.reset_index( ), df2_x='lon', df2_y='lat', df1=dirdf, df1_x='x', df1_y='y', label='z', copy=True) # Direction of outlet is given by the maximum repetitions of directions in the last 10 points _dir = recdf.sort_values(by='distance').iloc[0:10].groupby('z')[ 'z'].count().idxmax() return _dir
def directions_esri(inputrast, outputrast): """ Function to change convetion from a DIR file This script changes these numbers from TauDEM convention, 1,2,3... to ESRI convention 128,64,32,.. """ nodata = -32768 data = gdalutils.get_data(inputrast) datageo = gdalutils.get_geo(inputrast) data_esri = cy_directions_esri(np.int16(data), np.int16(nodata)) gdalutils.write_raster(np.int16(data_esri), outputrast, datageo, "Int16", nodata)
def directions_tau(inputrast, outputrast): """ Function to use in Shell to change convetion from a DIR file HydroSHEDS uses ESRI convention 128,64,32,.. this script changes these numbers to TauDEM convention, 1,2,3... """ nodata = -32768 data = gdalutils.get_data(inputrast) datageo = gdalutils.get_geo(inputrast) datatau = cy_directions_tau(np.int16(data), np.int16(nodata)) gdalutils.write_raster(np.float64(datatau), outputrast, datageo, "Int16", nodata)
def rasterresample(method, demf, netf, output, outlier, hrnodata, thresh, nproc): print(" running rasterresample.py...") fname1 = demf fname2 = output # coordinates for bank elevations are based in river network mask net = gdalutils.get_data(netf) geo = gdalutils.get_geo(netf) # consider all pixels in net30 including river network pixels iy, ix = np.where(net > -1) x = geo[8][ix] y = geo[9][iy] # Split x and y in nproc parts split_x = np.array_split(x, nproc) split_y = np.array_split(y, nproc) # Define a queue queue = mp.Queue() # Setup a list of processes that we want to run processes = [] processes = [ mp.Process(target=calc_resampling_mp, args=(i, queue, fname1, hrnodata, split_x[i], split_y[i], thresh, outlier, method)) for i in range(len(split_x)) ] # Run processes for p in processes: p.start() # Get process results from the queue results = [queue.get() for p in processes] # Retrieve results in a particular order results.sort() results = [r[1] for r in results] # Stack results horizontally elev = np.hstack(results).reshape(net.shape) # Replace NaN by hrnodata elev[np.isnan(elev)] = hrnodata # elev = calc_resampling(fname1,hrnodata,x,y,ix,iy,thresh,outlier,method) gdalutils.write_raster(elev, fname2, geo, "Float32", hrnodata)
def depth_raster(w, netf, fdepth, thresh): """ From a raster of depths this subroutine finds nearest depth to every river pixel in grid """ # Reading river network file dat_net = gdalutils.get_data(netf) geo_net = gdalutils.get_geo(netf) iy, ix = np.where(dat_net > 0) xx = geo_net[8][ix] yy = geo_net[9][iy] # Reading depth source file dat = gdalutils.get_data(fdepth) geo = gdalutils.get_geo(fdepth) iy, ix = np.where(dat > -9999) xdat = geo[8][ix] ydat = geo[9][iy] depth = [] for x, y in zip(xx, yy): try: dis, ind = misc_utils.near_euc(xdat, ydat, (x, y)) if dis <= thresh: val = dat[iy[ind], ix[ind]] depth.append(val) else: depth.append(np.nan) except ValueError: depth.append(np.nan) for x, y, mydepth in zip(xx, yy, depth): w.point(x, y) w.record(x, y, mydepth) return w
def find_nearest_mean_mask(ncf, ncproj, lon, lat, proj, thresh_dis, thresh_mean=5): """ Apply a threshold to the mean discharge Based on the thresholded map, find nearest value to lon, lat in a given perimiter and var threhsold For JRC data default values are 5 m3s-1 and 2.5 Km """ # JRC data set projection is EPSG:3035 # It's required to convert to WGS84 to perform distance calculation crs_wgs84 = Proj(init=proj) crs_nc = Proj(init=ncproj) # Reading mean mask dat = gu.get_data(ncf) geo = gu.get_geo(ncf) # Create df, a pandas dataframe with values larger than "thresh_mean=5" df = gu.array_to_pandas(dat, geo, thresh_mean, 'ge') # Creating two new columns with projected values coords = transform(crs_nc, crs_wgs84, df['x'].values, df['y'].values) df['lon'] = coords[0] df['lat'] = coords[1] # Calcualte distance to lat and lon point to every point in the dataframe vec = gu.haversine.haversine_array(np.array(df['lat'], dtype='float32'), np.array(df['lon'], dtype='float32'), np.float32(lat), np.float32(lon)) idx = np.argmin(vec) dis = gu.haversine.haversine(df.loc[idx, 'lat'], df.loc[idx, 'lon'], lat, lon) if dis <= thresh_dis: near_x = df.loc[idx, 'x'] near_y = df.loc[idx, 'y'] mymean = df.loc[idx, 'z'] df = None return near_x, near_y, mymean, dis else: df = None return None, None, None, None
def getdepths(proj, netf, method, output, **kwargs): print(" runnning getdepths.py...") fname = output w = shapefile.Writer(shapefile.POINT) w.field('x') w.field('y') w.field('depth') if method == "depth_raster": depth_raster(w, netf, **kwargs) elif method == "depth_geometry": depth_geometry(w, **kwargs) elif method == "depth_manning": depth_manning(w, **kwargs) else: sys.exit("ERROR method not recognised") # write final value in a shapefile w.save("%s.shp" % fname) # write .prj file prj = open("%s.prj" % fname, "w") srs = osr.SpatialReference() srs.ImportFromProj4(proj) prj.write(srs.ExportToWkt()) prj.close() nodata = -9999 fmt = "GTiff" name1 = output + ".shp" name2 = output + ".tif" mygeo = gdalutils.get_geo(netf) subprocess.call([ "gdal_rasterize", "-a_nodata", str(nodata), "-of", fmt, "-tr", str(mygeo[6]), str(mygeo[7]), "-a", "depth", "-a_srs", proj, "-te", str(mygeo[0]), str(mygeo[1]), str(mygeo[2]), str(mygeo[3]), name1, name2 ])
def step_03(): geo = gu.get_geo(void_demf) nx = geo[4] ny = geo[5] xmin = geo[0] xmax = geo[2] ymin = geo[1] ymax = geo[3] subprocess.call(['gdal_grid','--config','GDAL_NUM_THREADS','ALL_CPUS', '-a','invdist', '-of','GTiff', '-ot','Float64', '-txe', str(xmin), str(xmax), '-tye', str(ymin), str(ymax), '-outsize', str(nx), str(ny), '-l','delta_surf_wt_voids', 'delta_surf_wt_voids.vrt','delta_surf_interp.tif'])
def extract_from_zip(zipresults, date, date1, date2, var, proj4, outfile): """ Extract variable per date then convert to GTIFF Example ------- import lfptools.utils as lfp proj4 = '+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs' lfp.extract_from_zip('./176.zip','2002-08-20','1990-01-01','2014-12-31','wd',proj4,'./tmp.tif') """ tmpdir = os.path.dirname(outfile) + '/tmp/' try: os.mkdir(tmpdir) except FileExistsError: pass # Open zip myzip = zipfile.ZipFile(zipresults) # Get list of files in zip mylist = sorted(myzip.namelist()) myvar = [i for i in mylist if i.endswith('.' + var)] # Simulation times dates = pd.date_range(date1, date2) # Retrieve filenames based on dates ix = np.where(dates == date)[0][0] # Extract ASCII file myzip.extract(myvar[ix], tmpdir) # Get info from ASCII fname = tmpdir + myvar[ix] dat = gdalutils.get_data(fname) geo = gdalutils.get_geo(fname) geo[10] = _return_projection(proj4) gdalutils.write_raster(dat, outfile, geo, 'Float64', geo[-1]) # Remove temp folder shutil.rmtree(tmpdir)
def getbedelevs(bnkf, dptf, netf, output, proj): print(" running getbedelevs.py...") bnk = gpd.read_file(bnkf) dpt = gpd.read_file(dptf) print('loaded data') print('calculating bed from banks and depth') bnk['bedelev'] = bnk['elevadj'].astype(np.float32) - dpt['depth'].astype( np.float32) print(bnk.keys()) # print(bnk['bedelev']) bed = bnk[['x', 'y', 'geometry', 'bedelev']] # bnk.columns = ['x', 'y', 'bedelev'] print('Writing out data') # Just write bed dataframe to file, rather than creating a new dataframe with the same data # mybed = gpd.GeoDataFrame(bnk, crs={'init': 'epsg:4326'}, geometry=[ # Point(xy) for xy in zip(bed.x.astype(float), bed.y.astype(float))]) bed.to_file(output + '.shp') nodata = -9999 fmt = "GTiff" # name1 = output # name2 = os.path.dirname(output) + '/' + \ # os.path.basename(output).split('.')[0] + '.tif' name1 = output + '.shp' name2 = output + '.tif' mygeo = gdalutils.get_geo(netf) subprocess.call([ "gdal_rasterize", "-a_nodata", str(nodata), "-of", fmt, "-ot", "Float32", "-co", "COMPRESS=DEFLATE", "-tr", str(mygeo[6]), str(mygeo[7]), "-a", "bedelev", "-a_srs", proj, "-te", str(mygeo[0]), str(mygeo[1]), str(mygeo[2]), str(mygeo[3]), name1, name2 ])
dptf=dpt_shp + '.shp', netf=netf, output=bed_shp, proj='+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs') ############################################################################################# # Crop LISFLOOD-FP domain # First clip floats: output_tifs = [ bed_shp + '.tif', wdt_shp + '.tif', dem, bnkfix_shp + '.tif', slp_shp + '.tif', bfq_shp + '.tif', dpt_shp + '.tif' ] for tif in output_tifs: # Snap extent to match input tif grid cells geo = gdalutils.get_geo(tif) xmin0, ymin0, xmax0, ymax0 = regbound # Geo has format [xmin, ymin, xmax, ymax, xn, yn, xres, yres, ....] xmin = geo[0] + np.floor((xmin0 - geo[0]) / geo[6]) * geo[6] ymin = geo[1] + np.floor((ymin0 - geo[1]) / geo[7]) * geo[7] xmax = geo[2] + np.floor((xmax0 - geo[2]) / geo[6]) * geo[6] ymax = geo[3] + np.floor((ymax0 - geo[3]) / geo[7]) * geo[7] print('Clipextent:', xmin, xmax, ymin, ymax) tifclip = outdir1 + '/' + os.path.basename( tif[:-4]) + '_' + regname + '.tif' if not os.path.exists(tifclip) or overwrite: call([ "gdalwarp", '-ot', 'Float32', "-te", str(xmin), str(ymin), str(xmax),
def fixelevs(source, output, netf, recf, proj, method): print(" running fixelevs.py...") # Reading XXX_net.tif file geo = gdalutils.get_geo(netf) # Reading XXX_rec.csv file rec = pd.read_csv(recf) # Reading XXX_bnk.shp file bnk_gdf = gpd.read_file(source) # Initiate output shapefile w = shapefile.Writer(shapefile.POINT) w.field('x') w.field('y') w.field('elevadj') # Retrieving bank elevations from XXX_bnk.shp file # Values are stored in rec['bnk'] rec['bnk'] = bnk_gdf['elev'].astype(float) # Adjusting bank values, resulting values # are stored in rec['bnk_adj'] # coordinates are grouped by REACH number rec['bnk_adj'] = 0 recgrp = rec.groupby('reach') for reach, df in recgrp: ids = df.index dem = df['bnk'] # calc bank elevation if method == 'yamazaki': adjusted_dem = bank4flood(dem) elif method == 'lowless': adjusted_dem = lowless(dem) else: sys.exit('Method not recognised') rec['bnk_adj'][ids] = adjusted_dem # Writing .shp resulting file for i in rec.index: w.point(rec['lon'][i], rec['lat'][i]) w.record(rec['lon'][i], rec['lat'][i], rec['bnk_adj'][i]) w.save("%s.shp" % output) # write .prj file prj = open("%s.prj" % output, "w") srs = osr.SpatialReference() srs.ImportFromProj4(proj) prj.write(srs.ExportToWkt()) prj.close() nodata = -9999 fmt = "GTiff" name1 = output + ".shp" name2 = output + ".tif" subprocess.call([ "gdal_rasterize", "-a_nodata", str(nodata), "-of", fmt, "-co", "COMPRESS=DEFLATE", "-tr", str(geo[6]), str(geo[7]), "-a", "elevadj", "-a_srs", proj, "-te", str(geo[0]), str(geo[1]), str(geo[2]), str(geo[3]), name1, name2 ])
dem_downsample = os.path.join( indir, 'dem_downsample_' + str(nwindow * 3) + 's.tif') acc_downsample = os.path.join( indir, 'acc_downsample_' + str(nwindow * 3) + 's.tif') ord_downsample = os.path.join( indir, 'ord_downsample_' + str(nwindow * 3) + 's.tif') f_dir = os.path.join(indir, 'dir_d8_downsample_' + str(nwindow * 3) + 's.tif') f_net = os.path.join(indir, 'net_downsample_' + str(nwindow * 3) + 's.tif') f_outlets = os.path.join( indir, 'outlets_downsample_' + str(nwindow * 3) + 's.tif') ######################################################################################### # Get geometry information from acctif, assume all arrays have the same geometry # geo = gdalutils.get_geo(acctif) print(geo) # modify number of cells: divide by nwindow and round up (block_reduce pads the arrays) geo[4] = int(np.ceil(geo[4] / nwindow)) geo[5] = int(np.ceil(geo[5] / nwindow)) # modify resolution: multiply by nwindow geo[6] = geo[6] * nwindow geo[7] = geo[7] * nwindow ######################################################################################### # Downsample dem array if not os.path.exists(dem_downsample): data = gdalutils.get_data(demtif) print('inshape', data.shape) downsample_dem = block_reduce(data, block_size=(nwindow, nwindow),
def calc_banks(banktif, bedtif, fname_disch, fname_stage, reccsv, return_per, layer, outfolder): # Loading stage and discharge files # Try statement added since some discharge and stage files are empty, exit program try: stage = lfp.read_stage(fname_stage) df_locs = lfp.read_stage_locs(fname_stage) df_locs.index = range(len(stage.columns)) discharge = lfp.read_discharge(fname_disch) stage.columns = range(len(discharge.columns)) discharge.columns = range(len(stage.columns)) except ValueError: sys.exit('ERROR: Probably stage or discharge file is empty') # Loading Return Perid database (eg. FLOPROS) gdf_defenses = gpd.read_file(return_per) # Getting protection level from Return Period dataset at every cell # River points have been buffered to allow disaggrement between geolocations # By buffering some points get more than one value, maximum flood protection is selected mygeom = [Point(x, y) for x, y in zip(df_locs['x'], df_locs['y'])] gdf_locs = gpd.GeoDataFrame(crs={'init': 'epsg:4326'}, geometry=mygeom) gdf_locs_buf = gpd.GeoDataFrame( crs={'init': 'epsg:4326'}, geometry=gdf_locs.buffer(0.1)) gdf_locs_ret = gpd.sjoin(gdf_locs_buf, gdf_defenses, op='intersects') gdf_locs_ret['index'] = gdf_locs_ret.index gdf_locs_ret = gdf_locs_ret.sort_values( layer, ascending=False).drop_duplicates('index').sort_values('index') # Estimating error in discharge fitting dis_err = [] for i in range(discharge.shape[1]): try: dis_err.append(get_discharge_error(discharge[i])) except (KeyError,np.core._internal.AxisError): dis_err.append(0) # Estimating a defenses-related discharge dis_df = [] for i in range(discharge.shape[1]): ret_pe = gdf_locs_ret['MerL_Riv'][i] try: dis_df.append(get_discharge_returnperiod(discharge[i], ret_pe)) except (KeyError,np.core._internal.AxisError): dis_df.append(np.nan) # Estimating error in stage fitting stg_err = [] for i in range(discharge.shape[1]): try: stg_err.append(get_stage_error(discharge[i], stage[i])) except (RuntimeError, TypeError): stg_err.append(0) # Estimating a defenses-related stage stg_df = [] for i in range(discharge.shape[1]): try: stg_df.append(get_stage_discharge( discharge[i], stage[i], dis_df[i])) except (RuntimeError, TypeError): stg_df.append(np.nan) # Preparing a summary with variables retrived df_locs['dis_df'] = dis_df df_locs['stg_df'] = stg_df df_locs['dis_err'] = dis_err df_locs['stg_err'] = stg_err # Read REC file rec = pd.read_csv(reccsv) # Convert dataframe to geodataframe, join with rec gdf_sum = gpd.GeoDataFrame(df_locs, crs={'init': 'epsg:4326'}, geometry=[ Point(x, y) for x, y in zip(df_locs['x'], df_locs['y'])]) gdf_rec = gpd.GeoDataFrame(rec, crs={'init': 'epsg:4326'}, geometry=[ Point(x, y) for x, y in zip(rec['lon'], rec['lat'])]) gdf_rec_buf = gpd.GeoDataFrame( rec, crs={'init': 'epsg:4326'}, geometry=gdf_rec.buffer(0.001)) gdf_sum_rec = gpd.sjoin(gdf_sum, gdf_rec_buf, how='inner', op='intersects') gdf_sum_rec.sort_values('index_right', inplace=True) # Save errors in a GeoJSON file try: gdf_sum_rec.to_file(outfolder + 'bnk_err.geojson', driver='GeoJSON') except: os.remove(outfolder + 'bnk_err.geojson') gdf_sum_rec.to_file(outfolder + 'bnk_err.geojson', driver='GeoJSON') # Score should greater than 0.85 for both Discharge and Stage to be accepted, otherwise NaN gdf_err = gdf_sum_rec['stg_df'].where( (gdf_sum_rec['dis_err'] > 0.85) & (gdf_sum_rec['stg_err'] > 0.85)) # Fill with NaN stg_df not filling that condition gdf_sum_rec['stg_df'] = gdf_err # NaNs are filled repating last/first number per link gdf_sum_rec_fillna = gdf_sum_rec.groupby('link').fillna( method='bfill').fillna(method='ffill') gdf_sum_rec_fillna['link'] = gdf_sum_rec['link'] # Read data and geo for bedtif bed = gu.get_data(bedtif) geo = gu.get_geo(bedtif) # Convert dataframes to arrays df_locs_stgdf = gdf_sum_rec_fillna[['x', 'y', 'stg_df']] df_locs_stgdf.columns = ['x', 'y', 'z'] arr_stgdf = gu.pandas_to_array(df_locs_stgdf, geo, 0) # Sum bankfull stage and defenses-related stage to bed arr_bnkdf = (bed + arr_stgdf) # Write burned banks in ASC and TIF files gu.write_raster(arr_bnkdf, banktif, geo, 'Float64', 0)