def main(opts, flgs):
    pid = os.getpid()
    pat = "tmprgreen_%i_*" % pid
    atexit.register(cleanup,
                    pattern=pat,
                    debug=False)
    # check or generate raster map from rules files

    ecovalues = ['landvalue', 'tributes', 'stumpage', 'rotation', 'age',
                 'min_exc', 'max_exc']
    (lan, tri, stu, rot, age,
     excmin, excmax) = check_raster_or_landuse(opts, ecovalues)
    upper = opts['upper'] if opts['upper'] else ('tmprgreen_%i_upper' % pid)
    comp = opts['compensation'] if opts['compensation'] else ('tmprgreen_%i_compensation' % pid)
    exc = opts['excavation'] if opts['excavation'] else ('tmprgreen_%i_excavation' % pid)
    vlayer = int(opts['struct_layer'])

    plant, mset = (opts['plant'].split('@') if '@' in opts['plant'] else (opts['plant'], ''))

    struct, mset = (opts['struct'].split('@') if '@' in opts['struct'] else (opts['struct'], ''))

    # read common scalar parameters
    irate = float(opts['interest_rate'])
    life = float(opts['life'])
    width = float(opts['width'])
    depth = float(opts['depth'])
    slim = float(opts['slope_limit'])
    overw = overwrite()

    # RASTERS
    # Start computing the raster map of the costs
    # Upper value
    upper_value(upper, stu, lan, rot, age, irate, overw)
    # Compensation raster costs
    compensation_cost(comp, lan, tri, upper,
                      irate, float(opts['gamma_comp']), life, width, overw)
    # Excavation raster costs
    excavation_cost(exc, excmin, excmax, opts['slope'],
                    slim, width, depth, overw)
    # TODO: extra cost when crossing roads and rivers are missing

    # VECTOR
    # add columns with costs from rasters
    # add compensation costs
    v.rast_stats(map=struct, layer=vlayer, flags='c',
                 raster=comp, column_prefix='comp_cost', method='sum')
    # add excavation costs
    v.rast_stats(map=struct, layer=vlayer, flags='c',
                 raster=exc, column_prefix='exc_cost', method='sum')

    # add elecro-mechanical costs
    electromechanical_cost(struct,
                           power=opts['struct_column_power'],
                           head=opts['struct_column_head'],
                           gamma=float(opts['gamma_em']),
                           alpha=float(opts['alpha_em']),
                           beta=float(opts['beta_em']),
                           const=float(opts['const_em']),
                           vlayer=vlayer, cname='em_cost',
                           ctype='double precision',
                           overwrite=overw)

    # add linear cost for pipeline
    linear_cost(vname=struct, cname='lin_pipe_cost',
                alpha=float(opts['lc_pipe']), vlayer=vlayer,
                ctype='double precision',  overwrite=overw)

    # add linear for for electroline
    get_electro_length(opts)
    linear_cost(vname=struct, cname='lin_electro_cost',
                alpha=float(opts['lc_electro']), length='electro_length',
                vlayer=vlayer, ctype='double precision',  overwrite=overw)
    # Compensation raster costs for electroline
    comp = (opts['compensation']+'el' if
            opts['compensation']
            else ('tmprgreen_%i_compensation_el' % pid))
    exc = (opts['excavation']+'el'
           if opts['excavation']
           else ('tmprgreen_%i_excavation_el' % pid))
    compensation_cost(comp, lan, tri, upper,
                      irate, float(opts['gamma_comp']), life, 0.6, overw)
    # Excavation raster costs for electroline
    excavation_cost(exc, excmin, excmax, opts['slope'],
                    slim, 0.6, 0.6, overw)

    # add excavation cost and compensation cost for electroline
    elines = (opts['elines'] if opts['elines']
              else ('tmprgreen_%i_elines' % pid))
    v.rast_stats(map=elines, layer=vlayer, flags='c',
                 raster=comp, column_prefix='comp_cost', method='sum')
    # add excavation costs
    v.rast_stats(map=elines, layer=vlayer, flags='c',
                 raster=exc, column_prefix='exc_cost', method='sum')
    write2struct(elines, opts)

    xcost = "{cname} = {alpha} * {em}"
    # add power station costs
    vcolcalc(vname=struct, vlayer=vlayer,
             ctype='double precision',
             expr=xcost.format(cname='station_cost', em='em_cost',
                               alpha=opts['alpha_station']))
    # add inlet costs
    vcolcalc(vname=struct, vlayer=vlayer,
             ctype='double precision', notfinitesubstitute=0.,
             expr=xcost.format(cname='inlet_cost', em='em_cost',
                               alpha=opts['alpha_inlet']))
    # add total inlet costs
    # TODO: to be check to avoid to count cost more than one time I have moltiplied by 0.5
    tot = ('tot_cost = (comp_cost_sum + em_cost + el_comp_exc +'
           'lin_pipe_cost + lin_electro_cost + '
           'station_cost + inlet_cost + {grid}*0.5) * '
           '(1 + {general} + {hindrances})')
    vcolcalc(vname=struct, vlayer=vlayer,
             ctype='double precision', notfinitesubstitute=0.,
             expr=tot.format(grid=opts['grid'], general=opts['general'],
                             hindrances=opts['hindrances']))

    # TODO: produce a new vector map (output), with the conduct + penstock in
    # a unique line and sum the costs grouping by intake_id and side
    # SELECT {key} FROM {tname}
    #FIXME: intake_id and discharge can have different names
    group_by(struct, opts['output_struct'],
             isolate=['intake_id', opts['struct_column_id'],
                      opts['struct_column_side'], opts['struct_column_power'],
                      opts['struct_column_head'], 'discharge'],
             aggregate=['tot_cost', ],
             function='sum',
             group_by=['intake_id', opts['struct_column_side']])

    """
    where these values (3871.2256 and -0.45) are coming from?
    import numpy as np
    from scipy import stats

    power= np.array([50., 100., 200., 400., 600., 1000., 5000.])
    maint = np.array([707., 443., 389., 261., 209., 163., 88.])

    plt.plot(np.log(power), np.log(maint))
    plt.show()
    slope, intercept, r_value, p_value, std_err = stats.linregress(np.log(power), np.log(maint))
    #slope -0.45000431409701719
    #intercept 8.2613264284076049
    np.exp(intercept) * power ** slope

    """
#    maint = "{cname} = {alpha} * {power} ** (1 + {beta}) + {const}"
    maint = "{cname} = {cost_per_kW} * {power} * {alpha} + {const}"
    # compute yearly maintenance costs
    vcolcalc(vname=opts['output_struct'], vlayer=vlayer,
             ctype='double precision', notfinitesubstitute=0.,
             expr=maint.format(cname='maintenance',
                               cost_per_kW=opts['cost_maintenance_per_kw'],
                               alpha=opts['alpha_maintenance'],
                               power=opts['struct_column_power'],
                               beta=opts['beta_maintenance'],
                               const=opts['const_maintenance']))

    # compute yearly revenues
    rev = "{cname} = {eta} * {power} * {eprice} * {ophours}  + {const}"
    vcolcalc(vname=opts['output_struct'], vlayer=vlayer,
             ctype='double precision', notfinitesubstitute=0.,
             expr=rev.format(cname='revenue',
                             eta=opts['eta'],
                             power=opts['struct_column_power'],
                             eprice=opts['energy_price'],
                             ophours=opts['operative_hours'],
                             const=opts['const_revenue']))

    # compute the Net Present Value
    npv = "{cname} = {gamma} * ({revenue} - {maintenance}) - {tot}"
    gamma_npv = get_gamma_NPV(irate, life)
    vcolcalc(vname=opts['output_struct'], vlayer=vlayer,
             ctype='double precision', notfinitesubstitute=0.,
             expr=npv.format(cname='NPV',
                             gamma=gamma_npv,
                             revenue='revenue',
                             maintenance='maintenance',
                             tot='tot_cost'))

    economic2segment(economic=opts['output_struct'], segment=plant,
                         basename=opts['plant_basename'],
                         eco_layer=1, seg_layer=int(opts['plant_layer']),
                         eco_pid=opts['struct_column_id'],
                         seg_pid=opts['plant_column_id'],
                         function=max_NPV,
                         exclude=['intake_id', 'side', 'power',
                                  'gross_head', 'discharge'])

    vec = VectorTopo(opts['output_struct'])
    vec.open('rw')
    vec.table.columns.add('max_NPV','VARCHAR(3)')

    list_intakeid=list(set(vec.table.execute('SELECT intake_id FROM %s' %vec.table.name).fetchall()))

    for i in range(0,len(list_intakeid)):
        vec.rewind()
        list_npv=list(vec.table.execute('SELECT NPV FROM %s WHERE intake_id=%i;' % (vec.table.name, list_intakeid[i][0])).fetchall())
        npvmax=max(list_npv)[0]
        for line in vec:
            if line.attrs['intake_id'] == list_intakeid[i][0]:
                if line.attrs['NPV'] == npvmax:
                    line.attrs['max_NPV']='yes'
                else:
                    line.attrs['max_NPV']='no'

    vec.table.conn.commit()
    vec.close()
Example #2
0
def main(opts, flgs):
    pid = os.getpid()
    pat = "tmprgreen_%i_*" % pid
    atexit.register(cleanup, pattern=pat, debug=False)
    # check or generate raster map from rules files

    ecovalues = [
        "landvalue",
        "tributes",
        "stumpage",
        "rotation",
        "age",
        "min_exc",
        "max_exc",
    ]
    (lan, tri, stu, rot, age, excmin,
     excmax) = check_raster_or_landuse(opts, ecovalues)
    upper = opts["upper"] if opts["upper"] else ("tmprgreen_%i_upper" % pid)
    comp = (opts["compensation"] if opts["compensation"] else
            ("tmprgreen_%i_compensation" % pid))
    exc = (opts["excavation"] if opts["excavation"] else
           ("tmprgreen_%i_excavation" % pid))
    vlayer = int(opts["struct_layer"])

    plant, mset = (opts["plant"].split("@") if "@" in opts["plant"] else
                   (opts["plant"], ""))

    struct, mset = (opts["struct"].split("@") if "@" in opts["struct"] else
                    (opts["struct"], ""))

    # read common scalar parameters
    irate = float(opts["interest_rate"])
    life = float(opts["life"])
    width = float(opts["width"])
    depth = float(opts["depth"])
    slim = float(opts["slope_limit"])
    overw = overwrite()

    # RASTERS
    # Start computing the raster map of the costs
    # Upper value
    upper_value(upper, stu, lan, rot, age, irate, overw)
    # Compensation raster costs
    compensation_cost(comp, lan, tri, upper, irate, float(opts["gamma_comp"]),
                      life, width, overw)
    # Excavation raster costs
    excavation_cost(exc, excmin, excmax, opts["slope"], slim, width, depth,
                    overw)
    # TODO: extra cost when crossing roads and rivers are missing

    # VECTOR
    # add columns with costs from rasters
    # add compensation costs
    v.rast_stats(
        map=struct,
        layer=vlayer,
        flags="c",
        raster=comp,
        column_prefix="comp_cost",
        method="sum",
    )
    # add excavation costs
    v.rast_stats(
        map=struct,
        layer=vlayer,
        flags="c",
        raster=exc,
        column_prefix="exc_cost",
        method="sum",
    )

    # add elecro-mechanical costs
    electromechanical_cost(
        struct,
        power=opts["struct_column_power"],
        head=opts["struct_column_head"],
        gamma=float(opts["gamma_em"]),
        alpha=float(opts["alpha_em"]),
        beta=float(opts["beta_em"]),
        const=float(opts["const_em"]),
        vlayer=vlayer,
        cname="em_cost",
        ctype="double precision",
        overwrite=overw,
    )

    # add linear cost for pipeline
    linear_cost(
        vname=struct,
        cname="lin_pipe_cost",
        alpha=float(opts["lc_pipe"]),
        vlayer=vlayer,
        ctype="double precision",
        overwrite=overw,
    )

    # add linear for for electroline
    get_electro_length(opts)
    linear_cost(
        vname=struct,
        cname="lin_electro_cost",
        alpha=float(opts["lc_electro"]),
        length="electro_length",
        vlayer=vlayer,
        ctype="double precision",
        overwrite=overw,
    )
    # Compensation raster costs for electroline
    comp = (opts["compensation"] + "el" if opts["compensation"] else
            ("tmprgreen_%i_compensation_el" % pid))
    exc = (opts["excavation"] + "el" if opts["excavation"] else
           ("tmprgreen_%i_excavation_el" % pid))
    compensation_cost(comp, lan, tri, upper, irate, float(opts["gamma_comp"]),
                      life, 0.6, overw)
    # Excavation raster costs for electroline
    excavation_cost(exc, excmin, excmax, opts["slope"], slim, 0.6, 0.6, overw)

    # add excavation cost and compensation cost for electroline
    elines = opts["elines"] if opts["elines"] else ("tmprgreen_%i_elines" %
                                                    pid)
    v.rast_stats(
        map=elines,
        layer=vlayer,
        flags="c",
        raster=comp,
        column_prefix="comp_cost",
        method="sum",
    )
    # add excavation costs
    v.rast_stats(
        map=elines,
        layer=vlayer,
        flags="c",
        raster=exc,
        column_prefix="exc_cost",
        method="sum",
    )
    write2struct(elines, opts)

    xcost = "{cname} = {alpha} * {em}"
    # add power station costs
    vcolcalc(
        vname=struct,
        vlayer=vlayer,
        ctype="double precision",
        expr=xcost.format(cname="station_cost",
                          em="em_cost",
                          alpha=opts["alpha_station"]),
    )
    # add inlet costs
    vcolcalc(
        vname=struct,
        vlayer=vlayer,
        ctype="double precision",
        notfinitesubstitute=0.0,
        expr=xcost.format(cname="inlet_cost",
                          em="em_cost",
                          alpha=opts["alpha_inlet"]),
    )
    # add total inlet costs
    # TODO: to be check to avoid to count cost more than one time I have moltiplied by 0.5
    tot = ("tot_cost = (comp_cost_sum + em_cost + el_comp_exc +"
           "lin_pipe_cost + lin_electro_cost + "
           "station_cost + inlet_cost + {grid}*0.5) * "
           "(1 + {general} + {hindrances})")
    vcolcalc(
        vname=struct,
        vlayer=vlayer,
        ctype="double precision",
        notfinitesubstitute=0.0,
        expr=tot.format(grid=opts["grid"],
                        general=opts["general"],
                        hindrances=opts["hindrances"]),
    )

    # TODO: produce a new vector map (output), with the conduct + penstock in
    # a unique line and sum the costs grouping by intake_id and side
    # SELECT {key} FROM {tname}
    # FIXME: intake_id and discharge can have different names
    group_by(
        struct,
        opts["output_struct"],
        isolate=[
            "intake_id",
            opts["struct_column_id"],
            opts["struct_column_side"],
            opts["struct_column_power"],
            opts["struct_column_head"],
            "discharge",
        ],
        aggregate=[
            "tot_cost",
        ],
        function="sum",
        group_by=["intake_id", opts["struct_column_side"]],
    )
    """
    where these values (3871.2256 and -0.45) are coming from?
    import numpy as np
    from scipy import stats

    power= np.array([50., 100., 200., 400., 600., 1000., 5000.])
    maint = np.array([707., 443., 389., 261., 209., 163., 88.])

    plt.plot(np.log(power), np.log(maint))
    plt.show()
    slope, intercept, r_value, p_value, std_err = stats.linregress(np.log(power), np.log(maint))
    #slope -0.45000431409701719
    #intercept 8.2613264284076049
    np.exp(intercept) * power ** slope

    """
    #    maint = "{cname} = {alpha} * {power} ** (1 + {beta}) + {const}"
    maint = "{cname} = {cost_per_kW} * {power} * {alpha} + {const}"
    # compute yearly maintenance costs
    vcolcalc(
        vname=opts["output_struct"],
        vlayer=vlayer,
        ctype="double precision",
        notfinitesubstitute=0.0,
        expr=maint.format(
            cname="maintenance",
            cost_per_kW=opts["cost_maintenance_per_kw"],
            alpha=opts["alpha_maintenance"],
            power=opts["struct_column_power"],
            beta=opts["beta_maintenance"],
            const=opts["const_maintenance"],
        ),
    )

    # compute yearly revenues
    rev = "{cname} = {eta} * {power} * {eprice} * {ophours}  + {const}"
    vcolcalc(
        vname=opts["output_struct"],
        vlayer=vlayer,
        ctype="double precision",
        notfinitesubstitute=0.0,
        expr=rev.format(
            cname="revenue",
            eta=opts["eta"],
            power=opts["struct_column_power"],
            eprice=opts["energy_price"],
            ophours=opts["operative_hours"],
            const=opts["const_revenue"],
        ),
    )

    # compute the Net Present Value
    npv = "{cname} = {gamma} * ({revenue} - {maintenance}) - {tot}"
    gamma_npv = get_gamma_NPV(irate, life)
    vcolcalc(
        vname=opts["output_struct"],
        vlayer=vlayer,
        ctype="double precision",
        notfinitesubstitute=0.0,
        expr=npv.format(
            cname="NPV",
            gamma=gamma_npv,
            revenue="revenue",
            maintenance="maintenance",
            tot="tot_cost",
        ),
    )

    economic2segment(
        economic=opts["output_struct"],
        segment=plant,
        basename=opts["plant_basename"],
        eco_layer=1,
        seg_layer=int(opts["plant_layer"]),
        eco_pid=opts["struct_column_id"],
        seg_pid=opts["plant_column_id"],
        function=max_NPV,
        exclude=["intake_id", "side", "power", "gross_head", "discharge"],
    )

    vec = VectorTopo(opts["output_struct"])
    vec.open("rw")
    vec.table.columns.add("max_NPV", "VARCHAR(3)")

    list_intakeid = list(
        set(
            vec.table.execute("SELECT intake_id FROM %s" %
                              vec.table.name).fetchall()))

    for i in range(0, len(list_intakeid)):
        vec.rewind()
        list_npv = list(
            vec.table.execute(
                "SELECT NPV FROM %s WHERE intake_id=%i;" %
                (vec.table.name, list_intakeid[i][0])).fetchall())
        npvmax = max(list_npv)[0]
        for line in vec:
            if line.attrs["intake_id"] == list_intakeid[i][0]:
                if line.attrs["NPV"] == npvmax:
                    line.attrs["max_NPV"] = "yes"
                else:
                    line.attrs["max_NPV"] = "no"

    vec.table.conn.commit()
    vec.close()
Example #3
0
def main():
    """
    Adds GSFLOW parameters to a set of HRU sub-basins
    """

    ##################
    # OPTION PARSING #
    ##################

    options, flags = gscript.parser()
    basins = options['input']
    HRU = options['output']
    slope = options['slope']
    aspect = options['aspect']
    elevation = options['elevation']
    land_cover = options['cov_type']
    soil = options['soil_type']

    ################################
    # CREATE HRUs FROM SUB-BASINS  #
    ################################

    g.copy(vector=(basins,HRU), overwrite=gscript.overwrite())

    ############################################
    # ATTRIBUTE COLUMNS (IN ORDER FROM MANUAL) #
    ############################################

    # HRU
    hru_columns = []
    # Self ID
    hru_columns.append('id integer') # nhru
    # Basic Physical Attributes (Geometry)
    hru_columns.append('hru_area double precision') # acres (!!!!)
    hru_columns.append('hru_area_m2 double precision') # [not for GSFLOW: for me!]
    hru_columns.append('hru_aspect double precision') # Mean aspect [degrees]
    hru_columns.append('hru_elev double precision') # Mean elevation
    hru_columns.append('hru_lat double precision') # Latitude of centroid
    hru_columns.append('hru_lon double precision') # Longitude of centroid
                                                   # unnecessary but why not?
    hru_columns.append('hru_slope double precision') # Mean slope [percent]
    # Basic Physical Attributes (Other)
    #hru_columns.append('hru_type integer') # 0=inactive; 1=land; 2=lake; 3=swale; almost all will be 1
    #hru_columns.append('elev_units integer') # 0=feet; 1=meters. 0=default. I think I will set this to 1 by default.
    # Measured input
    hru_columns.append('outlet_sta integer') # Index of streamflow station at basin outlet:
                                             # station number if it has one, 0 if not
    # Note that the below specify projections and note lat/lon; they really seem
    # to work for any projected coordinates, with _x, _y, in meters, and _xlong, 
    # _ylat, in feet (i.e. they are just northing and easting). The meters and feet
    # are not just simple conversions, but actually are required for different
    # modules in the code, and are hence redundant but intentional.
    hru_columns.append('hru_x double precision') # Easting [m]
    hru_columns.append('hru_xlong double precision') # Easting [feet]
    hru_columns.append('hru_y double precision') # Northing [m]
    hru_columns.append('hru_ylat double precision') # Northing [feet]
    # Streamflow and lake routing
    hru_columns.append('K_coef double precision') # Travel time of flood wave to next downstream segment;
                                                  # this is the Muskingum storage coefficient
                                                  # 1.0 for reservoirs, diversions, and segments flowing
                                                  # out of the basin
    hru_columns.append('x_coef double precision') # Amount of attenuation of flow wave;
                                                  # this is the Muskingum routing weighting factor
                                                  # range: 0.0--0.5; default 0.2
                                                  # 0 for all segments flowing out of the basin
    hru_columns.append('hru_segment integer') # ID of stream segment to which flow will be routed
                                              # this is for non-cascade routing (flow goes directly
                                              # from HRU to stream segment)
    hru_columns.append('obsin_segment integer') # Index of measured streamflow station that replaces
                                                # inflow to a segment
    hru_columns.append('cov_type integer') # 0=bare soil;1=grasses; 2=shrubs; 3=trees; 4=coniferous
    hru_columns.append('soil_type integer') # 1=sand; 2=loam; 3=clay

    # Create strings
    hru_columns = ",".join(hru_columns)

    # Add columns to tables
    v.db_addcolumn(map=HRU, columns=hru_columns, quiet=True)


    ###########################
    # UPDATE DATABASE ENTRIES #
    ###########################

    colNames = np.array(gscript.vector_db_select(HRU, layer=1)['columns'])
    colValues = np.array(gscript.vector_db_select(HRU, layer=1)['values'].values())
    number_of_hrus = colValues.shape[0]
    cats = colValues[:,colNames == 'cat'].astype(int).squeeze()
    rnums = colValues[:,colNames == 'rnum'].astype(int).squeeze()

    nhru = np.arange(1, number_of_hrus + 1)
    nhrut = []
    for i in range(len(nhru)):
      nhrut.append( (nhru[i], cats[i]) )
    # Access the HRUs 
    hru = VectorTopo(HRU)
    # Open the map with topology:
    hru.open('rw')
    # Create a cursor
    cur = hru.table.conn.cursor()
    # Use it to loop across the table
    cur.executemany("update "+HRU+" set id=? where cat=?", nhrut)
    # Commit changes to the table
    hru.table.conn.commit()
    # Close the table
    hru.close()

    """
    # Do the same for basins <-------------- DO THIS OR SIMPLY HAVE HRUs OVERLAIN WITH GRID CELLS? IN THIS CASE, RMV AREA ADDITION TO GRAVRES
    v.db_addcolumn(map=basins, columns='id int', quiet=True)
    basins = VectorTopo(basins)
    basins.open('rw')
    cur = basins.table.conn.cursor()
    cur.executemany("update basins set id=? where cat=?", nhrut)
    basins.table.conn.commit()
    basins.close()
    """

    # if you want to append to table
    # cur.executemany("update HRU(id) values(?)", nhrut) # "insert into" will add rows

    #hru_columns.append('hru_area double precision')
    # Acres b/c USGS
    v.to_db(map=HRU, option='area', columns='hru_area', units='acres', quiet=True)
    v.to_db(map=HRU, option='area', columns='hru_area_m2', units='meters', quiet=True)

    # GET MEAN VALUES FOR THESE NEXT ONES, ACROSS THE BASIN

    # SLOPE (and aspect) 
    #####################
    v.rast_stats(map=HRU, raster=slope, method='average', column_prefix='tmp', flags='c', quiet=True)
    v.db_update(map=HRU, column='hru_slope', query_column='tmp_average', quiet=True)

    # ASPECT
    #########
    v.db_dropcolumn(map=HRU, columns='tmp_average', quiet=True)
    # Dealing with conversion from degrees (no good average) to something I can
    # average -- x- and y-vectors
    # Geographic coordinates, so sin=x, cos=y.... not that it matters so long 
    # as I am consistent in how I return to degrees
    r.mapcalc('aspect_x = sin(' + aspect + ')', overwrite=gscript.overwrite(), quiet=True)
    r.mapcalc('aspect_y = cos(' + aspect + ')', overwrite=gscript.overwrite(), quiet=True)
    #grass.run_command('v.db.addcolumn', map=HRU, columns='aspect_x_sum double precision, aspect_y_sum double precision, ncells_in_hru integer')
    v.rast_stats(map=HRU, raster='aspect_x', method='sum', column_prefix='aspect_x', flags='c', quiet=True)
    v.rast_stats(map=HRU, raster='aspect_y', method='sum', column_prefix='aspect_y', flags='c', quiet=True)
    hru = VectorTopo(HRU)
    hru.open('rw')
    cur = hru.table.conn.cursor()
    cur.execute("SELECT cat,aspect_x_sum,aspect_y_sum FROM %s" %hru.name)
    _arr = np.array(cur.fetchall()).astype(float)
    _cat = _arr[:,0]
    _aspect_x_sum = _arr[:,1]
    _aspect_y_sum = _arr[:,2]
    aspect_angle = np.arctan2(_aspect_y_sum, _aspect_x_sum) * 180. / np.pi
    aspect_angle[aspect_angle < 0] += 360 # all positive
    aspect_angle_cat = np.vstack((aspect_angle, _cat)).transpose()
    cur.executemany("update "+ HRU +" set hru_aspect=? where cat=?", aspect_angle_cat)
    hru.table.conn.commit()
    hru.close()

    # ELEVATION
    ############
    v.rast_stats(map=HRU, raster=elevation, method='average', column_prefix='tmp', flags='c', quiet=True)
    v.db_update(map=HRU, column='hru_elev', query_column='tmp_average', quiet=True)
    v.db_dropcolumn(map=HRU, columns='tmp_average', quiet=True)

    # CENTROIDS 
    ############

    # get x,y of centroid -- but have areas not in database table, that do have
    # centroids, and having a hard time finding a good way to get rid of them!
    # They have duplicate category values!
    # Perhaps these are little dangles on the edges of the vectorization where
    # the raster value was the same but pinched out into 1-a few cells?
    # From looking at map, lots of extra centroids on area boundaries, and removing
    # small areas (though threshold hard to guess) gets rid of these

    hru = VectorTopo(HRU)
    hru.open('rw')
    hru_cats = []
    hru_coords = []
    for hru_i in hru:
        if type(hru_i) is vector.geometry.Centroid:
            hru_cats.append(hru_i.cat)
            hru_coords.append(hru_i.coords())
    hru_cats = np.array(hru_cats)
    hru_coords = np.array(hru_coords)
    hru.rewind()
    
    hru_area_ids = []
    for coor in hru_coords:
        _area = hru.find_by_point.area(Point(coor[0], coor[1]))
        hru_area_ids.append(_area)
    hru_area_ids = np.array(hru_area_ids)
    hru.rewind()

    hru_areas = []
    for _area_id in hru_area_ids:
        hru_areas.append(_area_id.area())
    hru_areas = np.array(hru_areas)
    hru.rewind()
      
    allcats = sorted(list(set(list(hru_cats))))
    
    # Now create weighted mean
    hru_centroid_locations = []
    for cat in allcats:
        hrus_with_cat = hru_cats[hru_cats == cat]
        if len(hrus_with_cat) == 1:
            hru_centroid_locations.append((hru_coords[hru_cats == cat]).squeeze())
        else:
            _centroids = hru_coords[hru_cats == cat]
            #print _centroids
            _areas = hru_areas[hru_cats == cat]
            #print _areas
            _x = np.average(_centroids[:,0], weights=_areas)
            _y = np.average(_centroids[:,1], weights=_areas)
            #print _x, _y
            hru_centroid_locations.append(np.array([_x, _y]))
          
    # Now upload weighted mean to database table
    # allcats and hru_centroid_locations are co-indexed
    index__cats = create_iterator(HRU)
    cur = hru.table.conn.cursor()
    for i in range(len(allcats)):
        # meters
        cur.execute('update '+HRU
                    +' set hru_x='+str(hru_centroid_locations[i][0])
                    +' where cat='+str(allcats[i]))
        cur.execute('update '+HRU
                    +' set hru_y='+str(hru_centroid_locations[i][1])
                    +' where cat='+str(allcats[i]))
        # feet
        cur.execute('update '+HRU
                    +' set hru_xlong='+str(hru_centroid_locations[i][0]*3.28084)
                    +' where cat='+str(allcats[i]))
        cur.execute('update '+HRU
                    +' set hru_ylat='+str(hru_centroid_locations[i][1]*3.28084)
                    +' where cat='+str(allcats[i]))
        # (un)Project to lat/lon
        _centroid_ll = gscript.parse_command('m.proj',
                                             coordinates=
                                             list(hru_centroid_locations[i]),
                                             flags='od').keys()[0]
        _lon, _lat, _z = _centroid_ll.split('|')
        cur.execute('update '+HRU
                    +' set hru_lon='+_lon
                    +' where cat='+str(allcats[i]))
        cur.execute('update '+HRU
                    +' set hru_lat='+_lat
                    +' where cat='+str(allcats[i]))

    # feet -- not working.
    # Probably an issue with index__cats -- maybe fix later, if needed
    # But currently not a major speed issue
    """
    cur.executemany("update "+HRU+" set hru_xlong=?*3.28084 where hru_x=?", 
                    index__cats)
    cur.executemany("update "+HRU+" set hru_ylat=?*3.28084 where hru_y=?", 
                    index__cats)
    """                    

    cur.close()
    hru.table.conn.commit()
    hru.close()

    # ID NUMBER
    ############
    #cur.executemany("update "+HRU+" set hru_segment=? where id=?", 
    #                index__cats)
    # Segment number = HRU ID number
    v.db_update(map=HRU, column='hru_segment', query_column='id', quiet=True)

    # LAND USE/COVER
    ############
    try:
        land_cover = int(land_cover)
    except:
        pass
    if type(land_cover) is int:
        if land_cover <= 3:
            v.db_update(map=HRU, column='cov_type', value=land_cover, quiet=True)
        else:
            sys.exit("WARNING: INVALID LAND COVER TYPE. CHECK INTEGER VALUES.\n"
                     "EXITING TO ALLOW USER TO CHANGE BEFORE RUNNING GSFLOW")
    else:
        # NEED TO UPDATE THIS TO MODAL VALUE!!!!
        gscript.message("Warning: values taken from HRU centroids. Code should be updated to")
        gscript.message("acquire modal values")
        v.what_rast(map=HRU, type='centroid', raster=land_cover, column='cov_type', quiet=True)
        #v.rast_stats(map=HRU, raster=land_cover, method='average', column_prefix='tmp', flags='c', quiet=True)
        #v.db_update(map=HRU, column='cov_type', query_column='tmp_average', quiet=True)
        #v.db_dropcolumn(map=HRU, columns='tmp_average', quiet=True)

    # SOIL
    ############
    try:
        soil = int(soil)
    except:
        pass
    if type(soil) is int:
        if (soil > 0) and (soil <= 3):
            v.db_update(map=HRU, column='soil_type', value=soil, quiet=True)
        else:
            sys.exit("WARNING: INVALID SOIL TYPE. CHECK INTEGER VALUES.\n"
                     "EXITING TO ALLOW USER TO CHANGE BEFORE RUNNING GSFLOW")
    else:
        # NEED TO UPDATE THIS TO MODAL VALUE!!!!
        gscript.message("Warning: values taken from HRU centroids. Code should be updated to")
        gscript.message("acquire modal values")
        v.what_rast(map=HRU, type='centroid', raster=soil, column='soil_type', quiet=True)
Example #4
0
from grass.pygrass import utils

#############
# WORKSPACE #
#############

# Unsorted arrays: what is at start and what is at end?
streamsTopo = VectorTopo('streams', overwrite=True)
streamsTopo.build()
streamsTopo.open(mode='rw')

# Order everything
cats_full = [] # points and lines
for row in streamsTopo:
  cats_full.append(row.cat)
streamsTopo.rewind()
cats_full_order = np.argsort(cats)
streamsTopo_a = np.array(streamsTopo)
streamsTopo_a = streamsTopo_a[cats_full_order] # Place in order of ascending category

# NEW STRATEGY -- NO NEED TO ORGANIZE. SIMPLY FIND START AND END POINTS!
# Those points with id 0 will occur only at the start of the whole system.
# These are the headwaters; march downstream from here.
points = []
point_type_codes = [] # 0 = headwaters; 1 = downstream
point_cats = []
lines = []
line_type_codes = [] # 0 = headwaters; 1 = downstream
line_cats = []
streamsTopo = VectorTopo('streams', overwrite=True)
streamsTopo.build()