def neighborhood_function(raster, method, size, distance_map): """ Parameters ---------- raster : Name of input raster map for which to apply r.neighbors method : Method for r.neighbors size : Size for r.neighbors distance : A distance map Returns ------- filtered_output : A neighborhood filtered raster map Examples -------- ... """ r.null(map=raster, null=0) # Set NULLs to 0 neighborhood_output = distance_map + "_" + method msg = "* Neighborhood operator '{method}' and size '{size}' for map '{name}'" msg = msg.format(method=method, size=size, name=neighborhood_output) grass.verbose(_(msg)) r.neighbors( input=raster, output=neighborhood_output, method=method, size=size, overwrite=True, ) scoring_function = "{neighborhood} * {distance}" scoring_function = scoring_function.format( neighborhood=neighborhood_output, distance=distance_map) filtered_output = distance_map filtered_output += "_" + method + "_" + str(size) neighborhood_function = EQUATION.format(result=filtered_output, expression=scoring_function) # --------------------------------------------------------------- grass.debug(_("*** Expression: {e}".format(e=neighborhood_function))) # --------------------------------------------------------------- grass.mapcalc(neighborhood_function, overwrite=True) # tmp_distance_map = filtered_output # r.compress(distance_map, flags='g') return filtered_output
def recode_map(raster, rules, colors, output): """Scores a raster map based on a set of category recoding rules. This is a wrapper around r.recode Parameters ---------- raster : Name of input raster map rules : Rules for r.recode colors : Color rules for r.colors output : Name of output raster map Returns ------- Does not return any value Examples -------- ... """ msg = "Setting NULL cells in {name} map to 0" msg = msg.format(name=raster) grass.debug(_(msg)) # ------------------------------------------ r.null(map=raster, null=0) # Set NULLs to 0 msg = "To Do: confirm if setting the '{raster}' map's NULL cells to 0 is right" msg = msg.format(raster=raster) grass.debug(_(msg)) # Is this right? # ------------------------------------------ r.recode(input=raster, rules=rules, output=output) r.colors(map=output, rules="-", stdin=SCORE_COLORS, quiet=True) grass.verbose(_("Scored map {name}:".format(name=raster)))
def grassCommonViewpoints(viewNum, greaterthan, altitude, userid, dateStamp): r, g, gscript = connect2grass(userid) filename = str(dateStamp) combinedName = options['combinedname'] # checking if user has asked for an elevation filter elevationFlag = (greaterthan and altitude > 3) or (not greaterthan and altitude < 29000) if not elevationFlag: # elevation filter is not asked for, so we can skip to directly exporting image pass else: if greaterthan: sign = '>' else: sign = '<' expression = "{0} = {0}@{1} * ({2}@{1} {3} {4})".format( combinedName, userid, options['demname'], sign, altitude) print "map calc" print expression #info = g.mapcalc(exp = expression, overwrite = True , verbose=True) gscript.raster.mapcalc(expression, overwrite=True) # make 0 cells null r.null(map=combinedName + '@' + str(userid), setnull=0) #r.out.png -t -w --overwrite input=my_viewshed@ucmiGeoData output=/home/justin/Documents/ucmi/geodata/viewsheds/viewshed.png #not sure why I can't call as r.out.png(...) print "r.out" flags = '' if viewNum == 0: flags = 'w' # makes null cells transparent and w outputs world file output = viewshedDir.format(userid) + combinedName + '.png' gscript.run_command('r.out.png', flags=flags, input=combinedName + '@' + str(userid), output=output, overwrite=True) if viewNum == 0: # convert world file to json file with east, west, north, south bounds wld2Json(output, userid)
def main(): """ Builds a grid for the MODFLOW component of the USGS hydrologic model, GSFLOW. """ options, flags = gscript.parser() basin = options['basin'] pp = options['pour_point'] raster_input = options['raster_input'] dx = options['dx'] dy = options['dy'] grid = options['output'] mask = options['mask_output'] bc_cell = options['bc_cell'] # basin='basins_tmp_onebasin'; pp='pp_tmp'; raster_input='DEM'; raster_output='DEM_coarse'; dx=dy='500'; grid='grid_tmp'; mask='mask_tmp' """ # Fatal if raster input and output are not both set _lena0 = (len(raster_input) == 0) _lenb0 = (len(raster_output) == 0) if _lena0 + _lenb0 == 1: gscript.fatal("You must set both raster input and output, or neither.") """ # Fatal if bc_cell set but mask and grid are false if bc_cell != '': if (mask == '') or (pp == ''): gscript.fatal( 'Mask and pour point must be set to define b.c. cell') # Create grid -- overlaps DEM, three cells of padding gscript.use_temp_region() reg = gscript.region() reg_grid_edges_sn = np.linspace(reg['s'], reg['n'], reg['rows']) reg_grid_edges_we = np.linspace(reg['w'], reg['e'], reg['cols']) g.region(vector=basin, ewres=dx, nsres=dy) regnew = gscript.region() # Use a grid ratio -- don't match exactly the desired MODFLOW resolution grid_ratio_ns = np.round(regnew['nsres'] / reg['nsres']) grid_ratio_ew = np.round(regnew['ewres'] / reg['ewres']) # Get S, W, and then move the unit number of grid cells over to get N and E # and include 3 cells of padding around the whole watershed _s_dist = np.abs(reg_grid_edges_sn - (regnew['s'] - 3. * regnew['nsres'])) _s_idx = np.where(_s_dist == np.min(_s_dist))[0][0] _s = float(reg_grid_edges_sn[_s_idx]) _n_grid = np.arange(_s, reg['n'] + 3 * grid_ratio_ns * reg['nsres'], grid_ratio_ns * reg['nsres']) _n_dist = np.abs(_n_grid - (regnew['n'] + 3. * regnew['nsres'])) _n_idx = np.where(_n_dist == np.min(_n_dist))[0][0] _n = float(_n_grid[_n_idx]) _w_dist = np.abs(reg_grid_edges_we - (regnew['w'] - 3. * regnew['ewres'])) _w_idx = np.where(_w_dist == np.min(_w_dist))[0][0] _w = float(reg_grid_edges_we[_w_idx]) _e_grid = np.arange(_w, reg['e'] + 3 * grid_ratio_ew * reg['ewres'], grid_ratio_ew * reg['ewres']) _e_dist = np.abs(_e_grid - (regnew['e'] + 3. * regnew['ewres'])) _e_idx = np.where(_e_dist == np.min(_e_dist))[0][0] _e = float(_e_grid[_e_idx]) # Finally make the region g.region(w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg['nsres']), ewres=str(grid_ratio_ew * reg['ewres'])) # And then make the grid v.mkgrid(map=grid, overwrite=gscript.overwrite()) # Cell numbers (row, column, continuous ID) v.db_addcolumn(map=grid, columns='id int', quiet=True) colNames = np.array(gscript.vector_db_select(grid, layer=1)['columns']) colValues = np.array( gscript.vector_db_select(grid, layer=1)['values'].values()) cats = colValues[:, colNames == 'cat'].astype(int).squeeze() rows = colValues[:, colNames == 'row'].astype(int).squeeze() cols = colValues[:, colNames == 'col'].astype(int).squeeze() nrows = np.max(rows) ncols = np.max(cols) cats = np.ravel([cats]) _id = np.ravel([ncols * (rows - 1) + cols]) _id_cat = [] for i in range(len(_id)): _id_cat.append((_id[i], cats[i])) gridTopo = VectorTopo(grid) gridTopo.open('rw') cur = gridTopo.table.conn.cursor() cur.executemany("update " + grid + " set id=? where cat=?", _id_cat) gridTopo.table.conn.commit() gridTopo.close() # Cell area v.db_addcolumn(map=grid, columns='area_m2', quiet=True) v.to_db(map=grid, option='area', units='meters', columns='area_m2', quiet=True) # Basin mask if len(mask) > 0: # Fine resolution region: g.region(n=reg['n'], s=reg['s'], w=reg['w'], e=reg['e'], nsres=reg['nsres'], ewres=reg['ewres']) # Rasterize basin v.to_rast(input=basin, output=mask, use='val', value=1, overwrite=gscript.overwrite(), quiet=True) # Coarse resolution region: g.region(w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg['nsres']), ewres=str(grid_ratio_ew * reg['ewres'])) r.resamp_stats(input=mask, output=mask, method='sum', overwrite=True, quiet=True) r.mapcalc('tmp' + ' = ' + mask + ' > 0', overwrite=True, quiet=True) g.rename(raster=('tmp', mask), overwrite=True, quiet=True) r.null(map=mask, null=0, quiet=True) # Add mask location (1 vs 0) in the MODFLOW grid v.db_addcolumn(map=grid, columns='basinmask double precision', quiet=True) v.what_rast(map=grid, type='centroid', raster=mask, column='basinmask') """ # Resampled raster if len(raster_output) > 0: r.resamp_stats(input=raster_input, output=raster_output, method='average', overwrite=gscript.overwrite(), quiet=True) """ # Pour point if len(pp) > 0: v.db_addcolumn(map=pp, columns=('row integer', 'col integer'), quiet=True) v.build(map=pp, quiet=True) v.what_vect(map=pp, query_map=grid, column='row', query_column='row', quiet=True) v.what_vect(map=pp, query_map=grid, column='col', query_column='col', quiet=True) # Next point downstream of the pour point # Requires pp (always) and mask (sometimes) # Dependency set above w/ gscript.fatal if len(bc_cell) > 0: ########## NEED TO USE TRUE TEMPORARY FILE ########## # May not work with dx != dy! v.to_rast(input=pp, output='tmp', use='val', value=1, overwrite=True) r.buffer(input='tmp', output='tmp', distances=float(dx) * 1.5, overwrite=True) r.mapcalc('tmp2 = if(tmp==2,1,null()) * ' + raster_input, overwrite=True) g.rename(raster=('tmp2', 'tmp'), overwrite=True, quiet=True) #r.mapcalc('tmp = if(isnull('+raster_input+',0,(tmp == 2)))', overwrite=True) #g.region(rast='tmp') #r.null(map=raster_input, r.drain(input=raster_input, start_points=pp, output='tmp2', overwrite=True) r.mapcalc('tmp3 = tmp2 * tmp', overwrite=True, quiet=True) g.rename(raster=('tmp3', 'tmp'), overwrite=True, quiet=True) #r.null(map='tmp', setnull=0) # Not necessary: center point removed above r.to_vect(input='tmp', output=bc_cell, type='point', column='z', overwrite=gscript.overwrite(), quiet=True) v.db_addcolumn(map=bc_cell, columns=('row integer', 'col integer', 'x double precision', 'y double precision'), quiet=True) v.build(map=bc_cell, quiet=True) v.what_vect(map=bc_cell, query_map=grid, column='row', \ query_column='row', quiet=True) v.what_vect(map=bc_cell, query_map=grid, column='col', \ query_column='col', quiet=True) v.to_db(map=bc_cell, option='coor', columns=('x,y')) # Find out if this is diagonal: finite difference works only N-S, W-E colNames = np.array(gscript.vector_db_select(pp, layer=1)['columns']) colValues = np.array( gscript.vector_db_select(pp, layer=1)['values'].values()) pp_row = int(colValues[:, colNames == 'row'].astype(int).squeeze()) pp_col = int(colValues[:, colNames == 'col'].astype(int).squeeze()) colNames = np.array( gscript.vector_db_select(bc_cell, layer=1)['columns']) colValues = np.array( gscript.vector_db_select(bc_cell, layer=1)['values'].values()) bc_row = int(colValues[:, colNames == 'row'].astype(int).squeeze()) bc_col = int(colValues[:, colNames == 'col'].astype(int).squeeze()) # Also get x and y while we are at it: may be needed later bc_x = float(colValues[:, colNames == 'x'].astype(float).squeeze()) bc_y = float(colValues[:, colNames == 'y'].astype(float).squeeze()) if (bc_row != pp_row) and (bc_col != pp_col): # If not diagonal, two possible locations that are adjacent # to the pour point _col1, _row1 = str(bc_col), str(pp_row) _col2, _row2 = str(pp_col), str(bc_row) # Check if either of these is covered by the basin mask _ismask_1 = gscript.vector_db_select(grid, layer=1, where='(row == ' + _row1 + ') AND (col ==' + _col1 + ')', columns='basinmask') _ismask_1 = int(_ismask_1['values'].values()[0][0]) _ismask_2 = gscript.vector_db_select(grid, layer=1, where='(row == ' + _row2 + ') AND (col ==' + _col2 + ')', columns='basinmask') _ismask_2 = int(_ismask_2['values'].values()[0][0]) # If both covered by mask, error if _ismask_1 and _ismask_2: gscript.fatal( 'All possible b.c. cells covered by basin mask.\n\ Contact the developer: awickert (at) umn(.)edu') # Otherwise, those that keep those that are not covered by basin # mask and set ... # ... wait, do we want the point that touches as few interior # cells as possible? # maybe just try setting both and seeing what happens for now! else: # Get dx and dy dx = gscript.region()['ewres'] dy = gscript.region()['nsres'] # Build tool to handle multiple b.c. cells? bcvect = vector.Vector(bc_cell) bcvect.open('rw') _cat_i = 2 if not _ismask_1: # _x should always be bc_x, but writing generalized code _x = bc_x + dx * (int(_col1) - bc_col) # col 1 at w edge _y = bc_y - dy * (int(_row1) - bc_row) # row 1 at n edge point0 = Point(_x, _y) bcvect.write( point0, cat=_cat_i, attrs=(None, _row1, _col1, _x, _y), ) bcvect.table.conn.commit() _cat_i += 1 if not _ismask_2: # _y should always be bc_y, but writing generalized code _x = bc_x + dx * (int(_col2) - bc_col) # col 1 at w edge _y = bc_y - dy * (int(_row2) - bc_row) # row 1 at n edge point0 = Point(_x, _y) bcvect.write( point0, cat=_cat_i, attrs=(None, _row2, _col2, _x, _y), ) bcvect.table.conn.commit() # Build database table and vector geometry bcvect.build() bcvect.close() g.region(n=reg['n'], s=reg['s'], w=reg['w'], e=reg['e'], nsres=reg['nsres'], ewres=reg['ewres'])
roughch_points=Settings.channel_Mannings_n_vector, roughch_pt_col=Settings.channel_Mannings_n_vector_col, width1=Settings.channel_width, width2=Settings.channel_width, width_points=Settings.channel_width_vector, width_points_col=Settings.channel_width_vector_col, fp_width_value=Settings.floodplain_width, fp_width_pts=Settings.floodplain_width_vector, fp_width_pts_col=Settings.floodplain_width_vector_col, overwrite=True) # MODFLOW grid & basin mask (1s where basin exists and 0 where it doesn't) # Fill nulls in case of ocean # Any error-related NULL cells will not be part of the basin, and all cells # should have elevation > 0, so this hopefully will not cause any problems r.null(map=DEM, null=0) v.gsflow_grid(basin=basins_inbasin, pour_point=pour_point, raster_input=DEM, dx=Settings.MODFLOW_grid_resolution, dy=Settings.MODFLOW_grid_resolution, output=MODFLOW_grid, mask_output=basin_mask, bc_cell=bc_cell, overwrite=True) r.null(map=DEM, setnull=0) # Hydrologically-correct DEM for MODFLOW r.gsflow_hydrodem(dem=DEM, grid=MODFLOW_grid, streams=streams_all,
# Start in the lowest cell along the left-hand side of the experiment # May want to make this a user-defined region in the future. # And may want to define boundaries as closed or open -- for this, # just r.patch a wall around everything except the end of the flume on the RHS. reg = gscript.region() g.region(w=reg['w']-2*reg['ewres'], e=reg['e']+2*reg['ewres'], s=reg['s']-2*reg['nsres'], n=reg['n']+2*reg['nsres'], save='with_boundaries', overwrite=True) # CUSTOM COMMANDS HERE TO CREATE WALL BASED ON X AND Y POSITIONS # THIS SHOULD ALSO BE PRE-DEFINED WHEN THIS IS FINISHED # Keep right boundary open mcstr = "boundaries = (x < "+str(margin_left/1000.)+") + "+ \ "(y < "+str(margin_bottom/1000.)+") + "+ \ "(y > "+str(margin_top/1000.)+")" r.mapcalc(mcstr, overwrite=True) r.mapcalc("boundaries = boundaries > 0", overwrite=True) # Logical 0/1 r.null(map='boundaries', setnull=0) _x = garray.array() _x.read('x') _y = garray.array() _y.read('y') drainarray = garray.array() # Much of this will depend on experiment DEMs = gscript.parse_command('g.list', type='raster', pattern='*__DEM__*').keys() DEMs = sorted(DEMs) for DEM in DEMs: r.patch(input='boundaries,'+DEM, output='tmp', overwrite=True) drainarray.read('tmp') scanName = DEM.split('__DEM__')[0]
def main(): """ Builds a grid for the MODFLOW component of the USGS hydrologic model, GSFLOW. """ options, flags = gscript.parser() basin = options["basin"] pp = options["pour_point"] raster_input = options["raster_input"] dx = options["dx"] dy = options["dy"] grid = options["output"] mask = options["mask_output"] bc_cell = options["bc_cell"] # basin='basins_tmp_onebasin'; pp='pp_tmp'; raster_input='DEM'; raster_output='DEM_coarse'; dx=dy='500'; grid='grid_tmp'; mask='mask_tmp' """ # Fatal if raster input and output are not both set _lena0 = (len(raster_input) == 0) _lenb0 = (len(raster_output) == 0) if _lena0 + _lenb0 == 1: gscript.fatal("You must set both raster input and output, or neither.") """ # Fatal if bc_cell set but mask and grid are false if bc_cell != "": if (mask == "") or (pp == ""): gscript.fatal( "Mask and pour point must be set to define b.c. cell") # Create grid -- overlaps DEM, three cells of padding g.region(raster=raster_input, ewres=dx, nsres=dy) gscript.use_temp_region() reg = gscript.region() reg_grid_edges_sn = np.linspace(reg["s"], reg["n"], reg["rows"]) reg_grid_edges_we = np.linspace(reg["w"], reg["e"], reg["cols"]) g.region(vector=basin, ewres=dx, nsres=dy) regnew = gscript.region() # Use a grid ratio -- don't match exactly the desired MODFLOW resolution grid_ratio_ns = np.round(regnew["nsres"] / reg["nsres"]) grid_ratio_ew = np.round(regnew["ewres"] / reg["ewres"]) # Get S, W, and then move the unit number of grid cells over to get N and E # and include 3 cells of padding around the whole watershed _s_dist = np.abs(reg_grid_edges_sn - (regnew["s"] - 3.0 * regnew["nsres"])) _s_idx = np.where(_s_dist == np.min(_s_dist))[0][0] _s = float(reg_grid_edges_sn[_s_idx]) _n_grid = np.arange(_s, reg["n"] + 3 * grid_ratio_ns * reg["nsres"], grid_ratio_ns * reg["nsres"]) _n_dist = np.abs(_n_grid - (regnew["n"] + 3.0 * regnew["nsres"])) _n_idx = np.where(_n_dist == np.min(_n_dist))[0][0] _n = float(_n_grid[_n_idx]) _w_dist = np.abs(reg_grid_edges_we - (regnew["w"] - 3.0 * regnew["ewres"])) _w_idx = np.where(_w_dist == np.min(_w_dist))[0][0] _w = float(reg_grid_edges_we[_w_idx]) _e_grid = np.arange(_w, reg["e"] + 3 * grid_ratio_ew * reg["ewres"], grid_ratio_ew * reg["ewres"]) _e_dist = np.abs(_e_grid - (regnew["e"] + 3.0 * regnew["ewres"])) _e_idx = np.where(_e_dist == np.min(_e_dist))[0][0] _e = float(_e_grid[_e_idx]) # Finally make the region g.region( w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg["nsres"]), ewres=str(grid_ratio_ew * reg["ewres"]), ) # And then make the grid v.mkgrid(map=grid, overwrite=gscript.overwrite()) # Cell numbers (row, column, continuous ID) v.db_addcolumn(map=grid, columns="id int", quiet=True) colNames = np.array(gscript.vector_db_select(grid, layer=1)["columns"]) colValues = np.array( gscript.vector_db_select(grid, layer=1)["values"].values()) cats = colValues[:, colNames == "cat"].astype(int).squeeze() rows = colValues[:, colNames == "row"].astype(int).squeeze() cols = colValues[:, colNames == "col"].astype(int).squeeze() nrows = np.max(rows) ncols = np.max(cols) cats = np.ravel([cats]) _id = np.ravel([ncols * (rows - 1) + cols]) _id_cat = [] for i in range(len(_id)): _id_cat.append((_id[i], cats[i])) gridTopo = VectorTopo(grid) gridTopo.open("rw") cur = gridTopo.table.conn.cursor() cur.executemany("update " + grid + " set id=? where cat=?", _id_cat) gridTopo.table.conn.commit() gridTopo.close() # Cell area v.db_addcolumn(map=grid, columns="area_m2 double precision", quiet=True) v.to_db(map=grid, option="area", units="meters", columns="area_m2", quiet=True) # Basin mask if len(mask) > 0: # Fine resolution region: g.region( n=reg["n"], s=reg["s"], w=reg["w"], e=reg["e"], nsres=reg["nsres"], ewres=reg["ewres"], ) # Rasterize basin v.to_rast( input=basin, output=mask, use="val", value=1, overwrite=gscript.overwrite(), quiet=True, ) # Coarse resolution region: g.region( w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg["nsres"]), ewres=str(grid_ratio_ew * reg["ewres"]), ) r.resamp_stats(input=mask, output=mask, method="sum", overwrite=True, quiet=True) r.mapcalc("tmp" + " = " + mask + " > 0", overwrite=True, quiet=True) g.rename(raster=("tmp", mask), overwrite=True, quiet=True) r.null(map=mask, null=0, quiet=True) # Add mask location (1 vs 0) in the MODFLOW grid v.db_addcolumn(map=grid, columns="basinmask double precision", quiet=True) v.what_rast(map=grid, type="centroid", raster=mask, column="basinmask") """ # Resampled raster if len(raster_output) > 0: r.resamp_stats(input=raster_input, output=raster_output, method='average', overwrite=gscript.overwrite(), quiet=True) """ # Pour point if len(pp) > 0: v.db_addcolumn(map=pp, columns=("row integer", "col integer"), quiet=True) v.build(map=pp, quiet=True) v.what_vect(map=pp, query_map=grid, column="row", query_column="row", quiet=True) v.what_vect(map=pp, query_map=grid, column="col", query_column="col", quiet=True) # Next point downstream of the pour point # Requires pp (always) and mask (sometimes) # Dependency set above w/ gscript.fatal # g.region(raster='DEM') # dx = gscript.region()['ewres'] # dy = gscript.region()['nsres'] if len(bc_cell) > 0: ########## NEED TO USE TRUE TEMPORARY FILE ########## # May not work with dx != dy! v.to_rast(input=pp, output="tmp", use="val", value=1, overwrite=True) r.buffer(input="tmp", output="tmp", distances=float(dx) * 1.5, overwrite=True) r.mapcalc("tmp2 = if(tmp==2,1,null()) * " + raster_input, overwrite=True) # r.mapcalc('tmp = if(isnull('+raster_input+',0,(tmp == 2)))', overwrite=True) # g.region(rast='tmp') # r.null(map=raster_input, # g.region(raster=raster_input) # r.resample(input=raster_input, output='tmp3', overwrite=True) r.resamp_stats(input=raster_input, output="tmp3", method="minimum", overwrite=True) r.drain(input="tmp3", start_points=pp, output="tmp", overwrite=True) # g.region(w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns*reg['nsres']), ewres=str(grid_ratio_ew*reg['ewres'])) # r.resamp_stats(input='tmp2', output='tmp3', overwrite=True) # g.rename(raster=('tmp3','tmp2'), overwrite=True, quiet=True) r.mapcalc("tmp3 = tmp2 * tmp", overwrite=True, quiet=True) g.rename(raster=("tmp3", "tmp"), overwrite=True, quiet=True) # r.null(map='tmp', setnull=0) # Not necessary: center point removed above r.to_vect( input="tmp", output=bc_cell, type="point", column="z", overwrite=gscript.overwrite(), quiet=True, ) v.db_addcolumn( map=bc_cell, columns=( "row integer", "col integer", "x double precision", "y double precision", ), quiet=True, ) v.build(map=bc_cell, quiet=True) v.what_vect(map=bc_cell, query_map=grid, column="row", query_column="row", quiet=True) v.what_vect(map=bc_cell, query_map=grid, column="col", query_column="col", quiet=True) v.to_db(map=bc_cell, option="coor", columns=("x,y")) # Of the candidates, the pour point is the closest one # v.db_addcolumn(map=bc_cell, columns=('dist_to_pp double precision'), quiet=True) # v.distance(from_=bc_cell, to=pp, upload='dist', column='dist_to_pp') # Find out if this is diagonal: finite difference works only N-S, W-E colNames = np.array(gscript.vector_db_select(pp, layer=1)["columns"]) colValues = np.array( gscript.vector_db_select(pp, layer=1)["values"].values()) pp_row = colValues[:, colNames == "row"].astype(int).squeeze() pp_col = colValues[:, colNames == "col"].astype(int).squeeze() colNames = np.array( gscript.vector_db_select(bc_cell, layer=1)["columns"]) colValues = np.array( gscript.vector_db_select(bc_cell, layer=1)["values"].values()) bc_row = colValues[:, colNames == "row"].astype(int).squeeze() bc_col = colValues[:, colNames == "col"].astype(int).squeeze() # Also get x and y while we are at it: may be needed later bc_x = colValues[:, colNames == "x"].astype(float).squeeze() bc_y = colValues[:, colNames == "y"].astype(float).squeeze() if (bc_row != pp_row).all() and (bc_col != pp_col).all(): if bc_row.ndim > 0: if len(bc_row) > 1: for i in range(len(bc_row)): """ UNTESTED!!!! And probably unimportant -- having 2 cells with river going through them is most likely going to happen with two adjacent cells -- so a side and a corner """ _col1, _row1 = str(bc_col[i]), str(pp_row[i]) _col2, _row2 = str(pp_col[i]), str(bc_row[i]) # Check if either of these is covered by the basin mask _ismask_1 = gscript.vector_db_select( grid, layer=1, where="(row == " + _row1 + ") AND (col ==" + _col1 + ")", columns="basinmask", ) _ismask_1 = int(_ismask_1["values"].values()[0][0]) _ismask_2 = gscript.vector_db_select( grid, layer=1, where="(row == " + _row2 + ") AND (col ==" + _col2 + ")", columns="basinmask", ) _ismask_2 = int(_ismask_2["values"].values()[0][0]) # check if either of these is the other point """ NOT DOING THIS YET -- HAVEN'T THOUGHT THROUGH IF ACTUALLY NECESSARY. (And this is an edge case anyway) """ # If both covered by mask, error if _ismask_1 and _ismask_2: gscript.fatal( "All possible b.c. cells covered by basin mask.\n\ Contact the developer: awickert (at) umn(.)edu" ) # If not diagonal, two possible locations that are adjacent # to the pour point _col1, _row1 = str(bc_col), str(pp_row) _col2, _row2 = str(pp_col), str(bc_row) # Check if either of these is covered by the basin mask _ismask_1 = gscript.vector_db_select( grid, layer=1, where="(row == " + _row1 + ") AND (col ==" + _col1 + ")", columns="basinmask", ) _ismask_1 = int(_ismask_1["values"].values()[0][0]) _ismask_2 = gscript.vector_db_select( grid, layer=1, where="(row == " + _row2 + ") AND (col ==" + _col2 + ")", columns="basinmask", ) _ismask_2 = int(_ismask_2["values"].values()[0][0]) # If both covered by mask, error if _ismask_1 and _ismask_2: gscript.fatal( "All possible b.c. cells covered by basin mask.\n\ Contact the developer: awickert (at) umn(.)edu") # Otherwise, those that keep those that are not covered by basin # mask and set ... # ... wait, do we want the point that touches as few interior # cells as possible? # maybe just try setting both and seeing what happens for now! else: # Get dx and dy # dx = gscript.region()['ewres'] # dy = gscript.region()['nsres'] # Build tool to handle multiple b.c. cells? bcvect = vector.Vector(bc_cell) bcvect.open("rw") _cat_i = 2 if _ismask_1 != 0: # _x should always be bc_x, but writing generalized code _x = bc_x + float(dx) * (int(_col1) - bc_col ) # col 1 at w edge _y = bc_y - float(dy) * (int(_row1) - bc_row ) # row 1 at n edge point0 = Point(_x, _y) bcvect.write( point0, cat=_cat_i, attrs=(None, _row1, _col1, _x, _y), ) bcvect.table.conn.commit() _cat_i += 1 if _ismask_2 != 0: # _y should always be bc_y, but writing generalized code _x = bc_x + float(dx) * (int(_col2) - bc_col ) # col 1 at w edge _y = bc_y - float(dy) * (int(_row2) - bc_row ) # row 1 at n edge point0 = Point(_x, _y) bcvect.write( point0, cat=_cat_i, attrs=(None, _row2, _col2, _x, _y), ) bcvect.table.conn.commit() # Build database table and vector geometry bcvect.build() bcvect.close() g.region( n=reg["n"], s=reg["s"], w=reg["w"], e=reg["e"], nsres=reg["nsres"], ewres=reg["ewres"], )
def compute_attractiveness(raster, metric, constant, kappa, alpha, mask=None, output_name=None): """ Compute a raster map whose values follow an (euclidean) distance function ( {constant} + {kappa} ) / ( {kappa} + exp({alpha} * {distance}) ), where: Source: http://publications.jrc.ec.europa.eu/repository/bitstream/JRC87585/lb-na-26474-en-n.pd Parameters ---------- constant : 1 kappa : A constant named 'K' alpha : A constant named 'a' distance : A distance map based on the input raster score : A score term to multiply the distance function mask : Optional raster MASK which is inverted to selectively exclude non-NULL cells from distance related computations. output_name : Name to pass to temporary_filename() to create a temporary map name Returns ------- tmp_output : A temporary proximity to features raster map. Examples -------- ... """ distance_terms = [ str(raster), str(metric), "distance", str(constant), str(kappa), str(alpha), ] if score: grass.debug(_( "Score for attractiveness equation: {s}".format(s=score))) distance_terms += str(score) # tmp_distance = temporary_filename('_'.join(distance_terms)) tmp_distance = temporary_filename(filename="_".join([raster, metric])) r.grow_distance(input=raster, distance=tmp_distance, metric=metric, quiet=True, overwrite=True) if mask: msg = "Inverted masking to exclude non-NULL cells " msg += "from distance related computations based on '{mask}'" msg = msg.format(mask=mask) grass.verbose(_(msg)) r.mask(raster=mask, flags="i", overwrite=True, quiet=True) # FIXME: use a parameters dictionary, avoid conditionals if score: distance_function = build_distance_function( constant=constant, kappa=kappa, alpha=alpha, variable=tmp_distance, score=score, ) # FIXME: use a parameters dictionary, avoid conditionals if not score: distance_function = build_distance_function(constant=constant, kappa=kappa, alpha=alpha, variable=tmp_distance) # temporary maps will be removed if output_name: tmp_distance_map = temporary_filename(filename=output_name) else: basename = "_".join([raster, "attractiveness"]) tmp_distance_map = temporary_filename(filename=basename) distance_function = EQUATION.format(result=tmp_distance_map, expression=distance_function) msg = "* Distance function: {f}".format(f=distance_function) grass.verbose(_(msg)) grass.mapcalc(distance_function, overwrite=True) r.null(map=tmp_distance_map, null=0) # Set NULLs to 0 compress_status = grass.read_command("r.compress", flags="g", map=tmp_distance_map) grass.verbose(_( "* Compress status: {s}".format(s=compress_status))) # REMOVEME return tmp_distance_map
def main(): """ Builds a grid for the MODFLOW component of the USGS hydrologic model, GSFLOW. """ options, flags = gscript.parser() basin = options['basin'] pp = options['pour_point'] raster_input = options['raster_input'] dx = options['dx'] dy = options['dy'] grid = options['output'] mask = options['mask_output'] bc_cell = options['bc_cell'] # basin='basins_tmp_onebasin'; pp='pp_tmp'; raster_input='DEM'; raster_output='DEM_coarse'; dx=dy='500'; grid='grid_tmp'; mask='mask_tmp' """ # Fatal if raster input and output are not both set _lena0 = (len(raster_input) == 0) _lenb0 = (len(raster_output) == 0) if _lena0 + _lenb0 == 1: grass.fatal("You must set both raster input and output, or neither.") """ # Create grid -- overlaps DEM, one cell of padding gscript.use_temp_region() reg = gscript.region() reg_grid_edges_sn = np.linspace(reg['s'], reg['n'], reg['rows']) reg_grid_edges_we = np.linspace(reg['w'], reg['e'], reg['cols']) g.region(vector=basin, ewres=dx, nsres=dy) regnew = gscript.region() # Use a grid ratio -- don't match exactly the desired MODFLOW resolution grid_ratio_ns = np.round(regnew['nsres'] / reg['nsres']) grid_ratio_ew = np.round(regnew['ewres'] / reg['ewres']) # Get S, W, and then move the unit number of grid cells over to get N and E # and include 3 cells of padding around the whole watershed _s_dist = np.abs(reg_grid_edges_sn - (regnew['s'] - 3. * regnew['nsres'])) _s_idx = np.where(_s_dist == np.min(_s_dist))[0][0] _s = float(reg_grid_edges_sn[_s_idx]) _n_grid = np.arange(_s, reg['n'] + 3 * grid_ratio_ns * reg['nsres'], grid_ratio_ns * reg['nsres']) _n_dist = np.abs(_n_grid - (regnew['n'] + 3. * regnew['nsres'])) _n_idx = np.where(_n_dist == np.min(_n_dist))[0][0] _n = float(_n_grid[_n_idx]) _w_dist = np.abs(reg_grid_edges_we - (regnew['w'] - 3. * regnew['ewres'])) _w_idx = np.where(_w_dist == np.min(_w_dist))[0][0] _w = float(reg_grid_edges_we[_w_idx]) _e_grid = np.arange(_w, reg['e'] + 3 * grid_ratio_ew * reg['ewres'], grid_ratio_ew * reg['ewres']) _e_dist = np.abs(_e_grid - (regnew['e'] + 3. * regnew['ewres'])) _e_idx = np.where(_e_dist == np.min(_e_dist))[0][0] _e = float(_e_grid[_e_idx]) # Finally make the region g.region(w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg['nsres']), ewres=str(grid_ratio_ew * reg['ewres'])) # And then make the grid v.mkgrid(map=grid, overwrite=gscript.overwrite()) # Cell numbers (row, column, continuous ID) v.db_addcolumn(map=grid, columns='id int', quiet=True) colNames = np.array(gscript.vector_db_select(grid, layer=1)['columns']) colValues = np.array( gscript.vector_db_select(grid, layer=1)['values'].values()) cats = colValues[:, colNames == 'cat'].astype(int).squeeze() rows = colValues[:, colNames == 'row'].astype(int).squeeze() cols = colValues[:, colNames == 'col'].astype(int).squeeze() nrows = np.max(rows) ncols = np.max(cols) cats = np.ravel([cats]) _id = np.ravel([ncols * (rows - 1) + cols]) _id_cat = [] for i in range(len(_id)): _id_cat.append((_id[i], cats[i])) gridTopo = VectorTopo(grid) gridTopo.open('rw') cur = gridTopo.table.conn.cursor() cur.executemany("update " + grid + " set id=? where cat=?", _id_cat) gridTopo.table.conn.commit() gridTopo.close() # Cell area v.db_addcolumn(map=grid, columns='area_m2', quiet=True) v.to_db(map=grid, option='area', units='meters', columns='area_m2', quiet=True) # Basin mask if len(mask) > 0: # Fine resolution region: g.region(n=reg['n'], s=reg['s'], w=reg['w'], e=reg['e'], nsres=reg['nsres'], ewres=reg['ewres']) # Rasterize basin v.to_rast(input=basin, output=mask, use='val', value=1, overwrite=gscript.overwrite(), quiet=True) # Coarse resolution region: g.region(w=str(_w), e=str(_e), s=str(_s), n=str(_n), nsres=str(grid_ratio_ns * reg['nsres']), ewres=str(grid_ratio_ew * reg['ewres'])) r.resamp_stats(input=mask, output=mask, method='sum', overwrite=True, quiet=True) r.mapcalc(mask + ' = ' + mask + ' > 0', overwrite=True, quiet=True) """ # Resampled raster if len(raster_output) > 0: r.resamp_stats(input=raster_input, output=raster_output, method='average', overwrite=gscript.overwrite(), quiet=True) """ # Pour point if len(pp) > 0: v.db_addcolumn(map=pp, columns=('row integer', 'col integer'), quiet=True) v.build(map=pp, quiet=True) v.what_vect(map=pp, query_map=grid, column='row', query_column='row', quiet=True) v.what_vect(map=pp, query_map=grid, column='col', query_column='col', quiet=True) # Next point downstream of the pour point if len(bc_cell) > 0: ########## NEED TO USE TRUE TEMPORARY FILE ########## # May not work with dx != dy! v.to_rast(input=pp, output='tmp', use='val', value=1, overwrite=True) r.buffer(input='tmp', output='tmp', distances=float(dx) * 1.5, overwrite=True) r.mapcalc('tmp = (tmp == 2) * ' + raster_input, overwrite=True) r.drain(input=raster_input, start_points=pp, output='tmp2', overwrite=True) r.mapcalc('tmp = tmp2 * tmp', overwrite=True) r.null(map='tmp', setnull=0) r.to_vect(input='tmp', output=bc_cell, type='point', column='z', overwrite=gscript.overwrite(), quiet=True) v.db_addcolumn(map=bc_cell, columns=('row integer', 'col integer'), quiet=True) v.build(map=bc_cell, quiet=True) v.what_vect(map=bc_cell, query_map=grid, column='row', \ query_column='row', quiet=True) v.what_vect(map=bc_cell, query_map=grid, column='col', \ query_column='col', quiet=True) g.region(n=reg['n'], s=reg['s'], w=reg['w'], e=reg['e'], nsres=reg['nsres'], ewres=reg['ewres'])
#That's mostly because I don't know how to programmatically #rescale a float to an int print "Recoding raster layer" rules = "0.0:" + str(vals[-1]) + ":0:255" #r.recode(input=raster_layer, rules=rules, output=recoded_raster_layer) g.write_command('r.recode', input=raster_layer, rule='-', output=recoded_raster_layer, stdin=rules) # Now, we apply our color table # Again, we'll pipe this from stdin, but you should probably use a file. # These rules get way more complicated, since we need multiple lines, # but I'm still too lazy to write to a file. Also, \n's are fun. print "Applying new color table" color_rules = "0% blue\n33.33% green\n66.67% yellow\n100% red" g.write_command('r.colors', map=recoded_raster_layer, rules='-', stdin=color_rules) # Set NULL values to remove noise # I'm doing a fairly aggressive data purge, use respnsibly print "Nullifying nulls" r.null(map=recoded_raster_layer, setnull="0-20") # Finally, write it to a GeoTiff print "Writing file: %s" % os.path.join(data_directory, output_file) r.out_gdal(input=recoded_raster_layer, format="GTiff", type="Byte", output=os.path.join(data_directory, output_file), createopt="INTERLEAVE=PIXEL, TFW=YES, PROFILE=GeoTIFF") # That's all folks! print "Congrats, it is finished."
def main(): soillossin = options['soillossin'] soillossout = options['soillossout'] factorold = options['factorold'] factornew = options['factornew'] map = options['map'] factorcol = options['factorcol'] flag_p = flags['p'] # patch factornew with factorold flag_k = flags['k'] # calculate k-factor components from % clay p_T, silt p_U, stones p_st, humus p_H if not factornew: factors = {} if flag_k: gscript.message('Using factor derived from \ soil components.') parcelmap = Vect(map) parcelmap.open(mode='rw', layer=1) parcelmap.table.filters.select() cur = parcelmap.table.execute() col_names = [cn[0] for cn in cur.description] rows = cur.fetchall() for col in (u'Kb',u'Ks',u'Kh', u'K'): if col not in parcelmap.table.columns: parcelmap.table.columns.add(col,u'DOUBLE') for row in rows: rowid = row[1] p_T = row[7] p_U = row[8] p_st = row[9] p_H = row[10] print("Parzelle mit id %d :" %rowid) for sublist in bodenarten: # p_T and p_U if p_T in range(sublist[2],sublist[3]) \ and p_U in range(sublist[4],sublist[5]) : print('Bodenart "' + sublist[1] + '", Kb = ' + str(sublist[6])) Kb = sublist[6] break for sublist in skelettgehalte: if p_st < sublist[0]: print('Skelettgehaltsklasse bis ' + str(sublist[0]) + ' , Ks = ' + str(sublist[1])) Ks = sublist[1] break for sublist in humusgehalte: if p_H < sublist[0]: print('Humusgehaltsklasse bis ' + str(sublist[0]) + ' , Ks = ' + str(sublist[1])) Kh = sublist[1] break K = Kb * Ks * Kh print('K = ' + str(K)) if K > 0: parcelmap.table.execute("UPDATE " + parcelmap.name + " SET" + " Kb=" + str(Kb) + ", Ks=" + str(Ks) + ", Kh=" + str(Kh) + ", K=" + str(K) + " WHERE id=" + str(rowid) ) parcelmap.table.conn.commit() parcelmap.close() factorcol2 = 'K' factors['k'] = map.split('@')[0]+'.tmp.'+factorcol2 v.to_rast(input=map, use='attr', attrcolumn=factorcol2, output=factors['k']) r.null(map=factors['k'], setnull='0') if factorcol: gscript.message('Using factor from column %s of \ vector map <%s>.' % (factorcol, map) ) factors['factorcol'] = map.split('@')[0]+'.tmp.' + factorcol v.to_rast(input=map, use='attr', attrcolumn=factorcol, output=factors['factorcol']) r.null(map=factors['factorcol'], setnull='0') print factors.keys() if not 'k' in factors and not 'factorcol' in factors: gscript.fatal('Please provide either factor \ raster map or valid vector map with factor column \ (kfactor) or factor components columns (Kb, Ks, Kh)' ) #if 'k' in factors and 'factorcol' in factors: factornew = map.split('@')[0]+'.kfactor' if 'k' in factors and 'factorcol' in factors: factornew = map.split('@')[0]+'.kfactor' r.patch(input=(factors['factorcol'],factors['k']), output=factornew) elif 'k' in factors: g.copy(rast=(factors['k'],factornew)) elif 'factorcol' in factors: g.copy(rast=(factors['factorcol'],factornew)) if flag_p: #factorcorr = factorold + '.update' r.patch(input=(factornew,factorold), output=factornew) formula = soillossout + '=' + soillossin \ + '/' + factorold \ + '*' + factornew r.mapcalc(formula) r.colors(map=soillossout, raster=soillossin)
reg = gscript.region() g.region(w=reg['w'] - 2 * reg['ewres'], e=reg['e'] + 2 * reg['ewres'], s=reg['s'] - 2 * reg['nsres'], n=reg['n'] + 2 * reg['nsres'], save='with_boundaries', overwrite=True) # CUSTOM COMMANDS HERE TO CREATE WALL BASED ON X AND Y POSITIONS # THIS SHOULD ALSO BE PRE-DEFINED WHEN THIS IS FINISHED # Keep right boundary open mcstr = "boundaries = (x < "+str(margin_left/1000.)+") + "+ \ "(y < "+str(margin_bottom/1000.)+") + "+ \ "(y > "+str(margin_top/1000.)+")" r.mapcalc(mcstr, overwrite=True) r.mapcalc("boundaries = boundaries > 0", overwrite=True) # Logical 0/1 r.null(map='boundaries', setnull=0) _x = garray.array() _x.read('x') _y = garray.array() _y.read('y') drainarray = garray.array() # Much of this will depend on experiment DEMs = gscript.parse_command('g.list', type='raster', pattern='*__DEM__*').keys() DEMs = sorted(DEMs) for DEM in DEMs: print DEM r.patch(input='boundaries,' + DEM, output='tmp', overwrite=True)
r.cell_area(output=cellArea_meters2, units='m2', overwrite=True) # Hydrologic correction r.hydrodem(input=DEM_original_import, output=DEM, flags='a', overwrite=True) # No offmap flow r.watershed(elevation=DEM, flow=cellArea_meters2, accumulation=accumulation, flags='m', overwrite=True) r.mapcalc(accumulation_onmap + ' = ' + accumulation + ' * (' + accumulation + ' > 0)', overwrite=True) r.null(map=accumulation_onmap, setnull=0) r.mapcalc(DEM + ' = if(isnull(' + accumulation_onmap + '),null(),' + DEM + ')', overwrite=True) # Ensure that null cells are shared r.mapcalc(accumulation_onmap + ' = if(isnull(' + DEM + '),null(),' + accumulation_onmap + ')', overwrite=True) # Repeat is sometimes needed r.mapcalc(DEM + ' = if(isnull(' + accumulation_onmap + '),null(),' + DEM + ')', overwrite=True) r.mapcalc(accumulation_onmap + ' = if(isnull(' + DEM + '),null(),' + accumulation_onmap + ')', overwrite=True)