def _pysheds_handler(request, response): # Create pysheds Grid object dem_fn = request.inputs['dem'][0].file dir_fn = request.inputs['dir'][0].file if dem_fn: grid = Grid.from_raster(dem_fn, 'dem') if not dir_fn: grid.flowdir('dem', out_name='dir', nodata=nodata) else: grid.read_raster(dir_fn, 'dir') else: grid = Grid.from_raster(dir_fn, 'dir') lat = request.inputs['latitude'][0].data lon = request.inputs['longitude'][0].data # name = request.inputs['name'][0].data grid.catchment(data='dir', x=lon, y=lat, dirmap=dirmap, out_name='catch', nodata_in=nodata, xytype='label') # This returns multiple polygons, and it's not clear which we should use. catch = grid.polygonize(grid.catch.astype('int32'), connectivity=8) for p, val in catch: if val == 0: # No idea if this is right or not poly = p break # TODO: Select correct polygon # TODO: Decide which output formats should be supported. response.outputs['boundary'].data = json.dumps(poly) return response
def test_from_raster(): grid.clip_to('catch') grid.to_raster('dir', 'test_dir.tif', view=False, apply_mask=False, blockxsize=16, blockysize=16) newgrid = Grid.from_raster('test_dir.tif', 'dir_output') newgrid.clip_to('dir_output') assert ((newgrid.dir_output == grid.dir).all()) grid.to_raster('dir', 'test_dir.tif', view=True, apply_mask=True, blockxsize=16, blockysize=16) newgrid = Grid.from_raster('test_dir.tif', 'dir_output') assert((newgrid.dir_output == grid.view('catch')).all())
def test_mask_geometry(): grid = Grid.from_raster(dem_path,'dem', mask_geometry=feature_geometry) rows = np.array([225, 226, 227, 228, 229, 230, 231, 232] * 7) cols = np.array([np.arange(98,105)] * 8).T.reshape(1,56) masked_cols, masked_rows = grid.mask.nonzero() assert (masked_cols == cols).all() assert (masked_rows == rows).all() with warnings.catch_warnings(record=True) as warn: warnings.simplefilter("always") grid = Grid.from_raster(dem_path,'dem', mask_geometry=out_of_bounds) assert len(warn) == 1 assert issubclass(warn[-1].category, UserWarning) assert "does not fall within the bounds" in str(warn[-1].message) assert grid.mask.all(), "mask should be returned to all True as normal"
def set_node_multitransfers(self): for index, value in self.c.items(): for pair, comm in value.items(): i, j = pair lnode = self.nodes[index][i] rnode = self.nodes[index][j] comm_elev = self.dem.flat[comm] neighbors = Grid._select_surround_ravel(self, comm, self.dem.shape) ser = pd.DataFrame(np.column_stack([neighbors, self.dem.flat[neighbors], self.ws[index].flat[neighbors]])) ser = ser[ser[2].isin(list(pair))] g = ser.groupby(2).idxmin()[1].apply(lambda x: ser.loc[x, 0]) fullix = self.drop.flat[g.values.astype(int)] lv = self.dropmap.loc[fullix][0].values nm = self.dropmap.loc[fullix][1].values g = pd.DataFrame(np.column_stack([lv, nm]), index=g.index.values.astype(int), columns=['level', 'name']).to_dict(orient='index') # Children will always be in numeric order from left to right lt, rt = g[j], g[i] if lnode.s: lnode.s.append(self.nodes[lt['level']][lt['name']]) lnode.si.append(comm_elev) else: lnode.s = [self.nodes[lt['level']][lt['name']]] lnode.si = [comm_elev] if rnode.s: rnode.s.append(self.nodes[rt['level']][rt['name']]) rnode.si.append(comm_elev) else: rnode.s = [self.nodes[rt['level']][rt['name']]] rnode.si = [comm_elev] self.set_singleton_multitransfer(self.root)
def compute_ridges(tiff_image): grid = Grid.from_raster(str(tiff_image), data_name='dem') grid.dem = grid.dem.max() - grid.dem peaks = grid.detect_depressions('dem') grid.fill_depressions(data='dem', out_name='flooded_dem') flats = grid.detect_flats('flooded_dem') grid.resolve_flats(data='flooded_dem', out_name='inflated_dem') # Compute flow direction based on corrected DEM dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.flowdir(data='inflated_dem', out_name='dir', dirmap=dirmap) # Compute flow accumulation based on computed flow direction grid.accumulation(data='dir', out_name='acc', dirmap=dirmap) downsampled_ridges = np.log(grid.view('acc') + 1) upsampled_peaks = cv2.pyrUp(np.array(peaks, dtype=np.uint8), dstsize=(225, 225)) upsampled_ridges = cv2.pyrUp(downsampled_ridges, dstsize=(225, 225)) upsampled_ridges = (upsampled_ridges - np.amin(upsampled_ridges)) / \ (np.amax(upsampled_ridges) - np.amin(upsampled_ridges)) upsampled_ridges = np.array(upsampled_ridges * 255, dtype=np.uint8) _, thresholded_ridges = cv2.threshold(upsampled_ridges, 150, 255, cv2.THRESH_BINARY) thresholded_ridges[thresholded_ridges == 255] = 1 skeletonized_ridges = skeletonize(thresholded_ridges) return np.expand_dims(skeletonized_ridges, axis=-1), np.expand_dims(upsampled_peaks, axis=-1)
def set_node_transfers(self): for index, mapping in enumerate(self.tmap): for pair, node in mapping.items(): i, j = pair comm = int(node.comm) comm_elev = node.elev neighbors = Grid._select_surround_ravel( self, comm, self.dem.shape) ser = pd.DataFrame( np.column_stack([ neighbors, self.dem.flat[neighbors], self.ws[index].flat[neighbors] ])) ser = ser[ser[2].isin(list(pair))] g = ser.groupby(2).idxmin()[1].apply(lambda x: ser.loc[x, 0]) fullix = self.drop.flat[g.values.astype(int)] lv = self.dropmap.loc[fullix][0].values nm = self.dropmap.loc[fullix][1].values g = pd.DataFrame(np.column_stack([lv, nm]), index=g.index.values.astype(int), columns=['level', 'name']).to_dict(orient='index') # Children will always be in numeric order from left to right lt, rt = g[j], g[i] node.l.t = self.nodes[lt['level']][lt['name']] node.r.t = self.nodes[rt['level']][rt['name']] self.set_singleton_transfer(self.root)
def split_catchment(self, flow_dir, geom, x, y): #method to use catchment bounding box instead of exact geom minX, maxX, minY, maxY = geom.GetEnvelope() print('HERE', minX, minY, maxX, maxY) gdal.Warp('/vsimem/fdr.tif', flow_dir, outputBounds=[minX, minY, maxX, maxY]) #start pysheds catchment delineation grid = Grid.from_raster('/vsimem/fdr.tif', data_name='dir') #get catchment with pysheds grid.catchment(data='dir', x=x, y=y, out_name='catch', recursionlimit=15000, xytype='label') # Clip the bounding box to the catchment grid.clip_to('catch') #some sort of strange raster to polygon conversion using rasterio method shapes = grid.polygonize() #get split Catchment geometry print('Split catchment complete') split_geom = ogr.Geometry(ogr.wkbPolygon) for shape in shapes: split_geom = split_geom.Union( ogr.CreateGeometryFromJson(json.dumps(shape[0]))) return split_geom
def testing(): """I understand we need both elevation and drainage direction to delineate the watershed. We can compute the drainage direction from the DEM using flowdir. Downloaded the au and ca files from hydrosheds at 30sec resolution. Issues with affine transformation. Flow directions seem to be saved in int16 to limit file size. I assume this is why dirmap takes powers of 2 to indicate directions. Catchment delineation does not seem to work. """ from matplotlib import pyplot as plt dem_fn = "../../tests/testdata/ca_dem_30s/ca_dem_30s/" dir_fn = "../../tests/testdata/ca_dir_30s/ca_dir_30s/" fv = -32768 grid = Grid.from_raster(dir_fn, "dir", nodata=fv) grid.read_raster(dem_fn, "dem", nodata=fv) lon, lat = -99.0619, 20.933 fig, (ax1, ax2) = plt.subplots(1, 2) idem = ax1.imshow(grid.view("dem"), extent=grid.extent, cmap="cubehelix", zorder=1, vmin=0) plt.colorbar(idem, ax=ax1, label="Elevation (m)") idir = ax2.imshow(grid.view("dir"), extent=grid.extent, cmap="viridis", zorder=2, vmin=0) boundaries = [0] + sorted(list(dirmap)) plt.colorbar(idir, ax=ax2, boundaries=boundaries, values=sorted(dirmap)) grid.catchment( data="dir", x=lon, y=lat, dirmap=dirmap, out_name="catch", xytype="label", nodata_in=nodata, ) catch = grid.polygonize(grid.catch.astype("int32"), connectivity=8) grid.clip_to("catch") for (p, v) in catch: poly = geometry.asShape(p) ax1.plot(*poly.exterior.xy, color="white") plt.show()
def make_watersheds(self, point): #>>> grid = Grid.from_raster('../data/dem.tif', data_name='dem') grid = Grid.from_raster(self.input_dem, data_name='dem') print(grid.crs) #grid.read_raster(os.path.split(self.input_dem)[0], data_name='dir') # Read raw DEM #grid = Grid.from_raster('../data/roi_10m', data_name='dem') # Fill depressions grid.fill_depressions(data='dem', out_name='flooded_dem') # Resolve flats grid.resolve_flats(data='flooded_dem', out_name='inflated_dem') # Determine D8 flow directions from DEM # ---------------------- # Resolve flats in DEM #grid.resolve_flats('dem', out_name='inflated_dem') # Specify directional mapping dirmap = (64, 128, 1, 2, 4, 8, 16, 32) # Compute flow directions # ------------------------------------- grid.flowdir(data='dem', out_name='dir') #, dirmap=dirmap) #return grid,output #grid.view('dir') #plt.imshow(grid.view('dir')) #def make_watersheds(self,point): # Specify pour point x, y = point print('x is: ', x) print('y is: ', y) #input_flow_dir=self.get_dem_and_infill()[1] # Delineate the catchment grid.catchment(data='dir', x=x, y=y, out_name='catch', recursionlimit=10000, xytype='label', dirmap=dirmap) demView = grid.view('catch', nodata=np.nan) #grid.to_raster(demView, self.output_directory+'dem_watershed_pysheds_catchment.tif') # Plot the result #grid.clip_to('catch') plt.imshow(grid.view('catch')) plt.show() plt.close()
def find_connections(self): c = {} b = {} inside = np.zeros(self.shape, dtype=bool) inside[1:-1, 1:-1] = True for index in range(len(self.levels) - 1): c[index] = {} b[index] = {} comm = np.flatnonzero((self.ws[index] == 0) & inside) # TODO: Not super elegant neighbors = self.ws[index].flat[Grid._select_surround_ravel( self, comm, self.ws[index].shape)] comms = dict(zip(comm, [set() for i in comm])) for region in self.lup[index].keys(): for elem in comm[(neighbors == region).any(axis=1)]: comms[elem].add(region) for elem in comms: comms[elem] = tuple(comms[elem]) for comm, pair in comms.items(): if len(pair) > 2: for combination in combinations(pair, 2): subpair = tuple(sorted(combination)) if subpair in c[index]: b[index][subpair].append(comm) if self.dem.flat[comm] < self.dem.flat[c[index] [subpair]]: c[index][subpair] = comm else: c[index][subpair] = comm b[index][subpair] = [comm] elif len(pair) < 2: # TODO: Not really sure what's happening in this case pass else: if pair in c[index]: b[index][pair].append(comm) if self.dem.flat[comm] < self.dem.flat[c[index][pair]]: c[index][pair] = comm else: c[index][pair] = comm b[index][pair] = [comm] self.c = c self.b = b
def watershed_15s(path): ''' From path to the project a 15s watershed is generated and added to the geopackage. ''' grid = Grid.from_raster(os.path.join(path, 'dir_15s.tif'), data_name='dir') grid.read_raster(os.path.join(path, 'acc_15s.tif'), data_name='acc') with fiona.open(os.path.join(path, 'HydroSHEDS_15s.gpkg'), layer='pour_point_15s') as source: crs = source.crs for pt in source: coord = pt['geometry']['coordinates'] x, y = coord[0], coord[1] xy = np.column_stack([x, y]) new_xy = grid.snap_to_mask(grid.acc > 100, xy, return_dist=False) new_x, new_y = new_xy[0][0], new_xy[0][1] #N NE E SE S SW W NW dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.catchment(data='dir', x=new_x, y=new_y, dirmap=dirmap, out_name='catch',recursionlimit=15000, xytype='label') grid.clip_to('catch') shapes = grid.polygonize() for item in shapes: geom = item[0] schema = {'geometry': 'Polygon', 'properties': OrderedDict([])} with fiona.open(os.path.join(path, 'HydroSHEDS_15s.gpkg'), 'w', layer='catchment_15s', driver='GPKG', schema=schema, crs=crs) as sink: data = dict() data['geometry'] = geom data['properties'] = OrderedDict() sink.write(data)
def find_connections(self): c = {} b = {} inside = np.zeros(self.shape, dtype=bool) inside[1:-1, 1:-1] = True for index in range(len(self.levels) - 1): c[index] = {} b[index] = {} comm = np.flatnonzero((self.ws[index] == 0) & inside) # TODO: Not super elegant neighbors = self.ws[index].flat[Grid._select_surround_ravel(self, comm, self.ws[index].shape)] comms = dict(zip(comm, [set() for i in comm])) for region in self.lup[index].keys(): for elem in comm[(neighbors == region).any(axis=1)]: comms[elem].add(region) for elem in comms: comms[elem] = tuple(comms[elem]) for comm, pair in comms.items(): if len(pair) > 2: for combination in combinations(pair, 2): subpair = tuple(sorted(combination)) if subpair in c[index]: b[index][subpair].append(comm) if self.dem.flat[comm] < self.dem.flat[c[index][subpair]]: c[index][subpair] = comm else: c[index][subpair] = comm b[index][subpair] = [comm] elif len(pair) < 2: # TODO: Not really sure what's happening in this case pass else: if pair in c[index]: b[index][pair].append(comm) if self.dem.flat[comm] < self.dem.flat[c[index][pair]]: c[index][pair] = comm else: c[index][pair] = comm b[index][pair] = [comm] self.c = c self.b = b
def split_catchment(self, bounds, x, y): """Use catchment bounding box to clip NHD Plus v2 flow direction raster, and product split catchment delienation from X,Y""" print('test bounds:', bounds) RasterFormat = 'GTiff' PixelRes = 30 #method to use catchment bounding box instead of exact geom gdal.Warp(OUT_FDR, IN_FDR, format=RasterFormat, outputBounds=bounds, xRes=PixelRes, yRes=PixelRes, dstSRS=self.Projection, resampleAlg=gdal.GRA_NearestNeighbour, options=['COMPRESS=DEFLATE']) #start pysheds catchment delineation grid = Grid.from_raster(OUT_FDR, data_name='dir') #compute flow accumulation to snap to dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.accumulation(data='dir', dirmap=dirmap, out_name='acc', apply_mask=False) grid.to_raster('acc', OUT_PATH + 'acc.tif', view=False, blockxsize=16, blockysize=16) #snap the pourpoint to xy = (x, y) new_xy = grid.snap_to_mask(grid.acc > 100, xy, return_dist=False) #get catchment with pysheds grid.catchment(data='dir', x=new_xy[0], y=new_xy[1], out_name='catch', recursionlimit=15000, xytype='label') # Clip the bounding box to the catchment grid.clip_to('catch') #some sort of strange raster to polygon conversion using rasterio method shapes = grid.polygonize() #get split Catchment geometry print('Split catchment complete') split_geom = ogr.Geometry(ogr.wkbPolygon) for shape in shapes: split_geom = split_geom.Union(ogr.CreateGeometryFromJson(json.dumps(shape[0]))) return split_geom
def set_node_transfers(self): for index, mapping in enumerate(self.tmap): for pair, node in mapping.items(): i, j = pair comm = int(node.comm) comm_elev = node.elev neighbors = Grid._select_surround_ravel(self, comm, self.dem.shape) ser = pd.DataFrame(np.column_stack([neighbors, self.dem.flat[neighbors], self.ws[index].flat[neighbors]])) ser = ser[ser[2].isin(list(pair))] g = ser.groupby(2).idxmin()[1].apply(lambda x: ser.loc[x, 0]) fullix = self.drop.flat[g.values.astype(int)] lv = self.dropmap.loc[fullix][0].values nm = self.dropmap.loc[fullix][1].values g = pd.DataFrame(np.column_stack([lv, nm]), index=g.index.values.astype(int), columns=['level', 'name']).to_dict(orient='index') # Children will always be in numeric order from left to right lt, rt = g[j], g[i] node.l.t = self.nodes[lt['level']][lt['name']] node.r.t = self.nodes[rt['level']][rt['name']] self.set_singleton_transfer(self.root)
def __call__(self): self._prepare() out_shps = [self.gage_shp_moved, self.dem_net, self.watersheds_shp] for shp in out_shps: if not os_exists(shp): continue in_vec = ogr.Open(shp) out_driver = in_vec.GetDriver() in_vec.Destroy() out_driver.DeleteDataSource(shp) self._grid = Grid.from_raster(self.raw_dem_path, data_name='dem') ftns = [ self._deps, self._flats, self._fdrs, self._slopes, self._facs, self._threshs, self._snaps, self._streams_net, # self._streams, ] for ftn in ftns: beg_time = timeit.default_timer() ftn() end_time = timeit.default_timer() if self.verbose: print(f'Took {end_time - beg_time:0.2f} seconds.\n') return
def load_dem_data(basin_geom): basin_bounds = basin_geom.bounds basin_bbox = tuple((basin_bounds['minx'].values[0] - 0.001, basin_bounds['miny'].values[0] - 0.001, basin_bounds['maxx'].values[0] + 0.001, basin_bounds['maxy'].values[0] + 0.001)) grid = Grid.from_raster(path=FP_DIR + '/na_dem_15s/na_dem_15s', data_name='dem', window=basin_bbox, window_crs=Proj(4326)) xs = [c[1] for c in grid.view('dem').coords] ys = [c[0] for c in grid.view('dem').coords] elevations = np.array(grid.view('dem')).flatten() dem_df = pd.DataFrame() dem_df['x'] = xs dem_df['y'] = ys dem_df['elevation'] = elevations dem_df['geometry'] = [Point(a[0], a[1]) for a in grid.view('dem').coords] return dem_df
#Importamos librerías a usar import numpy as np import matplotlib.pyplot as plt import matplotlib.colors as colors from pysheds.grid import Grid import seaborn as sns import warnings import os warnings.filterwarnings('ignore') #Indicamos el directorio de trabajo: os.chdir("C:\\Users\\Julio\\Documents\\EVENTOS\\UNSCH-Julio 2020\\Pysheds") #Indicamos el nombre del archivo ráster grid = Grid.from_raster('n30w100_con', data_name='dem') #Configuramos espacio de gráfico fig, ax = plt.subplots(figsize=(8, 6)) fig.patch.set_alpha(0) #Generamos gráfico de DEM plt.imshow(grid.dem, extent=grid.extent, cmap='cubehelix', zorder=1) plt.colorbar(label='Elevation (m)') plt.grid(zorder=0) plt.title('Digital elevation map') plt.xlabel('Longitude') plt.ylabel('Latitude') plt.tight_layout() plt.savefig('dem', bbox_inches='tight')
# dest.write(mosaic) # # # # Re-Project Conditioned Raster to NAD 83 Albers Equal Area # # print("Reprojecting raster to NAD83 Albers Equal Area...") # os.chdir("D:\GitHub\pysheds\data\conditioned\output") # os.system('gdalwarp mosaic.tif reproject.tif -t_srs "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 ' # '+x_0=0 +y_0=0 +ellps=GRS9- +towgs84=0,0,0,0,0,0,0 +units=m _no_defs"') # os.chdir("D:\GitHub\pysheds\examples") # Change working directory back to script location # # Read in Conditioned (mosaiced + reprojected) raster print("Reading grid of conditioned raster ...") grid = Grid.from_raster(os.path.join('..', 'data', 'conditioned', 'n25w100_con', 'n25w100_con'), data_name='dem') # grid = Grid.from_raster(os.path.join('..', 'data', 'conditioned', 'output', 'reproject.tif'), data_name='dem') # grid = Grid.from_raster(os.path.join('..', 'data', 'conditioned', 'n30w095_con', 'n30w095_con'), data_name='dem') # grid = Grid.from_raster(os.path.join('..', 'data', 'conditioned', 'n30w100_con', 'n30w100_con'), data_name='dem') fig, ax = plt.subplots(figsize=(8, 6)) fig.patch.set_alpha(0) plt.imshow(grid.dem, vmin=0, vmax=3000, extent=grid.extent, cmap='cubehelix', zorder=1) plt.colorbar(label='Elevation (m)') plt.grid(zorder=0) plt.title('Digital elevation map')
import numpy as np import matplotlib.pyplot as plt import matplotlib.colors as colors from pysheds.grid import Grid import seaborn as sns import warnings warnings.filterwarnings('ignore') from PIL import Image # -------------------------------- # # <<< Instatiate a grid from a DEM raster >>> # C:/Users/Rahul/Documents/Geany/files/cach2/n30w100_con_grid/n30w100_con/n30w100_con grid = Grid.from_raster( 'C:/Users/Rahul/Documents/Geany/files/Cat_DEM/SRTM_90m_AP_srikakulam_5km.tif', data_name='dem') fig, ax = plt.subplots(figsize=(8, 6)) fig.patch.set_alpha(1) plt.imshow(grid.dem, extent=grid.extent, cmap='cubehelix', zorder=1) plt.colorbar(label='Elevation (m)') plt.grid(zorder=0) plt.title('Digital elevation map') plt.xlabel('Longitude') plt.ylabel('Latitude') plt.tight_layout() plt.savefig('C:/Users/Rahul/Documents/Geany/files/cach2/conditioned_dem.png', bbox_inches='tight') #im1=Image.open('C:/Users/Rahul/Documents/Geany/files/cach2/conditioned_dem.png') #im1.show() # -------------------------------- #
@author: joempie """ import os from pysheds.grid import Grid import richdem as rd filledDemPath = '../data/N09E037.tif' x, y = 37.15251, 9.55677 if (not os.path.isfile(filledDemPath)): dem = rd.LoadGDAL('../data/N09E037.hgt') rd.FillDepressions(dem, epsilon=True, in_place=True) rd.SaveGDAL(filledDemPath, dem) grid = Grid.from_raster(filledDemPath, data_name='infl_dem') # grid.fill_depressions(data='dem',out_name='flooded_dem') # grid.resolve_flats(data='flooded_dem') # Specify directional mapping dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.flowdir(data='infl_dem', out_name='dir', dirmap=dirmap) # Delineate the catchment grid.catchment(data='dir', x=x, y=y, dirmap=dirmap, out_name='catch', recursionlimit=15000, xytype='label')
def flow_acc(path_dem): grid = Grid.from_raster(path_dem, data_name='dem') print("The raster has been read") # plt.figure(figsize=(12,10)) # plt.imshow(grid.dem, extent=grid.extent, cmap='Blues') # plt.imshow(data, cmap=cmap) # plt.colorbar(label='Elevation (m)') # plt.grid() # plotFigure(grid.dem, 'Elevation (m)') depressions = grid.detect_depressions('dem') # Plot pits # fig, ax = plt.subplots(figsize=(8,8)) # ax.imshow(depressions, cmap='cubehelix', zorder=1) # ax.set_yticklabels([]) # ax.set_xticklabels([]) # plt.title('Depressions', size=14) grid.fill_depressions(data='dem', out_name='flooded_dem') flats = grid.detect_flats('flooded_dem') # Plot flats # fig, ax = plt.subplots(figsize=(8,8)) # plt.imshow(flats, cmap='cubehelix', zorder=1) # ax.set_yticklabels([]) # ax.set_xticklabels([]) # plt.title('Flats', size=14) grid.resolve_flats(data='flooded_dem', out_name='inflated_dem') # plt.figure(figsize=(12,10)) # plt.imshow(grid.inflated_dem, extent=grid.extent, cmap='cubehelix') # plt.imshow(data, cmap=cmap) # plt.colorbar(label='Flats') # plt.grid() # plotFigure(grid.inflated_dem, 'flats', 'cubehelix') flats_test = grid.detect_flats('inflated_dem') print("The Depressions have been filled and the Flats have been resolved") # Plot flats # fig, ax = plt.subplots(figsize=(8,8)) # plt.imshow(flats_test, cmap='cubehelix', zorder=1) # ax.set_yticklabels([]) # ax.set_xticklabels([]) # plt.title('Flats', size=14) #N NE E SE S SW W NW dirmap = (64, 128, 1, 2, 4, 8, 16, 32) # Compute flow direction based on corrected DEM grid.flowdir(data='inflated_dem', out_name='dir', dirmap=dirmap) print("Flow direction is computed") # plt.figure(figsize=(12,10)) # plt.imshow(grid.dir, extent=grid.extent, cmap='viridis') # plt.imshow(data, cmap=cmap) # plt.colorbar(label='flow_dir') # plt.grid() # plotFigure(grid.dir , 'flow dir', 'viridis') # Compute flow accumulation based on computed flow direction grid.accumulation(data='dir', out_name='acc', dirmap=dirmap) accView = grid.view('acc', nodata=np.nan) print("Flow accumulation is computed") # plt.figure(figsize=(12,10)) # plt.imshow(accView, extent=grid.extent, cmap='PuRd') # plt.imshow(data, cmap=cmap) # plt.colorbar(label='Cell_number') # plt.grid() # plotFigure(accView,"Cell Number",'PuRd') # Delineate catchment at point of high accumulation y, x = np.unravel_index(np.argsort(grid.acc.ravel())[-2], grid.acc.shape) grid.catchment(x, y, data='dir', out_name='catch', dirmap=dirmap, xytype='index') print("Catchment Delineated") streams = grid.extract_river_network('catch', 'acc', args["threshold"], dirmap=dirmap) print(streams["features"][:2]) print("River network has been extracted") f = open('OUTPUT/streams.geojson', 'w') f.write(str(streams)) f.close()
32.84167873121935), (-97.29304093486502, 32.84167861026064), (-97.29304075342363, 32.847513357726825)), ) }] class Datasets(): pass # Initialize dataset holder d = Datasets() # Initialize grid crs = pyproj.Proj('epsg:4326', preserve_units=True) grid = Grid.from_raster(dem_path) fdir = grid.read_ascii(dir_path, dtype=np.uint8, crs=grid.crs) dem = grid.read_raster(dem_path) roi = grid.read_raster(roi_path) # Add datasets to dataset holder d.dem = dem d.fdir = fdir d.roi = roi # Initialize parameters dirmap = (64, 128, 1, 2, 4, 8, 16, 32) acc_in_frame = 77261 cells_in_catch = 11422 catch_shape = (159, 169) max_distance_d8 = 209
def compute_section_mask(fdir_values, fdir_map=None, fdir_nodata=0, geo_reference=None, section_reference=None): if fdir_map is None: fdir_map = [8, 9, 6, 3, 2, 1, 4, 7] geo_values = geo_reference['values'] geo_longitude = geo_reference['longitude'] geo_latitude = geo_reference['latitude'] geo_transform = geo_reference['transform'] geo_crs = geo_reference['crs'] mask_values = np.zeros([fdir_values.shape[0], fdir_values.shape[1]], dtype=bool) mask_values[:, :] = True grid = Grid() grid.add_gridded_data(data=fdir_values, data_name='fdir', affine=geo_transform, crs=pyproj.Proj(geo_crs), nodata=fdir_nodata) grid.add_gridded_data(data=mask_values, data_name='mask', affine=geo_transform, crs=pyproj.Proj(geo_crs), nodata=False) section_obj = {} for section_tag, section_fields in section_reference.items(): section_idx_ji = section_fields['section_idx_ji'] section_j = section_idx_ji[0] - 1 section_i = section_idx_ji[1] - 1 section_mask = 'section_mask' grid.catchment(data=grid.fdir, x=section_i, y=section_j, dirmap=fdir_map, out_name=section_mask, recursionlimit=15000, nodata_out=0, ytype='index') section_mask = np.array(grid.section_mask).astype(np.float32) section_mask[section_mask == 0] = 0 section_mask[geo_values < 0] = 0 section_mask[section_mask >= 1] = 1 geo_latitude = np.flipud(geo_latitude) section_da = create_darray_2d(section_mask, geo_longitude, geo_latitude, coord_name_x='Longitude', coord_name_y='Latitude', dim_name_x='west_east', dim_name_y='south_north', dims_order=['south_north', 'west_east']) section_obj[section_tag] = {} section_obj[section_tag] = section_da return section_obj
print("Writing file...") with rasterio.open(out_fp, "w", **out_meta) as dest: kwargs = src.meta kwargs.update(bigtiff='YES', dtype=rasterio.uint16) dest.write(mosaic) # Re-Project Conditioned Raster to NAD 83 Albers Equal Area # print("Reprojecting raster to NAD83 Albers Equal Area...") # os.chdir("D:\\Projects\\Watersheds\\pysheds\\08108780\\mosaic") # os.system('gdalwarp mosaic_34.tif reproject.tif -t_srs "+proj=aea +lat_1=29.5 +lat_2=45.5 +lat_0=23 +lon_0=-96 ' # '+x_0=0 +y_0=0 +ellps=GRS9- +towgs84=0,0,0,0,0,0,0 +units=m _no_defs"') # grid = Grid.from_raster(os.path.join('pysheds', 'data', 'conditioned', 'original', 'n30w100_con', 'n30w100_con'), data_name='dem') grid.read_raster(os.path.join('pysheds', 'data', 'flowdir', 'original', 'n30w100_dir_bil', 'n30w100_dir.bil'), data_name='dir') # grid = Grid.from_raster(os.path.join('pysheds', 'data', 'conditioned', 'reproject', '30_100_con'), data_name='dem') # grid.read_raster(os.path.join('pysheds', 'data', 'flowdir', 'reproject', '30_100_reproj'), data_name='dir') dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.accumulation(data='dir', dirmap=dirmap, out_name='acc') print("Writing flow direction raster ...") os.chdir('D:\Projects\Watersheds\pysheds\data\processed_DEM') grid.to_ascii('dir', file_name='dir.ascii', view=True, apply_mask=False,
from pysheds.rfsm import RFSM # TODO: Major todo's # - self.mask should be a raster # - grid.clip_to should be able to take a raster (use _input_handler) current_dir = os.path.dirname(os.path.realpath(__file__)) data_dir = os.path.abspath(os.path.join(current_dir, '../data')) dir_path = os.path.join(data_dir, 'dir.asc') dem_path = os.path.join(data_dir, 'dem.tif') roi_path = os.path.join(data_dir, 'roi.tif') eff_path = os.path.join(data_dir, 'eff.tif') dinf_eff_path = os.path.join(data_dir, 'dinf_eff.tif') # Initialize grid grid = Grid() crs = pyproj.Proj('epsg:4326', preserve_units=True) grid.read_ascii(dir_path, 'dir', dtype=np.uint8, crs=crs) grid.read_raster(dem_path, 'dem') grid.read_raster(roi_path, 'roi') grid.read_raster(eff_path, 'eff') grid.read_raster(dinf_eff_path, 'dinf_eff') # set nodata to 1 # why is that not working with grid.view() in test_accumulation? #grid.eff[grid.eff==grid.eff.nodata] = 1 #grid.dinf_eff[grid.dinf_eff==grid.dinf_eff.nodata] = 1 # Initialize parameters dirmap = (64, 128, 1, 2, 4, 8, 16, 32) acc_in_frame = 76499 acc_in_frame_eff = 76498 # max value with efficiency
import pysheds import gdal import matplotlib.pyplot as plt import matplotlib.colors as colors from pysheds.grid import Grid import seaborn as sns import warnings warnings.filterwarnings('ignore') # functions #%% read DEM DEM = Grid.from_raster('DEM/n30w100_con/n30w100_con', data_name='dem') #grid = Grid.from_raster('DEM/dem_2000.tif', data_name='dem') #fig, ax = plt.subplots(figsize=(8,6)) #fig.patch.set_alpha(0) # #plt.imshow(DEM.dem, extent=DEM.extent, cmap='cubehelix', zorder=1) #plt.colorbar(label='Elevation (m)') #plt.grid(zorder=0) #plt.title('Digital elevation map') #plt.xlabel('Longitude') #plt.ylabel('Latitude') #plt.tight_layout() #plt.savefig('img/conditioned_dem.png', bbox_inches='tight') #%% flow_dir=Grid.flowdir(DEM.dem, data=None, out_name='dir', nodata_in=None, nodata_out=0, pits=-1, flats=-1, dirmap= (64, 128, 1, 2, 4, 8, 16, 32),
def test_windowed_reading(): # TODO: Write test for windowed reading newgrid = Grid.from_raster('test_dir.tif', window=grid.bbox, window_crs=grid.crs)
def create_FlowAccu_tif_file(shapefile, path_dict): topo_tif_lst = glob.glob(path_dict['topography_path'] + '*.tif') # shpdir_lst = glob.glob(path_dict['path_shp'] + '*') # for shpdir in shpdir_lst[2:3]: # shpfile_lst = glob.glob(shpdir + '/' + '*.shp') # for shapefile in shpfile_lst: shape = gpd.read_file(shapefile) shape = shape.to_crs('epsg:4269') shape_path_temp = os.path.join(path_dict['tempFolder_path'], 'watershed.shp') shape.to_file(shape_path_temp) with fiona.open(shape_path_temp) as shp: shape_geo = [feature['geometry'] for feature in shp] rs_lst = [] for tif_file in topo_tif_lst: with rasterio.open(tif_file) as tile: try: out_image, out_transform = rasterio.mask.mask(tile, shape_geo, crop=True) except ValueError: continue else: # it means there was not any except rs_lst.append(tif_file) temp_mosaic_path = os.path.join(path_dict['tempFolder_path'], 'temp_mosaic.tif') ### to release the memory tile = None if len(rs_lst) > 1: # need to mosaic ### firstly, doing clip, and then mosaic the clipped files #read shapefile with fiona.open(shape_path_temp, "r") as shpfile: shapes = [feature["geometry"] for feature in shpfile] # read raster files one by one temp_path = [] for i, rs in enumerate(rs_lst): with rasterio.open(rs) as src: bbox = box( np.maximum(src.bounds[0], shpfile.bounds[0]), # left np.maximum(src.bounds[1], shpfile.bounds[1]), # bottom np.minimum(src.bounds[2], shpfile.bounds[2]), # right np.minimum(src.bounds[3], shpfile.bounds[3]) # top ) geo = gpd.GeoDataFrame({'geometry': bbox}, index=[0], crs="EPSG:4269") geo = geo.to_crs(crs=src.crs.data['init']) coords = getFeatures(geo) out_img, out_transform = rasterio.mask.mask(dataset=src, shapes=coords, crop=True) out_meta = src.meta.copy() # we need to parse the epsg value from the CRS so that we can create a proj4 -string using pyCRS # library (to ensure that the projection information is saved correctly) epsg_code = int(src.crs.data['init'][5:]) # print(epsg_code) out_meta.update({ "driver": "GTiff", "height": out_img.shape[1], "width": out_img.shape[2], "transform": out_transform, "crs": pycrs.parse.from_epsg_code(epsg_code).to_proj4() }) out_tif = os.path.join(path_dict['tempFolder_path'], 'topo_temp_clip_' + str(i) + '.tif') temp_path.append(out_tif) with rasterio.open(out_tif, "w", **out_meta) as dest: dest.write(out_img) # clipped = rasterio.open(out_tif) # show(clipped, cmap='terrain') dest.close() ### to release the memory dest = None out_img = None # out_image, out_transform = rasterio.mask.mask(src, shapes, crop=True) # out_meta = src.meta # # make a new file # out_meta.update({"driver": "GTiff", # "height": out_image.shape[1], # "width": out_image.shape[2], # "transform": out_transform, # "crs": "epsg:4269"}) # path = os.path.join(path_dict['tempFolder_path'], 'topo_temp_clip_' + str(i) + '.tif') # temp_path.append(path) # with rasterio.open(path, "w", **out_meta) as dest: # dest.write(out_image) # dest.close() # ### to release the memory # dest = None # out_image = None #### now we do mosaic: src_files_to_mosaic = [] for fp in temp_path: src = rasterio.open(fp) src_files_to_mosaic.append(src) out_image_mos, out_trans = rasterio.merge.merge(src_files_to_mosaic) # make a new file out_meta = src.meta.copy() out_meta.update({ "driver": "GTiff", "height": out_image_mos.shape[1], "width": out_image_mos.shape[2], "transform": out_trans, "crs": "epsg:4269" }) with rasterio.open(temp_mosaic_path, "w", **out_meta) as dest: dest.write(out_image_mos) dest.close() ### to release memory dest = None out_image_mos = None AccuProcess = True ########################################### # src_files_to_mosaic = [] # for fp in rs_lst: # src = rasterio.open(fp) # src_files_to_mosaic.append(src) # out_image_mos, out_trans = rasterio.merge.merge(src_files_to_mosaic) # # make a new file # out_meta = src.meta.copy() # out_meta.update( # { # "driver": "GTiff", # "height": out_image_mos.shape[1], # "width": out_image_mos.shape[2], # "transform": out_trans, # "crs": "epsg:4269" # } # ) # with rasterio.open(temp_mosaic_path, "w", **out_meta) as dest: # dest.write(out_image_mos) # dest.close() # ### to release memory # dest = None # out_image_mos = None # AccuProcess = True elif len(rs_lst) == 1: # copy the tif file to tempfolder to work on # shutil.copyfile(rs_lst[0], temp_mosaic_path) rasterio.shutil.copy(rs_lst[0], temp_mosaic_path) # make a new file AccuProcess = True else: print( "There was no Topography .TIFF file for watershed: " + os.path.split(shapefile)[1], '\n') AccuProcess = False return temp_mosaic_path, AccuProcess ## it means the code stops here. because there is not any .tif file ## clip shapefile and mosaic try: with fiona.open(shape_path_temp, "r") as shpfile: shapes = [feature["geometry"] for feature in shpfile] with rasterio.open(temp_mosaic_path) as src: out_image, out_transform = rasterio.mask.mask(src, shapes, crop=True) out_meta = src.meta # make a new file out_meta.update({ "driver": "GTiff", "height": out_image.shape[1], "width": out_image.shape[2], "transform": out_transform, "crs": "epsg:4269" }) topo_clip_temp_path = os.path.join( path_dict['tempFolder_path'], 'topo_temp_clip.tif') with rasterio.open(topo_clip_temp_path, "w", **out_meta) as dest: dest.write(out_image) dest.close() ### to release the memory dest = None out_image = None except: AccuProcess = False return temp_mosaic_path, AccuProcess # calculating flow direction and flow accumulation (using pysheds package) try: grid = Grid.from_raster(topo_clip_temp_path, data_name='dem') grid.fill_depressions(data='dem', out_name='flooded_dem') grid.dem = None grid.resolve_flats(data='flooded_dem', out_name='inflated_dem') grid.flooded_dem = None # dirmap = (1, 2, 3, 4, 5, 6, 7, 8) dirmap = (64, 128, 1, 2, 4, 8, 16, 32) # ESRI default grid.flowdir(data='inflated_dem', out_name='dir', dirmap=dirmap) grid.inflated_dem = None grid.accumulation(data='dir', out_name='acc') grid.dir = None flowAccu_temp_path = os.path.join(path_dict['tempFolder_path'], 'flowAccu_temp.tif') # grid.to_raster('dir', flowAccu_temp_path) grid.to_raster('acc', flowAccu_temp_path, dtype=np.int32) grid = None return flowAccu_temp_path, AccuProcess except: AccuProcess = False return flowAccu_temp_path, AccuProcess
def test_constructors(): newgrid = grid.from_ascii(dir_path, dtype=np.uint8, crs=crs) new_fdir = grid.read_ascii(dir_path, dtype=np.uint8, crs=crs) assert ((fdir == new_fdir).all()) newgrid = Grid(viewfinder=fdir.viewfinder)
lines.append('\n\n') lines.append('[COORDINATES]') lines.append('\n') lines.append(self.coordinates.to_csv(sep='\t', header=None, index=None)) lines.append('\n\n') lines.append('[POLYGONS]') lines.append('\n') lines.append(self.polygons.to_csv(sep='\t', header=None, index=None)) self.lines = lines def to_file(self, filename, **kwargs): with open(filename, 'w') as outfile: outfile.writelines(self.lines) if __name__ == "__main__": grid = Grid.from_raster('../data/n30w100_con', data_name='dem', input_type='ascii') grid.read_raster('../data/n30w100_dir', data_name='dir', input_type='ascii') dirmap = (64, 128, 1, 2, 4, 8, 16, 32) # Specify pour point x, y = -97.2937, 32.7371 # Delineate the catchment grid.catchment(x, y, data='dir', dirmap=dirmap, out_name='catch', recursionlimit=15000, xytype='label') # Clip the bounding box to the catchment grid.clip_to('catch', precision=5) grid.accumulation(data='catch', dirmap=dirmap, pad_inplace=False, out_name='acc') projection = pyproj.Proj('+init=epsg:3083') node_depths = pd.read_csv('../../eecs-598-a455/notebooks/other/node_depths.csv', index_col=0) node_depths = node_depths.iloc[-1] link_flows = pd.read_csv('../../eecs-598-a455/notebooks/other/link_flows.csv', index_col=0)
def catch(x1,y1,x2,y2,data_url,out_url): # os.chdir(r'D:\Data\SRTM_TR') # os.chdir(r'D:\ASTER') grid = Grid.from_raster(data_url, data_name='dem') distance = 1 window = (x1,y1,x2,y2) grid.set_bbox(window) grid.read_raster(data_url, data_name='dem', window=grid.bbox, window_crs=grid.crs) dirmap = (64, 128, 1, 2, 4, 8, 16, 32) grid.fill_pits(data='dem', out_name='pit') grid.fill_depressions(data='pit', out_name='dep') grid.resolve_flats(data='dep', out_name='flat') grid.flowdir(data='flat', out_name='dir', dirmap=dirmap) grid.accumulation(data='dir', out_name='acc') # grid.to_raster('dir', "dir.tif", blockxsize=16, blockysize=16) # grid.to_raster('flat', "dem.tif", blockxsize=16, blockysize=16) # grid.to_raster('acc', "acc.tif", blockxsize=16, blockysize=16) # xy = np.column_stack([x, y]) # new = grid.snap_to_mask(grid.acc > 500, xy, return_dist=False) # x = new[:, 0] # y = new[:, 1] ynew, xnew = np.unravel_index(np.argsort(grid.acc.ravel())[-2], grid.acc.shape) # grid.catchment(x=x, y=y, data='dir', dirmap=dirmap, out_name='catch', recursionlimit=15000, xytype='label') grid.catchment(x=xnew, y=ynew, data='dir', dirmap=dirmap, out_name='catch', recursionlimit=15000, xytype='index') nodat = grid.catch.nodata grid.clip_to('catch') shapes = grid.polygonize() schema = { 'geometry': 'Polygon', 'properties': {'LABEL': 'float:16'} } i = 0 in_projection = Proj(init='epsg:4326') out_projection = Proj(init='epsg:4326') last_value = 0 coords = [[]] # print('Tranformation Started !') # transformation_time = datetime.datetime.now() for shape, value in shapes: if last_value < len(shape['coordinates'][0]): coords[0] = [] for index, val in enumerate(shape['coordinates'][0]): coords[0].append([transform(in_projection, out_projection, val[0], val[1])[0], transform(in_projection, out_projection, val[0], val[1])[1]]) last_value = len(shape['coordinates'][0]) else: pass # print('Transformation Finished : ', datetime.datetime.now()-transformation_time) # print(Polygon(coords)) poly = Polygon(coords) with fiona.open(os.path.join(out_url, "catchment.shp"), 'w', driver='ESRI Shapefile', crs=grid.crs.srs, schema=schema) as c: i = 0 for shape, value in shapes: rec = {} rec['geometry'] = shape rec['properties'] = {'LABEL': str(value)} rec['id'] = str(i) c.write(rec) i += 1 grid.catch.nodata = -9223372036854775808 grid.clip_to('catch') grid.accumulation(data='catch', dirmap=dirmap, pad_inplace=False, out_name='acc') grid.catch.nodata = -9223372036854775808 branches = grid.extract_river_network('catch', 'acc', threshold=50, dirmap=dirmap) # def saveDict(dic, file): # f = open(file, 'w') # f.write(str(dic)) # f.close() # # saveDict(branches, 'branches.geojson') # streamNet = gpd.read_file('branches.geojson') # streamNet.crs = {'init': 'epsg:23036'} schema = { 'geometry': 'LineString', 'properties': {} } os.path.join(out_url, "rivers.shp") with fiona.open(os.path.join(out_url, "rivers.shp"), 'w', driver='ESRI Shapefile', crs=grid.crs.srs, schema=schema) as c: i = 0 for branch in branches['features']: rec = {} rec['geometry'] = branch['geometry'] rec['properties'] = {} rec['id'] = str(i) c.write(rec) i += 1 def convert_wgs_to_utm(lon, lat): utm_band = str((math.floor((lon + 180) / 6) % 60) + 1) if len(utm_band) == 1: utm_band = '0' + utm_band if lat >= 0: epsg_code = '326' + utm_band else: epsg_code = '327' + utm_band return epsg_code input_lon, input_lat = x1, y1 utm_code = convert_wgs_to_utm(input_lon, input_lat) crs_wgs = pyproj.Proj(init='epsg:4326') # assuming you're using WGS84 geographic crs_utm = pyproj.Proj(init='epsg:{0}'.format(utm_code)) # a = gpd.read_file(out_url) # data_proj = a.copy() # data_proj['geometry'] = data_proj['geometry'].to_crs(epsg=utm_code) # Area = data_proj.area[0] / 1e6 Area = area(poly) / 1e6 file_name = 'rivers.zip' with zipfile.ZipFile(os.path.join(out_url, file_name), 'w') as file: file.write(os.path.join(out_url, 'rivers.cpg')) file.write(os.path.join(out_url, 'rivers.dbf')) file.write(os.path.join(out_url, 'rivers.prj')) file.write(os.path.join(out_url, 'rivers.shp')) file.write(os.path.join(out_url, 'rivers.shx')) return Area,utm_code,branches,poly
def test_windowed_reading(): newgrid = Grid.from_raster('test_dir.tif', 'dir_output', window=grid.bbox, window_crs=grid.crs)
import os import numpy as np from pysheds.grid import Grid current_dir = os.path.dirname(os.path.realpath(__file__)) data_dir = os.path.abspath(os.path.join(current_dir, '../data')) data_path = os.path.join(data_dir, 'dir.asc') # Initialize grid grid = Grid() grid.read_ascii(data_path, 'dir', dtype=np.uint8) # Initialize parameters dirmap = (64, 128, 1, 2, 4, 8, 16, 32) acc_in_frame = 77259 cells_in_catch = 11422 catch_shape = (159, 169) max_distance = 208 # TODO: Need to test dtypes of different constructor methods def test_dtype(): assert(grid.dir.dtype == np.uint8) def test_catchment(): # Specify pour point x, y = -97.2937, 32.7371 # Delineate the catchment grid.catchment(x, y, dirmap=dirmap, out_name='catch', recursionlimit=15000, xytype='label') assert(np.count_nonzero(grid.catch) == cells_in_catch)