示例#1
0
def raster_to_vector(raster, vector, type):
    """Converts a raster to a vector map

    Parameters
    ----------

    raster :
        Name of the input raster map

    vector :
        Name for the output vector map

    type :
        Type for the output vector map

    Returns
    -------

    Examples
    --------
    ..
    """
    r.to_vect(input=flow_in_category,
              output=flow_in_category,
              type="area",
              quiet=True)

    # Value is the ecosystem type
    v.db_renamecolumn(map=flow_in_category, column=("value", "ecosystem"))

    # New column for flow values
    addcolumn_string = flow_column_name + " double"
    v.db_addcolumn(map=flow_in_category, columns=addcolumn_string)

    # The raster category 'label' is the 'flow'
    v.db_update(map=flow_in_category, column="flow", query_column="label")
    v.db_dropcolumn(map=flow_in_category, columns="label")

    # Update the aggregation raster categories
    v.db_addcolumn(map=flow_in_category, columns="aggregation_id int")
    v.db_update(map=flow_in_category, column="aggregation_id", value=category)

    v.colors(map=flow_in_category, raster=flow_in_category, quiet=True)
示例#2
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
    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'])
示例#3
0
def main():
    """
    Links each river segment to the next downstream segment in a tributary
    network by referencing its category (cat) number in a new column. "0"
    means that the river exits the map.
    """

    options, flags = gscript.parser()

    streams = options["input_streams"]
    basins = options["input_basins"]
    downstream_cat = options["cat"]
    x_outlet = float(options["x_outlet"])
    y_outlet = float(options["y_outlet"])
    output_basins = options["output_basin"]
    output_streams = options["output_streams"]
    output_pour_point = options["output_pour_point"]
    draindir = options["draindir"]
    snapflag = flags["s"]

    # print options
    # print flags

    # Check that either x,y or cat are set
    if (downstream_cat != "") or ((x_outlet != "") and (y_outlet != "")):
        pass
    else:
        gscript.fatal(
            'You must set either "cat" or "x_outlet" and "y_outlet".')

    # NEED TO ADD IF-STATEMENT HERE TO AVOID AUTOMATIC OVERWRITING!!!!!!!!!!!
    if snapflag or (downstream_cat != ""):
        if downstream_cat == "":
            # Need to find outlet pour point -- start by creating a point at this
            # location to use with v.distance
            try:
                v.db_droptable(table="tmp", flags="f")
            except:
                pass
            tmp = vector.Vector("tmp")
            _cols = [
                ("cat", "INTEGER PRIMARY KEY"),
                ("x", "DOUBLE PRECISION"),
                ("y", "DOUBLE PRECISION"),
                ("strcat", "DOUBLE PRECISION"),
            ]
            tmp.open("w", tab_name="tmp", tab_cols=_cols)
            point0 = Point(x_outlet, y_outlet)
            tmp.write(
                point0,
                cat=1,
                attrs=(str(x_outlet), str(y_outlet), 0),
            )
            tmp.table.conn.commit()
            tmp.build()
            tmp.close()
            # Now v.distance
            gscript.run_command("v.distance",
                                from_="tmp",
                                to=streams,
                                upload="cat",
                                column="strcat")
            # v.distance(_from_='tmp', to=streams, upload='cat', column='strcat')
            downstream_cat = gscript.vector_db_select(map="tmp",
                                                      columns="strcat")
            downstream_cat = int(downstream_cat["values"].values()[0][0])

        # Attributes of streams
        colNames = np.array(vector_db_select(streams)["columns"])
        colValues = np.array(vector_db_select(streams)["values"].values())
        tostream = colValues[:, colNames == "tostream"].astype(int).squeeze()
        cats = colValues[:, colNames == "cat"].astype(
            int).squeeze()  # = "fromstream"

        # Find network
        basincats = [downstream_cat]  # start here
        most_upstream_cats = [
            downstream_cat
        ]  # all of those for which new cats must be sought
        while True:
            if len(most_upstream_cats) == 0:
                break
            tmp = list(most_upstream_cats)  # copy to a temp file: old values
            most_upstream_cats = []  # Ready to accept new values
            for ucat in tmp:
                most_upstream_cats += list(cats[tostream == int(ucat)])
                basincats += most_upstream_cats

        basincats = list(set(list(basincats)))

        basincats_str = ",".join(map(str, basincats))

        # Many basins out -- need to use overwrite flag in future!
        # SQL_OR = 'rnum = ' + ' OR rnum = '.join(map(str, basincats))
        # SQL_OR = 'cat = ' + ' OR cat = '.join(map(str, basincats))
        SQL_LIST = "cat IN (" + ", ".join(map(str, basincats)) + ")"
        if len(basins) > 0:
            v.extract(
                input=basins,
                output=output_basins,
                where=SQL_LIST,
                overwrite=gscript.overwrite(),
                quiet=True,
            )
        if len(streams) > 0:
            v.extract(
                input=streams,
                output=output_streams,
                cats=basincats_str,
                overwrite=gscript.overwrite(),
                quiet=True,
            )

    else:
        # Have coordinates and will limit the area that way.
        r.water_outlet(
            input=draindir,
            output="tmp",
            coordinates=(x_outlet, y_outlet),
            overwrite=True,
        )
        r.to_vect(input="tmp", output="tmp", type="area", overwrite=True)
        v.clip(input=basins, clip="tmp", output=output_basins, overwrite=True)
        basincats = gscript.vector_db_select(
            "basins_inbasin").values()[0].keys()
        basincats_str = ",".join(map(str, basincats))
        if len(streams) > 0:
            v.extract(
                input=streams,
                output=output_streams,
                cats=basincats_str,
                overwrite=gscript.overwrite(),
                quiet=True,
            )

    # If we want to output the pour point location
    if len(output_pour_point) > 0:
        # NEED TO ADD IF-STATEMENT HERE TO AVOID AUTOMATIC OVERWRITING!!!!!!!!!!!
        try:
            v.db_droptable(table=output_pour_point, flags="f")
        except:
            pass
        if snapflag or (downstream_cat != ""):
            _pp = gscript.vector_db_select(map=streams,
                                           columns="x2,y2",
                                           where="cat=" + str(downstream_cat))
            _xy = np.squeeze(_pp["values"].values())
            _x = float(_xy[0])
            _y = float(_xy[1])
        else:
            _x = x_outlet
            _y = y_outlet
        pptmp = vector.Vector(output_pour_point)
        _cols = [
            ("cat", "INTEGER PRIMARY KEY"),
            ("x", "DOUBLE PRECISION"),
            ("y", "DOUBLE PRECISION"),
        ]
        pptmp.open("w", tab_name=output_pour_point, tab_cols=_cols)
        point0 = Point(_x, _y)
        pptmp.write(
            point0,
            cat=1,
            attrs=(str(_x), str(_y)),
        )
        pptmp.table.conn.commit()
        pptmp.build()
        pptmp.close()
示例#4
0
# Build streams and sub-basins
r.stream_extract(elevation=DEM,
                 accumulation=accumulation_onmap,
                 stream_raster=streams_all,
                 stream_vector=streams_all,
                 threshold=Settings.drainage_threshold,
                 direction=draindir,
                 d8cut=0,
                 overwrite=True)
r.stream_basins(direction=draindir,
                stream_rast=streams_all,
                basins=basins_all,
                overwrite=True)
r.to_vect(input=basins_all,
          output=basins_all,
          type='area',
          flags='v',
          overwrite=True)

# Build stream network
v.stream_network(map=streams_all)

# Restrict to a single basin
v.stream_inbasin(input_streams=streams_all,
                 input_basins=basins_all,
                 output_streams=streams_inbasin,
                 output_basin=basins_inbasin,
                 x_outlet=Settings.outlet_point_x,
                 y_outlet=Settings.outlet_point_y,
                 output_pour_point=pour_point,
                 overwrite=True)
DEMs = sorted(DEMs)
for DEM in DEMs:
  r.patch(input='boundaries,'+DEM, output='tmp', overwrite=True)
  drainarray.read('tmp')
  scanName = DEM.split('__DEM__')[0]
  mainThalweg = scanName + '__main_thalweg__'
  tribThalweg = scanName + '__trib_thalweg__'
  # Main channel
  #start_x = margin_left/1000.
  #start_y = _y[:,1][drainarray[:,1] == np.min(drainarray[:,1])]
  flowIn = garray.array()
  flowIn[:,2][drainarray[:,2] < (np.min(drainarray[:,2])+.01)] = 1
  flowIn.write('tmpFlowIn', overwrite=True)
  r.watershed(elevation='tmp', flow='tmpFlowIn', threshold=np.sum(flowIn), stream='tmpStream', accumulation='tmpAccum', flags='s', overwrite=True)
  r.mapcalc('tmpStreamZ = (tmpStream * 0 + 1) * tmp', overwrite=True)
  r.to_vect(input='tmpStreamZ', output='tmpStreamLine', type='line', overwrite=True)
  r.to_vect(input='tmpStreamZ', output='tmpStreamPoints', type='point', column='z', overwrite=True)
  v.db_addcolumn(map='tmpStreamPoints', columns='x double precision, y double precision')
  v.to_db(map='tmpStreamPoints', option='coor', columns='x,y')
  """
  # Tributary channel
  start_x = _x[drainarray[-2,:] == np.min(drainarray[-2,:])] # CHECK INDEXING (TOP/BOTTOM)
  if len(start_x) > 0:
    start_x = start_x[0] # ARBITRARY, SHOULD FIX SOMETIME, PROBABLY NOT IMPORTANT THOUGH.
  startpoint = str(start_x)+','+str(margin_bottom)/1000.
  r.drain(input='tmp', drain=tribThalweg, start_coordinates=startpoint)
  """



# Try r.sim.water
示例#6
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"],
    )
示例#7
0
# Works with MFD too!
# Not really. Drainage from one catchment goes to multiple basins
r.watershed(elevation=elevation, flow='cellArea_km2', accumulation='drainageArea_km2', drainage='drainageDirection', stream='streams_tmp', threshold=thresh, flags='s', overwrite=True)
# Remove areas of negative (offmap) accumulation
r.mapcalc('drainageArea_km2 = drainageArea_km2 * (drainageArea_km2 > 0)', overwrite=True)
r.null(map='drainageArea_km2', setnull=0)
#r.mapcalc("streams_tmp = streams_tmp * (drainageArea_km2 > 0)", overwrite=True)

# Streams from new thresholding
r.mapcalc("streams_tmp = drainageArea_km2 > "+str(thresh), overwrite=True)
r.null(map="streams_tmp", setnull=0)
"""

# Prepare the stream lines and the points version of the same
r.thin(input='streams_tmp', output='streams', overwrite=True)
r.to_vect(input='streams', output='streams', type='line', overwrite=True)
v.db_dropcolumn(map='streams', columns='label')
v.db_renamecolumn(map='streams', column=('value', 'river_number'))
r.to_vect(input='streams',
          output='streams_points',
          type='point',
          overwrite=True)
v.db_dropcolumn(map='streams_points', columns='label')
v.db_renamecolumn(map='streams_points', column=('value', 'river_number'))

# Get slope and area
v.db_addcolumn(map='streams_points',
               columns=('slope double precision, area_km2 double precision'))
v.what_rast(map='streams_points', type='point', raster='slope', column='slope')
v.what_rast(map='streams_points',
            type='point',
示例#8
0
def raster_to_vector(raster_category_flow, vector_category_flow,
                     flow_column_name, category, type):
    """Converts a raster to a vector map

    Parameters
    ----------

    raster_category_flow :
        Name of the input raster map 'flow in category'

    vector_category_flow :
        Name for the output vector map 'flow in category'

    type :
        Type for the output vector map

    Returns
    -------

    Examples
    --------
    ..
    """
    msg = " * Vectorising raster map '{r}'"
    grass.verbose(
        _(
            msg.format(
                c=category,
                r=raster_category_flow,
                v=vector_category_flow,
            )))
    r.to_vect(
        input=raster_category_flow,
        output=vector_category_flow,
        type="area",
        quiet=True,
    )

    msg = " * Updating the attribute table"
    grass.verbose(_(msg))

    # Value is the ecosystem type
    v.db_renamecolumn(
        map=vector_category_flow,
        column=("value", "ecosystem"),
        quiet=True,
    )

    # New column for flow values
    addcolumn_string = flow_column_name + " double"
    v.db_addcolumn(
        map=vector_category_flow,
        columns=addcolumn_string,
        quiet=True,
    )

    # The raster category 'label' is the 'flow'
    v.db_update(
        map=vector_category_flow,
        column="flow",
        query_column="label",
        quiet=True,
    )
    v.db_dropcolumn(
        map=vector_category_flow,
        columns="label",
        quiet=True,
    )

    # Update the aggregation raster categories
    v.db_addcolumn(
        map=vector_category_flow,
        columns="aggregation_id int",
        quiet=True,
    )
    v.db_update(
        map=vector_category_flow,
        column="aggregation_id",
        value=category,
        quiet=True,
    )
    v.colors(
        map=vector_category_flow,
        raster=raster_category_flow,
        quiet=True,
    )
示例#9
0
    flowIn.write('tmpFlowIn', overwrite=True)
    # Must fix here: some cells on wall at boundary
    r.watershed(elevation='tmp',
                flow='tmpFlowIn',
                threshold=np.sum(flowIn),
                stream='tmpStream',
                accumulation='tmpAccum',
                flags='s',
                quiet=True,
                overwrite=True)
    r.mapcalc('tmpStreamZ = (tmpStream * 0 + 1) * tmp',
              quiet=True,
              overwrite=True)
    r.to_vect(input='tmpStreamZ',
              output='channel_centerline_' + DEM.split('_')[-1],
              type='line',
              quiet=True,
              overwrite=True)
"""
for DEM in DEMs:
  print DEM
  g.rename(vector=['Line__'+DEM,'channel_centerline_'+DEM.split('_')[-1]])
  #(input='tmpStreamZ', output='channel_centerline_'+DEM.split('_')[-1], type='line', quiet=True, overwrite=True)
"""

channels = sorted(
    gscript.parse_command('g.list',
                          type='vector',
                          pattern='channel_centerline_0*').keys())
for channel in channels:
    channel_points = channel[:-7] + 'points_' + channel[-7:]
示例#10
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:
        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'])
示例#11
0
    flowIn.write('tmpFlowIn', overwrite=True)
    # Must fix here: some cells on wall at boundary
    r.watershed(elevation='tmp',
                flow='tmpFlowIn',
                threshold=np.sum(flowIn),
                stream='tmpStream',
                accumulation='tmpAccum',
                flags='s',
                quiet=True,
                overwrite=True)
    r.mapcalc('tmpStreamZ = (tmpStream * 0 + 1) * tmp',
              quiet=True,
              overwrite=True)
    r.to_vect(input='tmpStreamZ',
              output='Line__' + DEM,
              type='line',
              quiet=True,
              overwrite=True)
    r.to_vect(input='tmpStreamZ',
              output='Points__' + DEM,
              type='point',
              column='z',
              quiet=True,
              overwrite=True)
    v.db_addcolumn(map='Points__' + DEM,
                   columns='x double precision, y double precision',
                   quiet=True)
    v.to_db(map='Points__' + DEM, option='coor', columns='x,y', quiet=True)

channels = sorted(
    gscript.parse_command('g.list',