예제 #1
0
def main():
    soilloss = options['soilloss']
    soilloss3 = soilloss # + '.3'
    map = options['map']
    parcelnumcol = options['parcelnumcol']
    flag_l = flags['l']
    flag_h = flags['h']
  
    quiet = True
    if gscript.verbosity() > 2:
        quiet=False

    zones = map.split('@')[0] + '.zones'
    v.to_rast( input=map, use='attr', attrcolumn=parcelnumcol,
              output=zones, quiet=quiet)
    
    
    def printStats(table, tablefmt='simple'):
        try:
            from tabulate import tabulate
        except:
            gscript.warning('Install tabulate for pretty printing tabular output ($ pip install tabulate). Using pprint instead...')
            from pprint import pprint
            pprint(statout)
        print tabulate(table,headers='firstrow',tablefmt=tablefmt)
         
    if not flag_h:
        runivar = r.univar(map=soilloss, zones=zones, flags='t', stdout=gscript.PIPE)
        rstats = runivar.outputs.stdout.strip().split('\n')
        #show all available values columns
        #rstats[0].split('|')
        rstatout = []
        for line in range(len(rstats)):
            lineout = []
            for i in (0,7,9,4,5): 
                lineout += (rstats[line].split('|')[i],)
            rstatout.append(lineout)
            
        if flag_l: printStats(rstatout, tablefmt='latex')
        else: printStats(rstatout)
        
    if flag_h:
            
        r.report(map=(zones,soilloss3),units='p',flags='')
예제 #2
0
def main():

    elevation = options['elevation']
    slope = options['slope']
    flat_thres = float(options['flat_thres'])
    curv_thres = float(options['curv_thres'])
    filter_size = int(options['filter_size'])
    counting_size = int(options['counting_size'])
    nclasses = int(options['classes'])
    texture = options['texture']
    convexity = options['convexity']
    concavity = options['concavity']
    features = options['features']

    # remove mapset from output name in case of overwriting existing map
    texture = texture.split('@')[0]
    convexity = convexity.split('@')[0]
    concavity = concavity.split('@')[0]
    features = features.split('@')[0]

    # store current region settings
    global current_reg
    current_reg = parse_key_val(g.region(flags='pg', stdout_=PIPE).outputs.stdout)
    del current_reg['projection']
    del current_reg['zone']
    del current_reg['cells']

    # check for existing mask and backup if found
    global mask_test
    mask_test = gs.list_grouped(
        type='rast', pattern='MASK')[gs.gisenv()['MAPSET']]
    if mask_test:
        global original_mask
        original_mask = temp_map('tmp_original_mask')
        g.copy(raster=['MASK', original_mask])

    # error checking
    if flat_thres < 0:
        gs.fatal('Parameter thres cannot be negative')

    if filter_size % 2 == 0 or counting_size % 2 == 0:
        gs.fatal(
            'Filter or counting windows require an odd-numbered window size')

    if filter_size >= counting_size:
        gs.fatal(
            'Filter size needs to be smaller than the counting window size')
    
    if features != '' and slope == '':
        gs.fatal('Need to supply a slope raster in order to produce the terrain classification')
                
    # Terrain Surface Texture -------------------------------------------------
    # smooth the dem
    gs.message("Calculating terrain surface texture...")
    gs.message(
        "1. Smoothing input DEM with a {n}x{n} median filter...".format(
            n=filter_size))
    filtered_dem = temp_map('tmp_filtered_dem')
    gs.run_command("r.neighbors", input = elevation, method = "median",
                    size = filter_size, output = filtered_dem, flags='c',
                    quiet=True)

    # extract the pits and peaks based on the threshold
    pitpeaks = temp_map('tmp_pitpeaks')
    gs.message("2. Extracting pits and peaks with difference > thres...")
    r.mapcalc(expression='{x} = if ( abs({dem}-{median})>{thres}, 1, 0)'.format(
                x=pitpeaks, dem=elevation, thres=flat_thres, median=filtered_dem),
                quiet=True)

    # calculate density of pits and peaks
    gs.message("3. Using resampling filter to create terrain texture...")
    window_radius = (counting_size-1)/2
    y_radius = float(current_reg['ewres'])*window_radius
    x_radius = float(current_reg['nsres'])*window_radius
    resample = temp_map('tmp_density')
    r.resamp_filter(input=pitpeaks, output=resample, filter=['bartlett','gauss'],
                    radius=[x_radius,y_radius], quiet=True)

    # convert to percentage
    gs.message("4. Converting to percentage...")
    r.mask(raster=elevation, overwrite=True, quiet=True)
    r.mapcalc(expression='{x} = float({y} * 100)'.format(x=texture, y=resample),
               quiet=True)
    r.mask(flags='r', quiet=True)
    r.colors(map=texture, color='haxby', quiet=True)

    # Terrain convexity/concavity ---------------------------------------------
    # surface curvature using lacplacian filter
    gs.message("Calculating terrain convexity and concavity...")
    gs.message("1. Calculating terrain curvature using laplacian filter...")
    
    # grow the map to remove border effects and run laplacian filter
    dem_grown = temp_map('tmp_elevation_grown')
    laplacian = temp_map('tmp_laplacian')
    g.region(n=float(current_reg['n']) + (float(current_reg['nsres']) * filter_size),
             s=float(current_reg['s']) - (float(current_reg['nsres']) * filter_size),
             w=float(current_reg['w']) - (float(current_reg['ewres']) * filter_size),
             e=float(current_reg['e']) + (float(current_reg['ewres']) * filter_size))

    r.grow(input=elevation, output=dem_grown, radius=filter_size, quiet=True)
    r.mfilter(
        input=dem_grown, output=laplacian,
        filter=string_to_rules(laplacian_matrix(filter_size)), quiet=True)

    # extract convex and concave pixels
    gs.message("2. Extracting convexities and concavities...")
    convexities = temp_map('tmp_convexities')
    concavities = temp_map('tmp_concavities')

    r.mapcalc(
        expression='{x} = if({laplacian}>{thres}, 1, 0)'\
        .format(x=convexities, laplacian=laplacian, thres=curv_thres),
        quiet=True)
    r.mapcalc(
        expression='{x} = if({laplacian}<-{thres}, 1, 0)'\
        .format(x=concavities, laplacian=laplacian, thres=curv_thres),
        quiet=True)

    # calculate density of convexities and concavities
    gs.message("3. Using resampling filter to create surface convexity/concavity...")
    resample_convex = temp_map('tmp_convex')
    resample_concav = temp_map('tmp_concav')
    r.resamp_filter(input=convexities, output=resample_convex,
                    filter=['bartlett','gauss'], radius=[x_radius,y_radius],
                    quiet=True)
    r.resamp_filter(input=concavities, output=resample_concav,
                    filter=['bartlett','gauss'], radius=[x_radius,y_radius],
                    quiet=True)

    # convert to percentages
    gs.message("4. Converting to percentages...")
    g.region(**current_reg)
    r.mask(raster=elevation, overwrite=True, quiet=True)
    r.mapcalc(expression='{x} = float({y} * 100)'.format(x=convexity, y=resample_convex),
               quiet=True)
    r.mapcalc(expression='{x} = float({y} * 100)'.format(x=concavity, y=resample_concav),
               quiet=True)
    r.mask(flags='r', quiet=True)

    # set colors
    r.colors_stddev(map=convexity, quiet=True)
    r.colors_stddev(map=concavity, quiet=True)

    # Terrain classification Flowchart-----------------------------------------
    if features != '':
        gs.message("Performing terrain surface classification...")
        # level 1 produces classes 1 thru 8
        # level 2 produces classes 5 thru 12
        # level 3 produces classes 9 thru 16
        if nclasses == 8: levels = 1
        if nclasses == 12: levels = 2
        if nclasses == 16: levels = 3

        classif = []
        for level in range(levels):
            # mask previous classes x:x+4
            if level != 0:
                min_cla = (4*(level+1))-4
                clf_msk = temp_map('tmp_clf_mask')
                rules = '1:{0}:1'.format(min_cla)
                r.recode(
                    input=classif[level-1], output=clf_msk,
                    rules=string_to_rules(rules), overwrite=True)
                r.mask(raster=clf_msk, flags='i', quiet=True, overwrite=True)

            # image statistics
            smean = r.univar(
                map=slope, flags='g', stdout_=PIPE).outputs.stdout.split(os.linesep)
            smean = [i for i in smean if i.startswith('mean=') is True][0].split('=')[1]

            cmean = r.univar(
                map=convexity, flags='g', stdout_=PIPE).outputs.stdout.split(os.linesep)
            cmean = [i for i in cmean if i.startswith('mean=') is True][0].split('=')[1]

            tmean = r.univar(
                map=texture, flags='g', stdout_=PIPE).outputs.stdout.split(os.linesep)
            tmean = [i for i in tmean if i.startswith('mean=') is True][0].split('=')[1]
            classif.append(temp_map('tmp_classes'))
            
            if level != 0:
                r.mask(flags='r', quiet=True)

            classification(level+1, slope, smean, texture, tmean,
                            convexity, cmean, classif[level])

        # combine decision trees
        merged = []
        for level in range(0, levels):
            if level > 0:
                min_cla = (4*(level+1))-4
                merged.append(temp_map('tmp_merged'))
                r.mapcalc(
                    expression='{x} = if({a}>{min}, {b}, {a})'.format(
                        x=merged[level], min=min_cla, a=merged[level-1],  b=classif[level]))
            else:
                merged.append(classif[level])
        g.rename(raster=[merged[-1], features], quiet=True)
        del TMP_RAST[-1]

    # Write metadata ----------------------------------------------------------
    history = 'r.terrain.texture '
    for key,val in options.iteritems():
        history += key + '=' + str(val) + ' '

    r.support(map=texture,
              title=texture,
              description='generated by r.terrain.texture',
              history=history)
    r.support(map=convexity,
              title=convexity,
              description='generated by r.terrain.texture',
              history=history)
    r.support(map=concavity,
              title=concavity,
              description='generated by r.terrain.texture',
              history=history)

    if features != '':
        r.support(map=features,
                  title=features,
                  description='generated by r.terrain.texture',
                  history=history)
        
        # write color and category rules to tempfiles                
        r.category(
            map=features,
            rules=string_to_rules(categories(nclasses)),
            separator='pipe')
        r.colors(
            map=features, rules=string_to_rules(colors(nclasses)), quiet=True)

    return 0
예제 #3
0
def main():
    # options and flags
    options, flags = gs.parser()
    input_raster = options["input"]
    minradius = int(options["minradius"])
    maxradius = int(options["maxradius"])
    steps = int(options["steps"])
    output_raster = options["output"]

    region = Region()
    res = np.mean([region.nsres, region.ewres])

    # some checks
    if "@" in output_raster:
        output_raster = output_raster.split("@")[0]

    if maxradius <= minradius:
        gs.fatal("maxradius must be greater than minradius")

    if steps < 2:
        gs.fatal("steps must be greater than 1")

    # calculate radi for generalization
    radi = np.logspace(np.log(minradius),
                       np.log(maxradius),
                       steps,
                       base=np.exp(1),
                       dtype=np.int)
    radi = np.unique(radi)
    sizes = radi * 2 + 1

    # multiscale calculation
    ztpi_maps = list()

    for step, (radius, size) in enumerate(zip(radi[::-1], sizes[::-1])):
        gs.message(
            "Calculating the TPI at radius {radius}".format(radius=radius))

        # generalize the dem
        step_res = res * size
        step_res_pretty = str(step_res).replace(".", "_")
        generalized_dem = gs.tempname(4)

        if size > 15:
            step_dem = gs.tempname(4)
            gg.region(res=str(step_res))
            gr.resamp_stats(
                input=input_raster,
                output=step_dem,
                method="average",
                flags="w",
            )
            gr.resamp_rst(
                input=step_dem,
                ew_res=res,
                ns_res=res,
                elevation=generalized_dem,
                quiet=True,
            )
            region.write()
            gg.remove(type="raster", name=step_dem, flags="f", quiet=True)
        else:
            gr.neighbors(input=input_raster, output=generalized_dem, size=size)

        # calculate the tpi
        tpi = gs.tempname(4)
        gr.mapcalc(expression="{x} = {a} - {b}".format(
            x=tpi, a=input_raster, b=generalized_dem))
        gg.remove(type="raster", name=generalized_dem, flags="f", quiet=True)

        # standardize the tpi
        raster_stats = gr.univar(map=tpi, flags="g",
                                 stdout_=PIPE).outputs.stdout
        raster_stats = parse_key_val(raster_stats)
        tpi_mean = float(raster_stats["mean"])
        tpi_std = float(raster_stats["stddev"])
        ztpi = gs.tempname(4)
        ztpi_maps.append(ztpi)
        RAST_REMOVE.append(ztpi)

        gr.mapcalc(expression="{x} = ({a} - {mean})/{std}".format(
            x=ztpi, a=tpi, mean=tpi_mean, std=tpi_std))
        gg.remove(type="raster", name=tpi, flags="f", quiet=True)

        # integrate
        if step > 1:
            tpi_updated2 = gs.tempname(4)
            gr.mapcalc("{x} = if(abs({a}) > abs({b}), {a}, {b})".format(
                a=ztpi_maps[step], b=tpi_updated1, x=tpi_updated2))
            RAST_REMOVE.append(tpi_updated2)
            tpi_updated1 = tpi_updated2
        else:
            tpi_updated1 = ztpi_maps[0]

    RAST_REMOVE.pop()
    gg.rename(raster=(tpi_updated2, output_raster), quiet=True)

    # set color theme
    with RasterRow(output_raster) as src:
        color_rules = """{minv} blue
            -1 0:34:198
            0 255:255:255
            1 255:0:0
            {maxv} 110:15:0
            """
        color_rules = color_rules.format(minv=src.info.min, maxv=src.info.max)
        gr.colors(map=output_raster, rules="-", stdin_=color_rules, quiet=True)