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
######################################################################################### # 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), func=np.mean, cval=-9999) print('downsampled dem', downsample_dem.shape) gdalutils.write_raster(downsample_dem, dem_downsample, geo, 'Float32', -9999) ######################################################################################### # Downsample ord and acc arrays (for calculation of directions) # if not os.path.exists(ord_downsample) or not os.path.exists( acc_downsample): data = gdalutils.get_data(ordtif)
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)
def split(argv): """ Info: ----- Split area per basins Check if basin area is larger than 100 Km2, if yes, it continues Check if number of pixels in river network is larger than 35, if yes, continues Clip tree and coord files To Clip .tif files, it checks outlet direction and increases 0.1 degrees from boundaries but no in the outlet boundary since it will obstruct the outflow. There is a “connections” function which finds connections between links. Basically, creates a NNN_rec.csv file containing all river coordinates, three classifications: 1) classification per “link” (given by TAUDEM), 2) classification per reach (coordinates belonging to longer link) and 3) classification per downstream link (given by TAUDEM), other features were added like strahler number (given by TAUDEM) and distance to outlet (given by TAUDEM). Dependencies: ------------- TAUDEM : streamnet, gagewatershed GDAL : gdalwarp Pandas, Numpy, GDAL Python API, gdalutils, prepdata_utils Inputs: ------- basnum : Basin number or the keyword “all” to process cattif : A GDAL raster file containing basin numbers (one number per basin) demtif : DEM in GDAL raster acctif : Accumulation GDAL raster nettif : River network GDAL raster wthtif : River width GDAL raster dirtif : Flow directions GDAL raster aretif : Area GDAL raster otltif : Outlets GDAL raster tretxt : Tree file from TAUDEM cootxt : Coord file from TAUDEM outdir : Out path Outputs (If running at 30s): ---------------------------- NNN_acc.tif NNN_coo.csv NNN_dem.tif NNN_dir.tif NNN_net.tif NNN_rec.csv NNN_tre.csv NNN_wth.tif """ opts, args = getopt.getopt(argv, "i:") for o, a in opts: if o == "-i": inifile = a config = configparser.SafeConfigParser() config.read(inifile) basnum = str(config.get('split', 'basnum')) cattif = str(config.get('split', 'cattif')) demtif = str(config.get('split', 'demtif')) acctif = str(config.get('split', 'acctif')) nettif = str(config.get('split', 'nettif')) wthtif = str(config.get('split', 'wthtif')) dirtif = str(config.get('split', 'dirtif')) otltif = str(config.get('split', 'otltif')) aretif = str(config.get('split', 'aretif')) tretxt = str(config.get('split', 'tretxt')) cootxt = str(config.get('split', 'cootxt')) outdir = str(config.get('split', 'outdir')) print(" running split.py...") # Clip input maps per catchment if basnum == "all": # Loading data catarr = gdalutils.get_data(cattif) # Loop over all catchment numbers # Catchments should be numbered and > 0 for nc in np.unique(catarr[catarr > 0]): basinsplit(nc, outdir, cattif, demtif, acctif, nettif, wthtif, dirtif, aretif, otltif, tretxt, cootxt) else: # Process a single catchments b = basnum.split(',') for nc in b: print('processing basin number: ' + nc) basinsplit(int(nc), outdir, cattif, demtif, acctif, nettif, wthtif, dirtif, aretif, otltif, tretxt, cootxt)
def basinsplit(ncatch, outdir, cattif, demtif, acctif, nettif, wthtif, dirtif, aretif, otltif, tretxt, cootxt): # Get extend for every catchment and area catarr = gdalutils.get_data(cattif) try: dat = catarr == ncatch except: sys.exit('ERROR invalid basin number') catgeo = gdalutils.get_geo(cattif) area = gdalutils.get_data(aretif) outlet = gdalutils.get_data(otltif) direc = gdalutils.get_data(dirtif) row, col = np.where(dat) _sum = np.sum(dat*area) if _sum >= 100: # be sure basin is larger than 100 Km2 xmin = catgeo[8][min(col)] xmax = catgeo[8][max(col)] ymin = catgeo[9][max(row)] ymax = catgeo[9][min(row)] # Clip input rasters netarr_tmp, netgeo_tmp = gdalutils.clip_raster( nettif, xmin, ymin, xmax, ymax) catarr_tmp, catgeo_tmp = gdalutils.clip_raster( cattif, xmin, ymin, xmax, ymax) # Mask only the catchment and fill with zeros netarr_tmp = np.where(catarr_tmp == ncatch, netarr_tmp, 0) if netarr_tmp.sum() >= 35: # be sure river network is long enough # Clipping tree and coord files based on nettif > 0, coordinates tree = misc_utils.read_tree_taudem(tretxt) coor = misc_utils.read_coord_taudem(cootxt) iy, ix = np.where(netarr_tmp > 0) Xrav = netgeo_tmp[8][ix] Yrav = netgeo_tmp[9][iy] # Clipping coord file (it may be improved, calculation takes some time) lfp_coor = pd.DataFrame() for i in range(len(Xrav)): dis, ind = misc_utils.near_euc( coor['lon'].values, coor['lat'].values, (Xrav[i], Yrav[i])) if dis <= 0.01: lfp_coor = lfp_coor.append(coor.loc[ind, :]) lfp_coor = lfp_coor[['lon', 'lat', 'distance', 'elev', 'contr_area']] lfp_coor.index.name = 'index' lfp_coor.sort_index(inplace=True) # Remove duplicates just in case lfp_coor.drop_duplicates(inplace=True) # Clipping tree file lfp_tree = pd.DataFrame() for i in tree.index: sta = tree.loc[i, 'start_pnt'] end = tree.loc[i, 'end_pnt'] lon1 = coor.loc[sta, 'lon'] lat1 = coor.loc[sta, 'lat'] lon2 = coor.loc[end, 'lon'] lat2 = coor.loc[end, 'lat'] dis1, ind1 = misc_utils.near_euc( lfp_coor['lon'].values, lfp_coor['lat'].values, (lon1, lat1)) dis2, ind2 = misc_utils.near_euc( lfp_coor['lon'].values, lfp_coor['lat'].values, (lon2, lat2)) # default value 0.01 wasn't able to find link number 3504, this value was increased to 0.012 to find missing link if (dis1 <= 0.012) & (dis2 <= 0.012): lfp_tree = lfp_tree.append(tree.loc[i, :]) lfp_tree = lfp_tree[['link_no', 'start_pnt', 'end_pnt', 'frst_ds', 'frst_us', 'scnd_us', 'strahler', 'mon_pnt', 'shreve']] lfp_tree.index.name = 'index' # Creating folder per basin ncatchstr = "%03d" % ncatch folder = outdir + "/" + ncatchstr create_out_folder(folder) # Writing clipped coord and tree files fnametre = folder + "/" + ncatchstr + "_tre.csv" fnamecoo = folder + "/" + ncatchstr + "_coo.csv" lfp_coor.to_csv(fnamecoo) lfp_tree.to_csv(fnametre, float_format='%i') # Creating rec dataframe rec = connections(fnametre, fnamecoo) # Writing XXX_rec.csv file fnamerec = folder + "/" + ncatchstr + "_rec.csv" rec.to_csv(fnamerec) # Get extent from rec dataframe xmin = rec['lon'].min() xmax = rec['lon'].max() ymin = rec['lat'].min() ymax = rec['lat'].max() # Get fixed extent # _dir = getdir(rec,dirtif) # _dirlet = getdirletter(_dir) # xmin,ymin,xmax,ymax = get_extent_outlet(_dirlet,0.1,xmin,ymin,xmax,ymax) # Clipping rasters demarrcli, demgeocli = gdalutils.clip_raster( demtif, xmin, ymin, xmax, ymax) accarrcli, accgeocli = gdalutils.clip_raster( acctif, xmin, ymin, xmax, ymax) wtharrcli, wthgeocli = gdalutils.clip_raster( wthtif, xmin, ymin, xmax, ymax) dirarrcli, dirgeocli = gdalutils.clip_raster( dirtif, xmin, ymin, xmax, ymax) netarrcli, netgeocli = gdalutils.clip_raster( nettif, xmin, ymin, xmax, ymax) catarrcli, catgeocli = gdalutils.clip_raster( cattif, xmin, ymin, xmax, ymax) # Mask only the catchment and fill with zeros netarrcli = np.where(catarrcli == ncatch, netarrcli, 0) dirarrcli = np.where(catarrcli == ncatch, dirarrcli, 0) # Creating output names fnamedem = folder + "/" + ncatchstr + "_dem.tif" fnameacc = folder + "/" + ncatchstr + "_acc.tif" fnamenet = folder + "/" + ncatchstr + "_net.tif" fnamewth = folder + "/" + ncatchstr + "_wth.tif" fnamedir = folder + "/" + ncatchstr + "_dir.tif" # Writing clipped arrays nodata = -9999 gdalutils.write_raster(demarrcli, fnamedem, demgeocli, "Float32", nodata) gdalutils.write_raster(accarrcli, fnameacc, accgeocli, "Float32", nodata) gdalutils.write_raster(netarrcli, fnamenet, netgeocli, "Float32", nodata) gdalutils.write_raster(wtharrcli, fnamewth, wthgeocli, "Float32", nodata) gdalutils.write_raster(dirarrcli, fnamedir, dirgeocli, "Float32", nodata) else: print("NOT PROCESSED: Number of pixels in river lower than 35 : " + str(netarr_tmp.sum()) + " pixels in basin number " + str(ncatch)) else: print("NOT PROCESSED: Basin area lower than 100 Km2 : " + str(_sum) + " KM**2 in basin number " + str(ncatch))
def getbankelevs(output, netf, hrdemf, proj, method, hrnodata, thresh, outlier): print(" running getbankelevs.py...") fname = output w = shapefile.Writer(shapefile.POINT) w.field('x') w.field('y') w.field('elev') # coordinates for bank elevations are based in river network mask net = gdalutils.get_data(netf) geo = gdalutils.get_geo(netf) iy, ix = np.where(net > 0) x = geo[8][ix] y = geo[9][iy] for i in range(len(x)): xmin = x[i] - thresh ymin = y[i] - thresh xmax = x[i] + thresh ymax = y[i] + thresh dem, dem_geo = gdalutils.clip_raster(hrdemf, xmin, ymin, xmax, ymax) ddem = np.ma.masked_where(dem == hrnodata, dem) if method == 'near': nodata = dem_geo[11] dfdem = gdalutils.array_to_pandas(dem, dem_geo, nodata, 'gt') arr = haversine.haversine_array( np.array(dfdem['y'].values, dtype='float32'), np.float32(dfdem['x'].values), np.float32(y[i]), np.float32(x[i])) dfdem['dis'] = np.array(arr) dfdem.sort_values(by='dis', inplace=True) elev = dfdem.iloc[0, 2] elif method == 'meanmin': if outlier == "yes": ddem = check_outlier(dem, ddem, hrnodata, 3.5) elev = np.mean([ddem.mean(), ddem.min()]) elif method == 'mean': if outlier == "yes": ddem = check_outlier(dem, ddem, hrnodata, 3.5) elev = ddem.mean() elif method == 'min': if outlier == "yes": ddem = check_outlier(dem, ddem, hrnodata, 3.5) elev = ddem.min() # Write final file in a shapefile if np.isfinite(elev): w.point(x[i], y[i]) w.record(x[i], y[i], elev) 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() fmt = "GTiff" nodata = -9999 bnkname1 = output + ".shp" bnkname2 = output + ".tif" subprocess.call([ "gdal_rasterize", "-a_nodata", str(nodata), "-of", fmt, "-tr", str(geo[6]), str(geo[7]), "-a", "elev", "-a_srs", proj, "-te", str(geo[0]), str(geo[1]), str(geo[2]), str(geo[3]), bnkname1, bnkname2 ])
print(geo) if nwindow is not None: ######################################################################################### # 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 chanmask arrays if not os.path.exists(maskraw_downsample): data = gdalutils.get_data(maskrawtif) downsample_count = block_reduce(data, block_size=(nwindow, nwindow), func=count, cval=-32767) data_mask = downsample_count >= count_thresh print('downsampled mask', data_mask.shape) gdalutils.write_raster(data_mask, maskraw_downsample, geo, 'Int16', -9999) else: data_mask = gdalutils.get_data(maskraw_downsample) ######################################################################################### # Clean chanmask - remove values away from stream network data_net = gdalutils.get_data(net_downsample) data_maskclean = clean_mask(data_mask, data_net, 900) gdalutils.write_raster(data_maskclean, maskclean_downsample, geo,
def beds(widthtif, bnkfixtif, runoffcsv, date1, date2, bedtif, lisfloodfp): # Create a temp temporal work folder outfolder = os.path.dirname(bedtif) + '/beds-temp/' try: os.makedirs(outfolder + 'lfp/nc/') except FileExistsError: pass # 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]) bnkfixasc = outfolder + 'bnkfix.asc' call(['gdal_translate', '-of', 'AAIGRID', bnkfixtif, bnkfixasc]) # 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) parlfp = outfolder + 'lfp.par' write_par(parlfp=parlfp, bcilfp=bcilfp, bdylfp=bdylfp, evaplfp=evaplfp, gaugelfp='./none', stagelfp='./none', dembnktif=demasc, wdttif=widthasc, bedtif=bnkfixasc, t=t) # Run simulation call([lisfloodfp, '-v', 'lfp.par'], cwd=outfolder) # Write netCDFs for WATER DEPTHS myfiles = sorted(glob(outfolder + '/lfp/*.wd')) for myfile in myfiles: fname = outfolder + 'lfp/nc/' + os.path.basename(myfile) + '.nc' xr.open_rasterio(myfile).to_dataset(name='myvar').to_netcdf(fname) # Read netCDFs ds = xr.open_mfdataset(outfolder + 'lfp/nc/*.nc', concat_dim='band', autoclose=True, parallel=False, chunks={'band': 10}) # Calculating mean method = ds.where(ds > 0, 0).myvar.mean('band') # Saving result in netCDF method.to_netcdf(outfolder + 'mean.nc') # Reading banks bnkfix = gu.get_data(bnkfixtif) bnkfix = np.where(bnkfix > 0, bnkfix, 0) # Calculating bed bed = bnkfix - method.compute().data # Write final raster gu.write_raster(bed, bedtif, geo, 'Float64', 0)
def basinsplit(ncatch, outdir, cattif, demtif, acctif, nettif, wthtif, dirtif, aretif, ordtif, tretxt, cootxt): # Get extend for every catchment and area catarr = gdalutils.get_data(cattif) try: dat = catarr == ncatch except: sys.exit('ERROR invalid basin number') # Use gdal to mask out basin in network and direction tifs nettmp = 'net_tmp.tif' dirtmp = 'dir_tmp.tif' acctmp = 'acc_tmp.tif' ordtmp = 'ord_tmp.tif' cmd = [ 'gdal_calc.py', '--calc', 'where(B==' + str(ncatch) + ',A,0)', '--format', 'GTiff', '--type', 'Int16', '--NoDataValue', '-9999', '-B', cattif, '--B_band', '1', '-A', nettif, '--A_band', '1', '--co', 'COMPRESS=DEFLATE', '--outfile', nettmp ] subprocess.call(cmd) cmd = [ 'gdal_calc.py', '--calc', 'where(B==' + str(ncatch) + ',A,0)', '--format', 'GTiff', '--type', 'Int16', '--NoDataValue', '-9999', '-B', cattif, '--B_band', '1', '-A', dirtif, '--A_band', '1', '--co', 'COMPRESS=DEFLATE', '--outfile', dirtmp ] subprocess.call(cmd) cmd = [ 'gdal_calc.py', '--calc', 'where(B==' + str(ncatch) + ',A,0)', '--format', 'GTiff', '--type', 'Float32', '--NoDataValue', '-9999', '-B', cattif, '--B_band', '1', '-A', acctif, '--A_band', '1', '--co', 'COMPRESS=DEFLATE', '--outfile', acctmp ] subprocess.call(cmd) cmd = [ 'gdal_calc.py', '--calc', 'where(B==' + str(ncatch) + ',A,0)', '--format', 'GTiff', '--type', 'Int16', '--NoDataValue', '-9999', '-B', cattif, '--B_band', '1', '-A', ordtif, '--A_band', '1', '--co', 'COMPRESS=DEFLATE', '--outfile', ordtmp ] subprocess.call(cmd) print('separated basin for nettif, dirtif, acctif, ordtif') catgeo = gdalutils.get_geo(cattif) area = gdalutils.get_data(aretif) #outlet = gdalutils.get_data(otltif) #direc = gdalutils.get_data(dirtif) row, col = np.where(dat) _sum = np.sum(dat * area) # clean up del (catarr, dat, area) if _sum >= 100: # be sure basin is larger than 100 Km2 xmin = catgeo[8][min(col)] xmax = catgeo[8][max(col)] ymin = catgeo[9][max(row)] ymax = catgeo[9][min(row)] # Clean up del (row, col) # Clip input rasters netarr_tmp, netgeo_tmp = gdalutils.clip_raster(nettmp, xmin, ymin, xmax, ymax) net_size = (netarr_tmp > 0).sum() print('loaded net array') if net_size >= 35: # be sure river network is long enough # Load tree and coord files tree = misc_utils.read_tree_taudem(tretxt) lfp_coor = misc_utils.read_coord_taudem(cootxt) lfp_coor.index.name = 'index' # Get list of x,y points in river network in basin iy, ix = np.where(netarr_tmp > 0) Xrav = netgeo_tmp[8][ix] Yrav = netgeo_tmp[9][iy] # Clean up memory del (netarr_tmp) # Clipping tree file based on segments within basin print('Clipping tree file') lfp_tree = pd.DataFrame() for i in tree.index: sta = tree.loc[i, 'start_pnt'] end = tree.loc[i, 'end_pnt'] lon1 = lfp_coor.loc[sta, 'lon'] lat1 = lfp_coor.loc[sta, 'lat'] lon2 = lfp_coor.loc[end, 'lon'] lat2 = lfp_coor.loc[end, 'lat'] # dis1, ind1 = misc_utils.near_euc( # lfp_coor['lon'].values, lfp_coor['lat'].values, (lon1, lat1)) # dis2, ind2 = misc_utils.near_euc( # lfp_coor['lon'].values, lfp_coor['lat'].values, (lon2, lat2)) dis1, ind1 = misc_utils.near_euc(Xrav, Yrav, (lon1, lat1)) dis2, ind2 = misc_utils.near_euc(Xrav, Yrav, (lon2, lat2)) # default value 0.01 wasn't able to find link number 3504, this value was increased to 0.012 to find missing link if (dis1 <= 0.012) & (dis2 <= 0.012): lfp_tree = lfp_tree.append(tree.loc[i, :]) lfp_tree = lfp_tree[[ 'link_no', 'start_pnt', 'end_pnt', 'frst_ds', 'frst_us', 'scnd_us', 'strahler', 'mon_pnt', 'shreve' ]] lfp_tree.index.name = 'index' # Creating folder per basin ncatchstr = "%03d" % ncatch folder = outdir + "/" + ncatchstr create_out_folder(folder) # Writing clipped coord and tree files print('Writing text files') fnametre = folder + "/" + ncatchstr + "_tre.csv" fnamecoo = folder + "/" + ncatchstr + "_coo.csv" lfp_coor.to_csv(fnamecoo) lfp_tree.to_csv(fnametre, float_format='%i') # clean up memory del (lfp_coor, lfp_tree) # Creating rec dataframe rec = connections(fnametre, fnamecoo) # Writing XXX_rec.csv file fnamerec = folder + "/" + ncatchstr + "_rec.csv" rec.to_csv(fnamerec) # Get extent from rec dataframe xmin = rec['lon'].min() xmax = rec['lon'].max() ymin = rec['lat'].min() ymax = rec['lat'].max() # Clean up memory del (rec) # Get fixed extent # _dir = getdir(rec,dirtif) # _dirlet = getdirletter(_dir) # xmin,ymin,xmax,ymax = get_extent_outlet(_dirlet,0.1,xmin,ymin,xmax,ymax) # Clipping rasters print('Loading and clipping rasters') nodata = -9999 # Creating output names fnamedem = folder + "/" + ncatchstr + "_dem.tif" fnameacc = folder + "/" + ncatchstr + "_acc.tif" fnamenet = folder + "/" + ncatchstr + "_net.tif" fnamewth = folder + "/" + ncatchstr + "_wth.tif" fnamedir = folder + "/" + ncatchstr + "_dir.tif" fnameord = folder + "/" + ncatchstr + "_ord.tif" # Load and write each array before removing it from memory demarrcli, demgeocli = gdalutils.clip_raster( demtif, xmin, ymin, xmax, ymax) gdalutils.write_raster(demarrcli, fnamedem, demgeocli, "Float32", nodata) del (demarrcli, demgeocli) accarrcli, accgeocli = gdalutils.clip_raster( acctmp, xmin, ymin, xmax, ymax) gdalutils.write_raster(accarrcli, fnameacc, accgeocli, "Float32", nodata) del (accarrcli, accgeocli) wtharrcli, wthgeocli = gdalutils.clip_raster( wthtif, xmin, ymin, xmax, ymax) gdalutils.write_raster(wtharrcli, fnamewth, wthgeocli, "Float32", nodata) del (wtharrcli, wthgeocli) dirarrcli, dirgeocli = gdalutils.clip_raster( dirtmp, xmin, ymin, xmax, ymax) gdalutils.write_raster(dirarrcli, fnamedir, dirgeocli, "Int16", nodata) del (dirarrcli, dirgeocli) netarrcli, netgeocli = gdalutils.clip_raster( nettmp, xmin, ymin, xmax, ymax) gdalutils.write_raster(netarrcli, fnamenet, netgeocli, "Int16", nodata) del (netarrcli, netgeocli) ordarrcli, ordgeocli = gdalutils.clip_raster( ordtmp, xmin, ymin, xmax, ymax) gdalutils.write_raster(ordarrcli, fnameord, ordgeocli, "Int16", nodata) del (ordarrcli, ordgeocli) # Finally delete the nettmp and dirtmp files os.remove(nettmp) os.remove(dirtmp) os.remove(ordtmp) os.remove(acctmp) else: print("NOT PROCESSED: Number of pixels in river lower than 35 : " + str(net_size) + " pixels in basin number " + str(ncatch)) else: print("NOT PROCESSED: Basin area lower than 100 Km2 : " + str(_sum) + " KM**2 in basin number " + str(ncatch))