Esempio n. 1
0
def normalize_map(raster, output_name):
    """
    Normalize all raster map cells by subtracting the raster map's minimum and
    dividing by the range.

    Parameters
    ----------
    raster :
        Name of input raster map

    output_name :
        Name of output raster map

    Returns
    -------

    Examples
    --------
    ...
    """
    # grass.debug(_("Input to normalize: {name}".format(name=raster)))
    # grass.debug(_("Ouput: {name}".format(name=output_name)))

    finding = grass.find_file(name=raster, element="cell")

    if not finding["file"]:
        grass.fatal("Raster map {name} not found".format(name=raster))
    # else:
    #     grass.debug("Raster map {name} found".format(name=raster))

    # univar_string = grass.read_command('r.univar', flags='g', map=raster)
    # univar_string = univar_string.replace('\n', '| ').replace('\r', '| ')
    # msg = "Univariate statistics: {us}".format(us=univar_string)

    minimum = grass.raster_info(raster)["min"]
    grass.debug(_("Minimum: {m}".format(m=minimum)))

    maximum = grass.raster_info(raster)["max"]
    grass.debug(_("Maximum: {m}".format(m=maximum)))

    if minimum is None or maximum is None:
        msg = "Minimum and maximum values of the <{raster}> map are 'None'. "
        msg += "The {raster} map may be empty "
        msg += "OR the MASK opacifies all non-NULL cells."
        grass.fatal(_(msg.format(raster=raster)))

    normalisation = "float(({raster} - {minimum}) / ({maximum} - {minimum}))"
    normalisation = normalisation.format(raster=raster,
                                         minimum=minimum,
                                         maximum=maximum)

    # Maybe this can go in the parent function? 'raster' names are too long!
    # msg = "Normalization expression: "
    # msg += normalisation
    # grass.verbose(_(msg))

    normalisation_equation = EQUATION.format(result=output_name,
                                             expression=normalisation)
    grass.mapcalc(normalisation_equation, overwrite=True)
    get_univariate_statistics(output_name)
Esempio n. 2
0
def test_tiling_schemes(tmp_path, width, height):
    """Check that different shapes of tiles work"""
    location = "test"
    gs.core._create_location_xy(tmp_path, location)  # pylint: disable=protected-access
    with grass_setup.init(tmp_path / location):
        gs.run_command("g.region", s=0, n=50, w=0, e=50, res=1)

        surface = "surface"
        gs.run_command("r.surf.fractal", output=surface)

        def run_grid_module():
            # modules/shortcuts calls get_commands which requires GISBASE.
            # pylint: disable=import-outside-toplevel
            from grass.pygrass.modules.grid import GridModule

            grid = GridModule(
                "r.slope.aspect",
                width=width,
                height=height,
                overlap=2,
                processes=max_processes(),
                elevation=surface,
                slope="slope",
                aspect="aspect",
            )
            grid.run()

        run_in_subprocess(run_grid_module)

        info = gs.raster_info("slope")
        assert info["min"] > 0
Esempio n. 3
0
 def _import_file(self, filename, module, args):
     mapname = self._map_name(filename)
     gs.message(_("Processing <{}>...").format(mapname))
     if module == "r.import":
         self._args["resolution_value"] = self._raster_resolution(filename)
     try:
         gs.run_command(module,
                        input=filename,
                        output=mapname,
                        **self._args)
         if gs.raster_info(mapname)["datatype"] in ("FCELL", "DCELL"):
             gs.message("Rounding to integer after reprojection")
             gs.use_temp_region()
             gs.run_command("g.region", raster=mapname)
             gs.run_command(
                 "r.mapcalc",
                 quiet=True,
                 expression="tmp_%s = round(%s)" % (mapname, mapname),
             )
             gs.run_command(
                 "g.rename",
                 quiet=True,
                 overwrite=True,
                 raster="tmp_%s,%s" % (mapname, mapname),
             )
             gs.del_temp_region()
         gs.raster_history(mapname)
     except CalledModuleError as e:
         pass  # error already printed
def adjust_coordinates(points, real_elev):
    info = gscript.raster_info(real_elev)
    orig_width = info['east'] - info['west']
    orig_height = info['north'] - info['south']
    orig_ratio = orig_width / orig_height

    width = abs(points[0][0] - points[1][0])
    height = abs(points[0][1] - points[1][1])
    ratio = width / height

    minx = min(points[0][0], points[1][0])
    miny = min(points[0][1], points[1][1])

    if orig_ratio > ratio:
        new_height = height
        new_width = new_height * orig_ratio
        minx = minx - (new_width - width) / 2
    else:
        new_width = width
        new_height = new_width / orig_ratio
        miny = miny - (new_height - height) / 2

    maxx = minx + new_width
    maxy = miny + new_height
    return ((minx, miny), (maxx, maxy))
Esempio n. 5
0
def run_geomorphons(real_elev, scanned_elev, env, **kwargs):
    analyses.geomorphon(scanned_elev,
                        new="geomorphon",
                        search=12,
                        skip=4,
                        flat=1,
                        dist=0,
                        env=env)
    # convert peaks to points
    gs.mapcalc("peaks = if(geomorphon == 2, 1, null())", env=env)
    gs.run_command("r.clump", input="peaks", output="clumped_peaks", env=env)
    gs.run_command(
        "r.volume",
        input="clumped_peaks",
        clump="clumped_peaks",
        centroids="peaks",
        errors="exit",
        env=env,
    )
    # contours
    info = gs.raster_info(scanned_elev)
    interval = (info["max"] - info["min"]) / 20.0
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours",
        step=interval,
        flags="t",
        env=env,
    )
Esempio n. 6
0
def indicatrix(raster, size):
    env = os.environ.copy()
    env['GRASS_OVERWRITE'] = '1'
    env['GRASS_VERBOSE'] = '0'
    env['GRASS_REGION'] = gscript.region_env(raster=raster)
    info = gscript.raster_info(raster)
    number = [3, 5]
    ew = info['east'] - info['west']
    ns = info['north'] - info['south']
    ew_step = ew / float(number[0] + 1)
    ns_step = ns / float(number[1] + 1)
    name = raster + '_indicatrix'
    circle_tmp = 'tmp_circle'
    circle_tmp2 = 'tmp_circle2'
    gscript.mapcalc('{} = null()'.format(circle_tmp2), overwrite=True)
    for i in range(number[0]):
        for j in range(number[1] - 1):
            gscript.run_command('r.circle', output=circle_tmp, min=size, max=size + 1, flags='b',
                                coordinates=[info['west'] + (i + 1) * ew_step, info['south'] + (j + 1) * ns_step],
                                env=env)
            gscript.run_command('r.patch', input=[circle_tmp, circle_tmp2], output=name, env=env)
            gscript.run_command('g.copy', raster=[name, circle_tmp2], env=env)

    gscript.run_command('r.to.vect', input=name, output=name, type='line', flags='vt', env=env)
    gscript.run_command('g.remove', type='raster', flags='f', name=[circle_tmp, circle_tmp2], env=env)
    return name
Esempio n. 7
0
def import_raster(filename, module, args):
    mapname = _map_name(filename)
    gs.message(_("Processing <{}>...").format(mapname))
    if module == "r.import":
        kv = gs.parse_command("g.proj", flags="j")
        if kv["+proj"] == "longlat":
            args["resolution"] = "estimated"
        else:
            args["resolution"] = "value"
            args["resolution_value"] = _raster_resolution(filename)
    try:
        gs.run_command(module, input=filename, output=mapname, **args)
        if gs.raster_info(mapname)["datatype"] in ("FCELL", "DCELL"):
            gs.message("Rounding to integer after reprojection")
            gs.use_temp_region()
            gs.run_command("g.region", raster=mapname)
            gs.run_command(
                "r.mapcalc",
                quiet=True,
                expression="tmp_%s = round(%s)" % (mapname, mapname),
            )
            gs.run_command(
                "g.rename",
                quiet=True,
                overwrite=True,
                raster="tmp_%s,%s" % (mapname, mapname),
            )
            gs.del_temp_region()
        gs.raster_history(mapname)
    except CalledModuleError as e:
        pass  # error already printed
Esempio n. 8
0
def createConfFile(res, inpumap, home):
    # set the name of conf file
    name = "conf_diversity_" + str(res)
    confilename = os.path.join(home, name)
    # start the text for the conf file
    outputLine = ["SAMPLINGFRAME 0|0|1|1\n"]
    # return r.info about input file
    rinfo = grass.raster_info(inpumap)
    # calculate number of lines
    rows = (rinfo["north"] - rinfo["south"]) / rinfo["nsres"]
    # calculate number of columns
    columns = (rinfo["east"] - rinfo["west"]) / rinfo["ewres"]
    # value for row
    rV = int(res) / rows
    # value for column
    cV = int(res) / columns
    # append the text for the conf file
    outputLine.append("SAMPLEAREA -1|-1|" + str(rV) + "|" + str(cV) + "\n")
    outputLine.append("MOVINGWINDOW\n")
    # open configuration file
    fileConf = open(confilename, "w")
    # write file
    fileConf.writelines(outputLine)
    # close file
    fileConf.close()
Esempio n. 9
0
    def InitRasterOpts(self, rasterList, plottype):
        """Initialize or update raster dictionary for plotting"""

        rdict = {}  # initialize a dictionary
        self.properties["raster"] = UserSettings.Get(group=self.plottype, key="raster")

        for r in rasterList:
            idx = rasterList.index(r)

            try:
                ret = grass.raster_info(r)
            except:
                continue
                # if r.info cannot parse map, skip it

            self.raster[r] = self.properties["raster"]  # some default settings
            rdict[r] = {}  # initialize sub-dictionaries for each raster in the list

            rdict[r]["units"] = ""
            if ret["units"] not in ("(none)", '"none"', "", None):
                rdict[r]["units"] = ret["units"]

            rdict[r]["plegend"] = r  # use fully-qualified names
            # list of cell value,frequency pairs for plotting histogram
            rdict[r]["datalist"] = []
            rdict[r]["pline"] = None
            rdict[r]["datatype"] = ret["datatype"]

            #
            # initialize with saved values
            #
            if self.properties["raster"]["pwidth"] is not None:
                rdict[r]["pwidth"] = self.properties["raster"]["pwidth"]
            else:
                rdict[r]["pwidth"] = 1

            if (
                self.properties["raster"]["pstyle"] is not None
                and self.properties["raster"]["pstyle"] != ""
            ):
                rdict[r]["pstyle"] = self.properties["raster"]["pstyle"]
            else:
                rdict[r]["pstyle"] = "solid"

            if idx < len(self.colorList):
                if idx == 0:
                    # use saved color for first plot
                    if self.properties["raster"]["pcolor"] is not None:
                        rdict[r]["pcolor"] = self.properties["raster"]["pcolor"]
                    else:
                        rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]]
                else:
                    rdict[r]["pcolor"] = self.colorDict[self.colorList[idx]]
            else:
                r = randint(0, 255)
                b = randint(0, 255)
                g = randint(0, 255)
                rdict[r]["pcolor"] = (r, g, b, 255)

        return rdict
Esempio n. 10
0
def controlPoints(inputmap):
    """ This function serve to return the coordinates of the photo's four
    vertex

    :param str inpumap: the input raster map's name
    """

    # return r.info about input file
    rinfo = grass.raster_info(inputmap)
    nsres = rinfo['nsres']
    ewres = rinfo['ewres']
    # create a dictionary for Nord East
    NE = [rinfo['east'] - 2 * ewres, rinfo["north"] - 2 * nsres]
    # create a dictionary for Nord West
    NW = [rinfo['west'] + 2 * ewres, rinfo["north"] - 2 * nsres]
    # create a dictionary for Sud East
    SE = [rinfo['east'] - 2 * ewres, rinfo["south"] + 2 * nsres]
    # create a dictionary for Sud West
    SW = [rinfo['west'] + 2 * ewres, rinfo["south"] + 2 * nsres]
    ## create a dictionary for Nord Center
    #NC = {'x':rinfo['east']-(rinfo['east']-rinfo['west'])/2, 'y':rinfo["north"]-2*nsres}
    ## create a dictionary for Sud Center
    #SC = {'x':rinfo['east']-(rinfo['east']-rinfo['west'])/2,'y':rinfo["south"]+2*nsres}
    ## create a dictionary for West Center
    #WC = {'x':rinfo['west']+2*ewres, 'y':rinfo["north"] - (rinfo["north"] - rinfo["south"]) / 2 }
    ## create a dictionary for East Center
    #EC = {'x':rinfo['east']-2*ewres, 'y':rinfo["north"]- (rinfo["north"] - rinfo["south"]) / 2}
    # create a dictionary to return the four point
    retDict = {'NE': NE, 'NW': NW, 'SE': SE, 'SW': SW}  # 'NC' : NC,'SC' : SC,
    # 'WC' : WC, 'EC' : EC}
    # return the dictionary
    return retDict
Esempio n. 11
0
def main():

    #create a list for parallel mapcalc modules and a mapcalc module to act as template 
    mapcalc_list = []
    mapcalc = Module("r.mapcalc", overwrite=True, run_=False)
    
    #get number of tiles in each row and col from arguments 
    tile_rows = int(sys.argv[1])
    tile_cols = int(sys.argv[2])
    
    #Create que for parallel processes
    queue = ParallelModuleQueue(nprocs=sys.argv[3])
    
    #Use temporary region that will be reset after execution of this script
    gscript.use_temp_region()
    
    #Input raster (can be grass raster dataset or externally linked dataset such as tiff vrt etc.)
    input="input_raster"
    
    #Read raster boundaries and resolution into numeric variables
    info = gscript.raster_info(input)
    no = float(info['north'])
    so = float(info['south'])
    we = float(info['west'])
    ea = float(info['east'])
    ro = int(info['rows'])
    co = int(info['cols'])
    ewr = int(info['ewres'])
    nsr = int(info['nsres'])

    #Start mapcalc module for each tile
    k = 0
    for i in xrange(tile_rows):
        for j in xrange(tile_cols):
            #Set processing region to specific part of the raster (column+row)
            gscript.run_command('g.region', 
                    n=so+(i+1)*ro/tile_rows*nsr, 
                    s=so+i*ro/tile_rows*nsr, 
                    e=we+(1+j)*co/tile_cols*ewr, 
                    w=we+j*co/tile_cols*ewr, 
                    rows=ro/tile_rows, 
                    cols=co/tile_cols, 
                    nsres=nsr, 
                    ewres=ewr)
            #Create a copy of mapcalc template, give it mapcalc expression and put it into parallel que where it will be executed when a process becomes available.
            new_mapcalc = copy.deepcopy(mapcalc)
            mapcalc_list.append(new_mapcalc)
            m = new_mapcalc(expression="test_pygrass_%i = %s * (%i+1)"%(k,input, k))
            queue.put(m)
            k+=1
    #wait for all mapcalc modules to have finished execution
    queue.wait()

    #print mapcalc returncodes to check that everything went as expected
    for mapcalc in mapcalc_list:
        print(mapcalc.popen.returncode)

    #delete temporary region to restore the region that was in use at the start of the script
    gscript.del_temp_region()    
Esempio n. 12
0
    def InitRasterOpts(self, rasterList, plottype):
        """!Initialize or update raster dictionary for plotting
        """

        rdict = {} # initialize a dictionary

        self.properties['raster'] = UserSettings.Get(group = self.plottype, key = 'raster')

        for r in rasterList:
            idx = rasterList.index(r)
            
            try:
                ret = grass.raster_info(r)
            except:
                continue
                # if r.info cannot parse map, skip it
               
            self.raster[r] = self.properties['raster'] # some default settings
            rdict[r] = {} # initialize sub-dictionaries for each raster in the list
            
            rdict[r]['units'] = ''
            if ret['units'] not in ('(none)', '"none"', '', None):
                rdict[r]['units'] = ret['units']
            
            rdict[r]['plegend'] = r.split('@')[0]
            rdict[r]['datalist'] = [] # list of cell value,frequency pairs for plotting
            rdict[r]['pline'] = None
            rdict[r]['datatype'] = ret['datatype']

            #    
            #initialize with saved values
            #
            if self.properties['raster']['pwidth'] != None:
                rdict[r]['pwidth'] = self.properties['raster']['pwidth']
            else:
                rdict[r]['pwidth'] = 1
                
            if self.properties['raster']['pstyle'] != None and \
                self.properties['raster']['pstyle'] != '':
                rdict[r]['pstyle'] = self.properties['raster']['pstyle']
            else:
                rdict[r]['pstyle'] = 'solid'
                        
            if idx <= len(self.colorList):
                if idx == 0:
                    # use saved color for first plot
                    if self.properties['raster']['pcolor'] != None:
                        rdict[r]['pcolor'] = self.properties['raster']['pcolor'] 
                    else:
                        rdict[r]['pcolor'] = self.colorDict[self.colorList[idx]]
                else:
                    rdict[r]['pcolor'] = self.colorDict[self.colorList[idx]]
            else:
                r = randint(0, 255)
                b = randint(0, 255)
                g = randint(0, 255)
                rdict[r]['pcolor'] = ((r,g,b,255))
        
        return rdict
Esempio n. 13
0
def main():

    #create a list for parallel mapcalc modules and a mapcalc module to act as template
    mapcalc_list = []
    mapcalc = Module("r.mapcalc", overwrite=True, run_=False)

    #get number of tiles in each row and col from arguments
    tile_rows = int(sys.argv[1])
    tile_cols = int(sys.argv[2])

    #Create que for parallel processes
    queue = ParallelModuleQueue(nprocs=sys.argv[3])

    #Use temporary region that will be reset after execution of this script
    gscript.use_temp_region()

    input = "input_raster"

    #Read raster boundaries and resolution into numeric variables
    info = gscript.raster_info(input)
    no = float(info['north'])
    so = float(info['south'])
    we = float(info['west'])
    ea = float(info['east'])
    ro = int(info['rows'])
    co = int(info['cols'])
    ewr = int(info['ewres'])
    nsr = int(info['nsres'])

    #Start mapcalc module for each tile
    k = 0
    for i in xrange(tile_rows):
        for j in xrange(tile_cols):
            #Set processing region to specific part of the raster (column+row)
            gscript.run_command('g.region',
                                n=so + (i + 1) * ro / tile_rows * nsr,
                                s=so + i * ro / tile_rows * nsr,
                                e=we + (1 + j) * co / tile_cols * ewr,
                                w=we + j * co / tile_cols * ewr,
                                rows=ro / tile_rows,
                                cols=co / tile_cols,
                                nsres=nsr,
                                ewres=ewr)
            #Create a copy of mapcalc template, give it mapcalc expression and put it into parallel que where it will be executed when a process becomes available.
            new_mapcalc = copy.deepcopy(mapcalc)
            mapcalc_list.append(new_mapcalc)
            m = new_mapcalc(expression="test_pygrass_%i = %s * (%i+1)" %
                            (k, input, k))
            queue.put(m)
            k += 1
    #wait for all mapcalc modules to have finished execution
    queue.wait()

    #print mapcalc returncodes to check that everything went as expected
    for mapcalc in mapcalc_list:
        print(mapcalc.popen.returncode)

    #delete temporary region to restore the region that was in use at the start of the script
    gscript.del_temp_region()
def adjust_futures_colors(raster):
    import grass.script as gs
    new_raster = raster + '_'
    info = gs.raster_info(raster)
    color = '0 200:200:200\n1 255:100:50\n{m} 255:255:0\n100 180:255:160'.format(m=info['max'])
    gs.mapcalc('{nr} = if({r} == -1, 100, {r})'.format(nr=new_raster, r=raster))
    gs.write_command('r.colors', map=new_raster, stdin=color, rules='-')
    return new_raster
Esempio n. 15
0
def main():
    input = options['input']
    maskcats = options['maskcats']
    remove = flags['r']
    invert = flags['i']

    if not remove and not input:
	grass.fatal(_("Required parameter <input> not set"))

    #check if input file exists
    if not grass.find_file(input)['file'] and not remove:
        grass.fatal(_("<%s> does not exist.") % input)

    if not 'MASKCATS' in grass.gisenv() and not remove:
        ## beware: next check is made with != , not with 'is', otherwise:
        #>>> grass.raster_info("basin_50K")['datatype'] is "CELL"
        #False
        # even if:
        #>>> "CELL" is "CELL"
        #True 
        if grass.raster_info(input)['datatype'] != "CELL":
            grass.fatal(_("Raster map %s must be integer for maskcats parameter") % input)

    mapset = grass.gisenv()['MAPSET']
    exists = bool(grass.find_file('MASK', element = 'cell', mapset = mapset)['file'])

    if remove:
	if exists:
	    grass.run_command('g.remove', rast = 'MASK')
	    grass.message(_("Raster MASK removed"))
 	else:
	    grass.fatal(_("No existing MASK to remove"))
    else:
	if exists:
            if not grass.overwrite():
                grass.fatal(_("MASK already found in current mapset. Delete first or overwrite."))
            else:
                grass.warning(_("MASK already exists and will be overwritten"))

	p = grass.feed_command('r.reclass', input = input, output = 'MASK', overwrite = True, rules = '-')
	p.stdin.write("%s = 1" % maskcats)
	p.stdin.close()
	p.wait()

	if invert:
	    global tmp
	    tmp = "r_mask_%d" % os.getpid()
	    grass.run_command('g.rename', rast = ('MASK',tmp), quiet = True)
	    grass.mapcalc("MASK=if(isnull($tmp),1,null())", tmp = tmp)
	    grass.run_command('g.remove', rast = tmp, quiet = True)
	    grass.message(_("Inverted MASK created."))
	else:
	    grass.message(_("MASK created."))

        grass.message(_("All subsequent raster operations will be limited to MASK area. ") +
		      "Removing or renaming raster file named MASK will " +
		      "restore raster operations to normal")
def calib_run(scanned_elev, env, **kwargs):
    info = gs.raster_info(scanned_elev)
    interval = (info["max"] - info["min"]) / 20.0
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours",
        step=interval,
        flags="t",
        env=env,
    )
def Data_prep(Land_cover):
    '''
	Function that extracts informations from the Land Cover : resolution and classes
	'''

    info = gscript.raster_info(Land_cover)
    nsres = info.nsres
    ewres = info.ewres
    L = []
    L = [cl for cl in gscript.parse_command('r.category', map=Land_cover)]
    return nsres, ewres, L
Esempio n. 18
0
def main():

    rast1 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n39w114/imgn39w114_1.img'    
    rast2 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n39w115/imgn39w115_1.img'
    rast3 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n40w114/imgn40w114_1.img'
    rast4 = '/home/vitale232/Google\ Drive/UNR/UNR-Thesis/Data/GIS-Data/DEM/n40w115/imgn40w115_1.img'


    a = garray.array()
    a.read(rast1)

    print(grass.raster_info(rast1))
def create_end_points(env):
    info = gs.raster_info("scan")
    y1 = info["south"] + 2 * (info["north"] - info["south"]) / 10.0
    y2 = info["south"] + 8 * (info["north"] - info["south"]) / 10.0
    x1 = info["west"] + 2 * (info["east"] - info["west"]) / 10.0
    x2 = info["west"] + 8 * (info["east"] - info["west"]) / 10.0
    gs.write_command(
        "v.in.ascii",
        input="-",
        stdin="{x1}|{y1}\n{x2}|{y2}".format(x1=x1, x2=x2, y1=y1, y2=y2),
        output="trail_points",
        env=env,
    )
    return ((x1, y1), (x2, y2))
Esempio n. 20
0
    def render_raster(self, name):
        """Reprojects raster to Pseudo-Mercator and saves PNG in working directory.
        Return PNG filename and bounding box of WGS84.

        param str name: name of raster
        """
        # Find full name of raster
        file_info = gs.find_file(name, element="cell", env=self._src_env)
        full_name = file_info["fullname"]
        name = file_info["name"]
        mapset = file_info["mapset"]

        self._region_manager.set_region_from_raster(full_name)
        # Reproject raster into WGS84/epsg3857 location
        env_info = gs.gisenv(env=self._src_env)
        tgt_name = full_name.replace("@", "_")
        gs.run_command(
            "r.proj",
            input=full_name,
            output=tgt_name,
            mapset=mapset,
            location=env_info["LOCATION_NAME"],
            dbase=env_info["GISDBASE"],
            resolution=self._region_manager.resolution,
            env=self._psmerc_env,
        )
        # Write raster to png file with Map
        raster_info = gs.raster_info(tgt_name, env=self._psmerc_env)
        filename = os.path.join(self._tmp_dir.name, f"{tgt_name}.png")
        img = Map(
            width=int(raster_info["cols"]),
            height=int(raster_info["rows"]),
            env=self._psmerc_env,
            filename=filename,
            use_region=True,
        )
        img.run("d.rast", map=tgt_name)
        # Reproject bounds of raster for overlaying png
        # Bounds need to be in WGS84
        old_bounds = get_region(self._src_env)
        from_proj = get_location_proj_string(env=self._src_env)
        to_proj = get_location_proj_string(env=self._wgs84_env)
        bounds = reproject_region(old_bounds, from_proj, to_proj)
        new_bounds = [
            [bounds["north"], bounds["west"]],
            [bounds["south"], bounds["east"]],
        ]

        return filename, new_bounds
Esempio n. 21
0
def run_slope(real_elev, scanned_elev, env, **kwargs):
    gs.run_command("r.slope.aspect",
                   elevation=scanned_elev,
                   slope="slope",
                   env=env)
    info = gs.raster_info(scanned_elev)
    interval = (info["max"] - info["min"]) / 20.0
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours",
        step=interval,
        flags="t",
        env=env,
    )
Esempio n. 22
0
def run_dem(real_elev, scanned_elev, blender_path, eventHandler, env,
            **kwargs):
    gscript.run_command('g.copy', raster=[scanned_elev, 'topo_saved'], env=env)
    info = gscript.raster_info(map=scanned_elev)
    env2 = get_environment(raster=scanned_elev,
                           res=(info['nsres'] + info['ewres']) / 4)
    gscript.run_command('r.resamp.interp',
                        input=scanned_elev,
                        output=scanned_elev + '_hires',
                        method='bilinear',
                        env=env2)
    blender_export_DEM(raster=scanned_elev + '_hires',
                       name='terrain',
                       time_suffix=False,
                       path=blender_path,
                       env=env2)
def Data_prep(categorical_raster):
    '''
    Function that extracts resolution and sorted list of classes of a categorical raster (e.g., a land cover or a land use map).
    '''
    info = gscript.raster_info(categorical_raster)
    nsres = info.nsres
    ewres = info.ewres
    L = []
    L = [
        cl.split("   ")[0]
        for cl in gscript.parse_command('r.category', map=categorical_raster)
    ]
    for i, x in enumerate(L):  #Make sure the format is UTF8 and not Unicode
        L[i] = x.encode('UTF8')
    L.sort(key=float)  #Sort the raster categories in ascending.
    return nsres, ewres, L
Esempio n. 24
0
def rg_nonhier_worker(parms, parameter_queue, result_queue):
    """Launch parallel processes for non-hierarchical segmentation"""

    try:
        for threshold, minsize in iter(parameter_queue.get, "STOP"):
            mapname = rg_non_hierarchical_seg(parms, threshold, minsize)
            mapinfo = gscript.raster_info(mapname)
            if mapinfo["max"] > mapinfo["min"]:
                variance_per_raster = []
                autocor_per_raster = []
                neighbordict = get_nb_matrix(mapname)
                for raster in parms["rasters"]:
                    # there seems to be some trouble in ms windows with qualified
                    # map names
                    raster = raster.split("@")[0]
                    var = get_variance(mapname, raster)
                    variance_per_raster.append(var)
                    autocor = get_autocorrelation(
                        mapname, raster, neighbordict, parms["indicator"]
                    )
                    autocor_per_raster.append(autocor)

                mean_lv = sum(variance_per_raster) / len(variance_per_raster)
                mean_autocor = sum(autocor_per_raster) / len(autocor_per_raster)
                result_queue.put([mapname, mean_lv, mean_autocor, threshold, minsize])
            else:
                # If resulting map contains only one segment, then give high
                # value of variance and 0 for spatial autocorrelation in order
                # to give this map a low priority
                result_queue.put([mapname, 999999, 0, threshold, minsize])

    except:
        exc_info = sys.exc_info()
        result_queue.put(
            [
                "%s: %s_%f_%d failed with message:\n\n %s"
                % (
                    current_process().name,
                    parms["region"],
                    threshold,
                    minsize,
                    exc_info,
                )
            ]
        )

    return True
 def _import_file(self, filename, module, args):
     mapname = self._map_name(filename)
     gs.message(_('Processing <{}>...').format(mapname))
     if module == 'r.import':
         args['resolution_value'] = self._raster_resolution(filename)
     try:
         gs.run_command(module, input=filename, output=mapname, **args)
         if gs.raster_info(mapname)['datatype'] in ('FCELL', 'DCELL'):
             gs.message('Rounding to integer after reprojection')
             gs.use_temp_region()
             gs.run_command('g.region', raster=mapname)
             gs.run_command('r.mapcalc', quiet=True, expression='tmp_%s = round(%s)' % (mapname, mapname))
             gs.run_command('g.rename', quiet=True, overwrite=True, raster='tmp_%s,%s' % (mapname, mapname))
             gs.del_temp_region()
         gs.raster_history(mapname)
     except CalledModuleError as e:
         pass # error already printed
Esempio n. 26
0
def show_interactively(raster, opacity=0.8):
    import grass.script as gs
    info = gs.raster_info(raster)
    raster = raster.split('@')[0]
    gs.mapcalc(
        '{r}_processed = if({r} == 0, null(), int({r}))'.format(r=raster))
    gs.run_command('r.colors', map=raster + '_processed', raster=raster)
    gs.run_command('r.out.gdal',
                   input=raster + '_processed',
                   output=raster + '_spm.tif',
                   type='Byte')
    gs.run_command('g.remove',
                   type='raster',
                   name=raster + '_processed',
                   flags='f')
    subprocess.call([
        'gdalwarp', '-t_srs', 'EPSG:3857', raster + '_spm.tif',
        raster + '_merc.tif', '-overwrite'
    ])
    subprocess.call([
        'gdal_translate', '-of', 'png', raster + '_merc.tif',
        raster + '_merc.png'
    ])
    info = subprocess.check_output(
        ['gdalinfo', '-json', '-noct', '-nomd', raster + '_merc.png'],
        universal_newlines=True)
    coors = json.loads(info)['wgs84Extent']['coordinates'][0]
    lon = [pt[0] for pt in coors]
    lat = [pt[1] for pt in coors]
    minlat = min(lat)
    minlon = min(lon)
    maxlat = max(lat)
    maxlon = max(lon)
    m = folium.Map(location=[(maxlat + minlat) / 2, (maxlon + minlon) / 2])
    img = folium.raster_layers.ImageOverlay(
        name=raster,
        image=raster + '_merc.png',
        bounds=[[minlat, minlon], [maxlat, maxlon]],
        opacity=opacity,
        interactive=True,
        cross_origin=False,
    )
    img.add_to(m)
    folium.LayerControl().add_to(m)
    return m
Esempio n. 27
0
def parse(raster, values):
    info = gs.raster_info(raster)
    if info["datatype"] != "CELL":
        gs.fatal(_("Input raster map must be of type CELL"))
    rules = []
    vals = values.split(",")
    for val in vals:
        if "-" in val:
            a, b = val.split("-")
            if not a:
                a = info["min"]
            if not b:
                b = info["max"]
            for i in range(int(a), int(b) + 1):
                rules.append("{v} = {v}".format(v=i))
        else:
            rules.append("{v} = {v}".format(v=val))
    return rules
Esempio n. 28
0
    def _maskOrBlank(self, name):
        '''Check if name option is given, if yes make a mask,
        if not make a blank map out of the default value.'''
        # if given, then it must be a raster, if not just make blank
        argv = getattr(self, name, None)
        if argv:
            # make mask for DCELL and FCELL
            if not grass.raster_info(argv)['datatype'] == 'CELL':
                outname = '%s__mask'%name
                grass.mapcalc(exp=outname+'=isnull(%s)' % argv)
                self.floatmaps[outname] = self.__dict__[name]
            else:
                # CELL is just passed on
                outname = self.__dict__[name]
        else:
            # not given, make default blank map
            outname = '%s__default'%name
            grass.mapcalc(exp=outname+'=%s'%self.DEFAULTS[name])

        return outname
Esempio n. 29
0
def run_futures(scanned_elev, env, update, giface, **kwargs):
    analyses.match_scan(base='scan_saved', scan=scanned_elev, matched='matched', env=env)
    threshold = 180
    params = list()
    gscript.mapcalc(exp="{change} = if({new} - {old} > {thres}, {new} - {old}, null())".format(
                    change='change', thres=threshold, new='matched', old='scan_saved'), env=env)
    change_info = gscript.raster_info('change')
    if not math.isnan(change_info['min']):
        max_change = change_info['max']
        gscript.mapcalc(exp="{change} = if(change, 1, null())".format(
                        change='change_bin'), env=env)
        gscript.run_command('r.clump', input='change_bin', output='clump', env=env)
        gscript.run_command('r.stats.zonal', base='clump', cover='color_r', output='red_mean', method='average', env=env)
        gscript.run_command('r.stats.zonal', base='clump', cover='color_g', output='green_mean', method='average', env=env)
        gscript.mapcalc('stimulus = if(isnull(red_mean), 0, if(red_mean > green_mean, graph(change, 0,0, {}, 0.9), 0))'.format(max_change), env=env)
        gscript.mapcalc('constrain = if(isnull(green_mean), 1, if(green_mean > red_mean, graph(change, 0,1, {},0.1), 1))'.format(max_change), env=env)
        gscript.mapcalc('stimulus_flat = if(red_mean > green_mean, 1, null())', env=env)
        gscript.mapcalc('constrain_flat = if(green_mean > red_mean, 1, null())', env=env)
#        try:
#            gscript.run_command('g.remove', flags='f',  type='vector', name='constrain,stimulus', env=env)
#        except:
#            pass
        gscript.run_command('r.to.vect', input='stimulus_flat', output='stimulus', type='area', flags='s', env=env)
        gscript.run_command('r.to.vect', input='constrain_flat', output='constrain', type='area', flags='s', env=env)
        gscript.run_command('r.colors', map='stimulus', color='greens', env=env)
        gscript.run_command('r.colors', map='constrain', color='red', flags='n', env=env)
#        params['stimulus'] = 'stimulus'
#        params['constrain'] = 'constrain'
        params.append('constrain=constrain')        
        params.append('stimulus=stimulus')
    else:
        gscript.run_command('v.edit', tool='create', map='stimulus', env=env)
        gscript.run_command('v.edit', tool='create', map='constrain', env=env)
    update()    

#    ff = gscript.find_file(name='appended', element='vector')
#    if ff and ff['fullname'] and gscript.vector_info_topo('appended')['lines'] > 0:
        #roads = 'road_dens_perc_edit'
#        gscript.mapcalc('stimulus2 = stimulus + stimulus_roads', env=env2)
#        params[-1] = 'stimulus=stimulus2'
    futures(params, giface, update)
Esempio n. 30
0
def run_aspect(real_elev, scanned_elev, env, **kwargs):
    gs.run_command("r.slope.aspect",
                   elevation=scanned_elev,
                   aspect="aspect",
                   env=env)
    # reclassify using rules passed as a string to standard input
    # 0:45:2 means reclassify interval 0 to 45 degrees to category 2
    # rules = ['225:315:3', '315:360:2', '0:45:2', '45:135:1', '135:225:4']
    # gs.write_command('r.recode', input='aspect', output='aspect_class',
    #                  rules='-', stdin='\n'.join(rules), env=env)
    # contours
    info = gs.raster_info(scanned_elev)
    interval = (info["max"] - info["min"]) / 20.0
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours",
        step=interval,
        flags="t",
        env=env,
    )
def run_aspect(real_elev, scanned_elev, env, **kwargs):
    info = gs.raster_info(scanned_elev)
    interval = (info["max"] - info["min"]) / 20.0
    # alternatively set fixed interval
    # interval = 10
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours_main",
        step=interval * 5,
        flags="t",
        env=env,
    )
    gs.run_command(
        "r.contour",
        input=scanned_elev,
        output="contours",
        step=interval,
        flags="t",
        env=env,
    )
Esempio n. 32
0
def pops_process_simulation(infected, money_spent, treated_area, baselineValues, pops, baseline):
    env = get_environment(raster=infected)
    res = gscript.raster_info(infected)['nsres']
    # infected cells
    info = gscript.parse_command('r.univar', map=infected, flags='g', env=env)
    counts = gscript.read_command('r.stats', flags='c', input=infected, env=env).strip().splitlines()
    zero, cnts = counts[0].split(' ')
    if zero == '0':
        infected_cells = int(info['n']) - int(cnts)
    else:
        infected_cells = int(info['n'])

    # crops affected - overlay:
    # TODO: overlay with probability > 20% maybe? now it overlays with averaged scenario, which is larger than one run
    gscript.mapcalc("crop_affected = if(! isnull({c}) && {i} > 0, 1, null())".format(c=pops["crop"], i=infected), env=env)
    crop_info = gscript.parse_command('r.univar', map='crop_affected', flags='g', env=env)
    if crop_info:
        crop_affected_area = int(crop_info['n']) * res * res
    else:
        crop_affected_area = 0

    # bar chart
    record = (infected_cells * res * res, money_spent, treated_area, crop_affected_area)

    # radar scaling
    max_money = 5000000.
    if baseline:
        infected_scaled = 10
    else:
        infected_scaled = round(min(10 * record[0] / float(baselineValues[0]), 10))
    money_scaled = round(min(10 * record[1] / max_money, 10))
    treated_scaled = 0  # round(min(10 * record[2] / (max_money / 1.24), 10))
    radar_values = (infected_scaled, money_scaled, treated_scaled, 0)

    # not sure why the condition here
    if baseline:
        gscript.run_command('r.colors', map=infected, env=env, rules=pops['color_trees'])
    return record, radar_values
def compare_points(new, old, real_elev, env):
    res = gscript.read_command('v.distance',
                               flags='p',
                               from_=new,
                               from_type='point',
                               to=old,
                               to_type='point',
                               upload='dist',
                               separator='comma',
                               env=env).strip()
    print(res)
    res = res.splitlines()[1:]
    total = 0
    for line in res:
        cat, dist = line.split(',')
        total += float(dist)

    info = gscript.raster_info(real_elev)
    width = info['east'] - info['west']
    print('compare')
    print(total / width)
    if total / width > 0.1:
        return False
    return True
Esempio n. 34
0
def createConfFile(res,inpumap,home):
    # set the name of conf file
    confilename = home + '/.r.li/history/conf_diversity_' + str(res)  
    # start the text for the conf file
    outputLine = ['SAMPLINGFRAME 0|0|1|1\n']
    # return r.info about input file
    rinfo = grass.raster_info(inpumap)
    # calculate number of lines
    rows = (rinfo["north"]-rinfo["south"])/rinfo['nsres']
    # calculate number of columns
    columns = (rinfo['east']-rinfo['west'])/rinfo['ewres']
    # value for row
    rV = int(res)/rows
    # value for column
    cV = int(res)/columns
    # append the text for the conf file
    outputLine.append('SAMPLEAREA -1|-1|'+str(rV)+'|'+str(cV)+'\n')
    outputLine.append('MOVINGWINDOW\n')
    # open configuration file
    fileConf=open(confilename,'w')
    # write file 
    fileConf.writelines(outputLine)
    # close file
    fileConf.close()
Esempio n. 35
0
def main():
    raster = options["raster"]
    maskcats = options["maskcats"]
    vector = options["vector"]
    layer = options["layer"]
    cats = options["cats"]
    where = options["where"]
    remove = flags["r"]
    invert = flags["i"]

    if not remove and not raster and not vector:
        grass.fatal(_("Either parameter <raster> ot parameter <vector> is required"))

    mapset = grass.gisenv()["MAPSET"]
    exists = bool(grass.find_file("MASK", element="cell", mapset=mapset)["file"])

    if remove:
        # -> remove
        if exists:
            grass.run_command("g.remove", flags="f", quiet=True, type="rast", pattern="MASK")
            grass.message(_("Raster MASK removed"))
        else:
            grass.fatal(_("No existing MASK to remove"))
    else:
        # -> create
        if exists:
            if not grass.overwrite():
                grass.fatal(_("MASK already found in current mapset. Delete first or overwrite."))
            else:
                grass.warning(_("MASK already exists and will be overwritten"))
                grass.run_command("g.remove", flags="f", quiet=True, type="rast", pattern="MASK")

        if raster:
            # check if input raster exists
            if not grass.find_file(raster)["file"]:
                grass.fatal(_("Raster map <%s> not found") % raster)

            if maskcats != "*" and not remove:
                if grass.raster_info(raster)["datatype"] != "CELL":
                    grass.fatal(
                        _(
                            "The raster map <%s> must be integer (CELL type) "
                            " in order to use the 'maskcats' parameter"
                        )
                        % raster
                    )

            p = grass.feed_command("r.reclass", input=raster, output="MASK", overwrite=True, rules="-")
            p.stdin.write("%s = 1" % maskcats)
            p.stdin.close()
            p.wait()
        elif vector:
            vector_name = grass.find_file(vector, "vector")["fullname"]
            if not vector_name:
                grass.fatal(_("Vector map <%s> not found") % vector)

            # parser bug?
            if len(cats) == 0:
                cats = None
            if len(where) == 0:
                where = None

            if grass.vector_info_topo(vector_name)["areas"] < 1:
                grass.warning(_("No area found in vector map <%s>. " "Creating a convex hull for MASK.") % vector_name)
                global tmp_hull
                tmp_hull = "tmp_hull_%d" % os.getpid()
                to_rast_input = tmp_hull
                # force 'flat' convex hull for 3D vector maps
                if 0 != grass.run_command(
                    "v.hull",
                    flags="f",
                    quiet=True,
                    input=vector_name,
                    output=tmp_hull,
                    layer=layer,
                    cats=cats,
                    where=where,
                ):
                    grass.fatal(_("Unable to create a convex hull for vector map <%s>") % vector_name)
            else:
                to_rast_input = vector_name

            env = os.environ.copy()
            if grass.verbosity() > 1:
                env["GRASS_VERBOSE"] = "1"
            grass.run_command(
                "v.to.rast",
                input=to_rast_input,
                layer=layer,
                output="MASK",
                use="val",
                val="1",
                type="area",
                cats=cats,
                where=where,
                env=env,
            )

        if invert:
            global tmp
            tmp = "r_mask_%d" % os.getpid()
            grass.run_command("g.rename", rast=("MASK", tmp), quiet=True)
            grass.message(_("Creating inverted raster MASK..."))
            grass.mapcalc("MASK = if(isnull($tmp), 1, null())", tmp=tmp)
            grass.verbose(_("Inverted raster MASK created"))
        else:
            grass.verbose(_("Raster MASK created"))

        grass.message(
            _(
                "All subsequent raster operations will be limited to "
                "the MASK area. Removing or renaming raster map named "
                "'MASK' will restore raster operations to normal."
            )
        )
Esempio n. 36
0
def get_limit(map):
    return grass.raster_info(map)['max']
Esempio n. 37
0
def main():
    inr = options['input']
    outr = options['output']
    outp = options['points']
    msize = options['msize']
    msize = int(msize)
    
    global nuldev
    nuldev = None

    mmax = (msize-1)/2

    mapcalc_str1 = "%s = if(%s == max(" % (outr, inr)
    mapcalc_list = []

    i = 0
    j = 0
    for x in xrange(i, msize):
        for y in xrange(j, msize):
            mapcalc_list.append("%s[%d,%d]" % (inr, -(mmax)+x, -(mmax)+y))
    mapcalc_str2 = ','.join(mapcalc_list)
    mapcalc_str3 = mapcalc_str1 + mapcalc_str2 + ("),%s,null())" % inr)

    grass.mapcalc(mapcalc_str3)
    
    if outp:
        vect1 = 'R_LOCALMAX_vect1'
        grass.run_command('r.to.vect',
                        input_ = outr, output = vect1,
                        type_ = 'point',
                        quiet = True, stderr = nuldev)
        res = grass.raster_info(inr)['nsres']
        vect2 = 'R_LOCALMAX_vect2'
        grass.run_command('v.buffer',
                        input_ = vect1, output = vect2,
                        dist = res*2,
                        quiet = True, stderr = nuldev)
        vect3 = 'R_LOCALMAX_vect3'
        grass.run_command('v.type',
                          input_ = vect2, output = vect3,
                          from_type_ = 'centroid',
                          to_type = 'point',
                          quiet = True, stderr = nuldev)
        vect4 = 'R_LOCALMAX_vect4'
        grass.run_command('v.category',
                          input_ = vect3, opt = 'del', 
                          output = vect4,
                          quiet = True, stderr = nuldev)
        vect5 = 'R_LOCALMAX_vect5'
        grass.run_command('v.category',
                          input_ = vect4, opt = 'add', 
                          output = vect5,
                          quiet = True, stderr = nuldev)
        grass.run_command('v.db.addtable',
                          map_ = vect5, columns = 'dist double',
                          quiet = True, stderr = nuldev)
        vect6 = 'R_LOCALMAX_vect6'
        grass.run_command('v.distance',
                          from_ = vect5, from_type = 'point',
                          to = vect1, to_type = 'point',
                          output = vect6,  upload = 'dist', column = 'dist',
                          quiet = True, stderr = nuldev)
        grass.run_command('v.select',
                          ainput = vect1, binput = vect6,
                          output = outp,
                          quiet = True, stderr = nuldev)

        return 0
Esempio n. 38
0
 def test_raster_info(self):
     res = gscript.raster_info(self.raster)
     self.assertEquals(str(res['cols']), str(self.region['cols']))
     self.assertEquals(str(res['north']), str(self.region['n']))
Esempio n. 39
0
def main():
    global tmp

    landsat = flags['l']
    quickbird = flags['q']
    spot = flags['s']

    ms1 = options['ms1']
    ms2 = options['ms2']
    ms3 = options['ms3']
    pan = options['pan']
    out = options['output_prefix']

    tmp = str(os.getpid())

    if not landsat and not quickbird and not spot:
	grass.fatal(_("Please select a flag to specify the satellite sensor"))

    #get PAN resolution:
    kv = grass.raster_info(map = pan)
    nsres = kv['nsres']
    ewres = kv['ewres']
    panres = (nsres + ewres) / 2

    # clone current region
    grass.use_temp_region()

    grass.verbose("Using resolution from PAN: %f" % panres)
    grass.run_command('g.region', flags = 'a', res = panres)

    grass.verbose("Performing Brovey transformation...")

    # The formula was originally developed for LANDSAT-TM5 and SPOT, 
    # but it also works well with LANDSAT-TM7
    # LANDSAT formula:
    #  r.mapcalc "brov.red=1. *  tm.5 / (tm.2 + tm.4 + tm.5) * etmpan"
    #  r.mapcalc "brov.green=1. * tm.4 /(tm.2 + tm.4 + tm.5) * etmpan"
    #  r.mapcalc "brov.blue=1. * tm.2 / (tm.2 + tm.4 + tm.5) * etmpan"
    #
    # SPOT formula:
    # r.mapcalc "brov.red= 1.  * spot.ms.3 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
    # r.mapcalc "brov.green=1. * spot.ms.2 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
    # r.mapcalc "brov.blue= 1. * spot.ms.1 / (spot.ms.1 + spot.ms.2 + spot.ms.3) * spot.p"
    # note: for RGB composite then revert brov.red and brov.green!

    grass.message(_("Calculating %s.{red,green,blue}: ...") % out)
    e = '''eval(k = float("$pan") / ("$ms1" + "$ms2" + "$ms3"))
	   "$out.red"   = "$ms3" * k
	   "$out.green" = "$ms2" * k
	   "$out.blue"  = "$ms1" * k'''
    grass.mapcalc(e, out = out, pan = pan, ms1 = ms1, ms2 = ms2, ms3 = ms3)

    # Maybe?
    #r.colors   $GIS_OPT_OUTPUTPREFIX.red col=grey
    #r.colors   $GIS_OPT_OUTPUTPREFIX.green col=grey
    #r.colors   $GIS_OPT_OUTPUTPREFIX.blue col=grey
    #to blue-ish, therefore we modify
    #r.colors $GIS_OPT_OUTPUTPREFIX.blue col=rules << EOF
    #5 0 0 0
    #20 200 200 200
    #40 230 230 230
    #67 255 255 255
    #EOF

    if spot:
        #apect table is nice for SPOT:
	grass.message(_("Assigning color tables for SPOT..."))
	for ch in ['red', 'green', 'blue']:
	    grass.run_command('r.colors', map = "%s.%s" % (out, ch), col = 'aspect')
	grass.message(_("Fixing output names..."))
	for s, d in [('green','tmp'),('red','green'),('tmp','red')]:
	    src = "%s.%s" % (out, s)
	    dst = "%s.%s" % (out, d)
	    grass.run_command('g.rename', rast = (src, dst), quiet = True)
    else:
	#aspect table is nice for LANDSAT and QuickBird:
	grass.message(_("Assigning color tables for LANDSAT or QuickBird..."))
	for ch in ['red', 'green', 'blue']:
	    grass.run_command('r.colors', map = "%s.%s" % (out, ch), col = 'aspect')

    grass.message(_("Following pan-sharpened output maps have been generated:"))
    for ch in ['red', 'green', 'blue']:
	grass.message(_("%s.%s") % (out, ch))

    grass.verbose("To visualize output, run:")
    grass.verbose("g.region -p rast=%s.red" % out)
    grass.verbose("d.rgb r=%s.red g=%s.green b=%s.blue" % (out, out, out))
    grass.verbose("If desired, combine channels with 'r.composite' to a single map.")

    # write cmd history:
    for ch in ['red', 'green', 'blue']:
	grass.raster_history("%s.%s" % (out, ch))
Esempio n. 40
0
def main():
    # Get user inputs
    friction_original = options['friction'] # Input friction map
    out = options['out']                    # Output totalcost raster
    maxcost = options['maxcost']            # Max cost distance in cost units
    knight = "k" if flags["k"] else ""      # Use Knight's move in r.cost instead Queen's move (a bit slower, but more accurate)
    mempercent = int(options['mempercent']) # Percent of map to keep in memory in r.cost calculation

    # Error if no valid friction surface is given
    if not grass.find_file(friction_original)['name']:
        grass.message(_("Friction surface <%s> not found") % friction_original)
        sys.exit()

    # Calculate cost distances / edge effect distances from the friction map. Result is in map units
    info = grass.raster_info(friction_original)             # Read and get raster info
    edgeeffect_min = float(maxcost) / float(info['max'])    # Minimum cost distance / edge effect distance
    edgeeffect_max = float(maxcost) / float(info['min'])    # Maximum cost distance / edge effect distance
    
    # If "Only calculate edge effect" is selected
    if flags['e']:
        grass.message("Minimum distance / edge effect: " + str(edgeeffect_min))
        grass.message("Maximum distance / edge effect: " + str(edgeeffect_max))
        sys.exit()

    # If output file exists, but overwrite option isn't selected
    if not grass.overwrite():
        if grass.find_file(out)['name']:
            grass.message(_("Output raster map <%s> already exists") % out)
            sys.exit()

    # Get raster calculation region information
    regiondata = grass.read_command("g.region", flags = 'p')
    regvalues = grass.parse_key_val(regiondata, sep= ':')
    # Assign variables for necessary region info bits
    nsres = float(regvalues['nsres'])
    ewres = float(regvalues['ewres'])
    # Calculate the mean resolution
    meanres = (nsres + ewres) / 2.0
    
    # Create a list holding cell coordinates
    coordinatelist = []             # An empty list that will be populated with coordinates
    rasterdata = grass.read_command('r.stats', flags="1gn", input = friction_original)  # Read input raster coordinates
    rastervalues = rasterdata.split()   # Split the values from r.stats into list entries
    # rastervalues list is structured like that: [x1, y1, rastervalue1, x2, y2, rastervalue2 ... xn, yn, rastervaluen], so iterate through that list with step of 3 and write a new list that has coordinates in a string: ["x1,y1", "x2,y2" ... "xn,yn"]
    for val in xrange(0,len(rastervalues),3):
        coordinatelist.append(rastervalues[val] + "," + rastervalues[val+1])
        
    # This is the number of cells (and hence cost surfaces) to be used
    n_coords = len(coordinatelist)

    # Create temporary filenames with unique process id in their name. Add each name to the tmp_layers list.
    pid = os.getpid()
    cost1 = str("tmp_totalcost_cost1_%d" % pid)
    tmp_layers.append(cost1)
    cost2 = str("tmp_totalcost_cost2_%d" % pid)
    tmp_layers.append(cost2)
    cost3 = str("tmp_totalcost_cost3_%d" % pid)
    tmp_layers.append(cost3)
    cost4 = str("tmp_totalcost_cost4_%d" % pid)
    tmp_layers.append(cost4)
    friction = str("tmp_friction_%d" % pid)
    tmp_layers.append(friction)
    calctemp = str("tmp_calctemp_%d" % pid)
    tmp_layers.append(calctemp)

    # Assuming the friction values are per map unit (not per cell), the raster should be multiplied with region resolution. This is because r.cost just uses cell values and adds them - slightly different approach compared to ArcGIS which compensates for the resolution automatically. The result is then divided by maxcost so that r.cost max_cost value can be fixed to 1 (it doesn't accept floating point values, hence the workaround).
    grass.mapcalc("$outmap = $inmap * $res / $mcost", outmap = friction, inmap = friction_original, res = meanres, mcost = maxcost)

    # Do the main loop
    for c in xrange(0, n_coords, 4):    # Iterate through the numbers of cells with the step of 4

        # Start four r.cost processes with different coordinates. The first process (costproc1) is always made, but the other 3 have the condition that there exists a successive coordinate in the list. This is because the used step of 4 in the loop. In case there are no coordinates left, assign the redundant cost outputs null-values so they wont be included in the map calc. 
        try:
            costproc1 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost1, start_coordinates = coordinatelist[c], max_cost = 1, percent_memory = mempercent)
            if c+1 < n_coords:
                costproc2 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost2, start_coordinates = coordinatelist[c+1], max_cost = 1, percent_memory = mempercent)
            else:
                cost2 = "null()"
            if c+2 < n_coords:
                costproc3 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost3, start_coordinates = coordinatelist[c+2], max_cost = 1, percent_memory = mempercent)
            else:
                cost3 = "null()"
            if c+3 < n_coords:
                costproc4 = grass.start_command('r.cost', overwrite = True, flags = knight, input = friction, output = cost4, start_coordinates = coordinatelist[c+3], max_cost = 1, percent_memory = mempercent)
            else:
                cost4 = "null()"
        except:
            grass.message("Error with r.cost: " + str(sys.exc_info()[0]))
            sys.exit()

        # For the very first iteration just add those first r.cost results together
        if c == 0:
            # Wait for the r.cost processes to stop before moving on
            costproc1.wait()
            costproc2.wait()
            costproc3.wait()
            costproc4.wait()
            # Do the map algebra: merge the cost surfaces
            try:
                grass.mapcalc("$outmap = if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1) + if(isnull($tempmap3),0,1) + if(isnull($tempmap4),0,1)", outmap = out, tempmap1 = cost1, tempmap2 = cost2, tempmap3 = cost3, tempmap4 = cost4, overwrite=True)
            except:
                grass.message("Error with mapcalc: " + str(sys.exc_info()[0]))
                sys.exit()
        # If it's not the first iteration...
        else:
            # Rename the output of previous mapcalc iteration so that it can be used in the mapcalc expression (x = x + y logic doesn't work apparently)
            try:
                # If pygrass gets fixed, replace g.rename with those commented out pygrass-based lines as they seem to be a bit faster (are they really?)
                #map = pygrass.raster.RasterRow(out)
                #map.name = calctemp
                grass.run_command('g.rename', overwrite = True, rast = out + "," + calctemp)
            except:
                grass.message("Error: " + str(sys.exc_info()[0]))
                sys.exit()
            # Wait for the r.cost processes to stop before moving on
            costproc1.wait()
            costproc2.wait()
            costproc3.wait()
            costproc4.wait()
            # Merge the r.cost results and the cumulative map from previous iteration
            try:
                grass.mapcalc("$outmap = if(isnull($inmap),0,$inmap) + if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1) + if(isnull($tempmap3),0,1) + if(isnull($tempmap4),0,1)", inmap = calctemp, outmap = out, tempmap1 = cost1, tempmap2 = cost2, tempmap3 = cost3, tempmap4 = cost4, overwrite=True)
            except:
                grass.message("Error with mapcalc: " + str(sys.exc_info()[0]))
                sys.exit()
    
    # Finally print the edge effect values
    grass.message("---------------------------------------------")
    grass.message("Minimum distance / edge effect: " + str(edgeeffect_min))
    grass.message("Maximum distance / edge effect: " + str(edgeeffect_max))
Esempio n. 41
0
def main():
    if not hasNumPy:
        grass.fatal(_("Required dependency NumPy not found. Exiting."))

    sharpen = options['method']  # sharpening algorithm
    ms1 = options['blue']  # blue channel
    ms2 = options['green']  # green channel
    ms3 = options['red']  # red channel
    pan = options['pan']  # high res pan channel
    out = options['output']  # prefix for output RGB maps
    bladjust = flags['l']  # adjust blue channel
    sproc = flags['s']  # serial processing

    outb = grass.core.find_file('%s_blue' % out)
    outg = grass.core.find_file('%s_green' % out)
    outr = grass.core.find_file('%s_red' % out)

    if (outb['name'] != '' or outg['name'] != '' or outr['name'] != '') and not grass.overwrite():
        grass.warning(_('Maps with selected output prefix names already exist.'
                        ' Delete them or use overwrite flag'))
        return

    pid = str(os.getpid())

    # get PAN resolution:
    kv = grass.raster_info(map=pan)
    nsres = kv['nsres']
    ewres = kv['ewres']
    panres = (nsres + ewres) / 2

    # clone current region
    grass.use_temp_region()

    grass.run_command('g.region', res=panres, align=pan)

    grass.message(_("Performing pan sharpening with hi res pan image: %f" % panres))

    if sharpen == "brovey":
        grass.verbose(_("Using Brovey algorithm"))

        # pan/intensity histogram matching using linear regression
        outname = 'tmp%s_pan1' % pid
        panmatch1 = matchhist(pan, ms1, outname)

        outname = 'tmp%s_pan2' % pid
        panmatch2 = matchhist(pan, ms2, outname)

        outname = 'tmp%s_pan3' % pid
        panmatch3 = matchhist(pan, ms3, outname)

        outr = '%s_red' % out
        outg = '%s_green' % out
        outb = '%s_blue' % out

        # calculate brovey transformation
        grass.message(_("Calculating Brovey transformation..."))

        if sproc:
            # serial processing
            e = '''eval(k = "$ms1" + "$ms2" + "$ms3")
                "$outr" = 1.0 * "$ms3" * "$panmatch3" / k
                "$outg" = 1.0 * "$ms2" * "$panmatch2" / k
                "$outb" = 1.0 * "$ms1" * "$panmatch1" / k'''
            grass.mapcalc(e, outr=outr, outg=outg, outb=outb,
                          panmatch1=panmatch1, panmatch2=panmatch2,
                          panmatch3=panmatch3, ms1=ms1, ms2=ms2, ms3=ms3,
                          overwrite=True)
        else:
            # parallel processing
            pb = grass.mapcalc_start('%s_blue = (1.0 * %s * %s) / (%s + %s + %s)' %
                                     (out, ms1, panmatch1, ms1, ms2, ms3),
                                     overwrite=True)
            pg = grass.mapcalc_start('%s_green = (1.0 * %s * %s) / (%s + %s + %s)' %
                                     (out, ms2, panmatch2, ms1, ms2, ms3),
                                     overwrite=True)
            pr = grass.mapcalc_start('%s_red = (1.0 * %s * %s) / (%s + %s + %s)' %
                                     (out, ms3, panmatch3, ms1, ms2, ms3),
                                     overwrite=True)

            pb.wait()
            pg.wait()
            pr.wait()

        # Cleanup
        grass.run_command('g.remove', flags='f', quiet=True, type='raster',
                          name='%s,%s,%s' % (panmatch1, panmatch2, panmatch3))

    elif sharpen == "ihs":
        grass.verbose(_("Using IHS<->RGB algorithm"))
        # transform RGB channels into IHS color space
        grass.message(_("Transforming to IHS color space..."))
        grass.run_command('i.rgb.his', overwrite=True,
                          red=ms3,
                          green=ms2,
                          blue=ms1,
                          hue="tmp%s_hue" % pid,
                          intensity="tmp%s_int" % pid,
                          saturation="tmp%s_sat" % pid)

        # pan/intensity histogram matching using linear regression
        target = "tmp%s_int" % pid
        outname = "tmp%s_pan_int" % pid
        panmatch = matchhist(pan, target, outname)

        # substitute pan for intensity channel and transform back to RGB color space
        grass.message(_("Transforming back to RGB color space and sharpening..."))
        grass.run_command('i.his.rgb', overwrite=True,
                          hue="tmp%s_hue" % pid,
                          intensity="%s" % panmatch,
                          saturation="tmp%s_sat" % pid,
                          red="%s_red" % out,
                          green="%s_green" % out,
                          blue="%s_blue" % out)

        # Cleanup
        grass.run_command('g.remove', flags='f', quiet=True, type='raster',
                          name=panmatch)

    elif sharpen == "pca":
        grass.verbose(_("Using PCA/inverse PCA algorithm"))
        grass.message(_("Creating PCA images and calculating eigenvectors..."))

        # initial PCA with RGB channels
        pca_out = grass.read_command('i.pca', quiet=True, rescale='0,0',
                                     input='%s,%s,%s' % (ms1, ms2, ms3),
                                     output='tmp%s.pca' % pid)
        if len(pca_out) < 1:
            grass.fatal(_("Input has no data. Check region settings."))

        b1evect = []
        b2evect = []
        b3evect = []
        for l in pca_out.replace('(', ',').replace(')', ',').splitlines():
            b1evect.append(float(l.split(',')[1]))
            b2evect.append(float(l.split(',')[2]))
            b3evect.append(float(l.split(',')[3]))

        # inverse PCA with hi res pan channel substituted for principal component 1
        pca1 = 'tmp%s.pca.1' % pid
        pca2 = 'tmp%s.pca.2' % pid
        pca3 = 'tmp%s.pca.3' % pid
        b1evect1 = b1evect[0]
        b1evect2 = b1evect[1]
        b1evect3 = b1evect[2]
        b2evect1 = b2evect[0]
        b2evect2 = b2evect[1]
        b2evect3 = b2evect[2]
        b3evect1 = b3evect[0]
        b3evect2 = b3evect[1]
        b3evect3 = b3evect[2]

        outname = 'tmp%s_pan' % pid
        panmatch = matchhist(pan, ms1, outname)

        grass.message(_("Performing inverse PCA ..."))

        stats1 = grass.parse_command("r.univar", map=ms1, flags='g',
                                     parse=(grass.parse_key_val,
                                            {'sep': '='}))
        stats2 = grass.parse_command("r.univar", map=ms2, flags='g',
                                     parse=(grass.parse_key_val,
                                            {'sep': '='}))
        stats3 = grass.parse_command("r.univar", map=ms3, flags='g',
                                     parse=(grass.parse_key_val,
                                            {'sep': '='}))

        b1mean = float(stats1['mean'])
        b2mean = float(stats2['mean'])
        b3mean = float(stats3['mean'])

        if sproc:
            # serial processing
            e = '''eval(k = "$ms1" + "$ms2" + "$ms3")
                "$outr" = 1.0 * "$ms3" * "$panmatch3" / k
                "$outg" = 1.0 * "$ms2" * "$panmatch2" / k
                "$outb" = 1.0* "$ms1" * "$panmatch1" / k'''

            outr = '%s_red' % out
            outg = '%s_green' % out
            outb = '%s_blue' % out

            cmd1 = "$outb = (1.0 * $panmatch * $b1evect1) + ($pca2 * $b2evect1) + ($pca3 * $b3evect1) + $b1mean"
            cmd2 = "$outg = (1.0 * $panmatch * $b1evect2) + ($pca2 * $b2evect1) + ($pca3 * $b3evect2) + $b2mean"
            cmd3 = "$outr = (1.0 * $panmatch * $b1evect3) + ($pca2 * $b2evect3) + ($pca3 * $b3evect3) + $b3mean"

            cmd = '\n'.join([cmd1, cmd2, cmd3])

            grass.mapcalc(cmd, outb=outb, outg=outg, outr=outr,
                          panmatch=panmatch, pca2=pca2, pca3=pca3,
                          b1evect1=b1evect1, b2evect1=b2evect1, b3evect1=b3evect1,
                          b1evect2=b1evect2, b2evect2=b2evect2, b3evect2=b3evect2,
                          b1evect3=b1evect3, b2evect3=b2evect3, b3evect3=b3evect3,
                          b1mean=b1mean, b2mean=b2mean, b3mean=b3mean,
                          overwrite=True)
        else:
            # parallel processing
            pb = grass.mapcalc_start('%s_blue = (%s * %f) + (%s * %f) + (%s * %f) + %f'
                                     % (out, panmatch, b1evect1, pca2,
                                        b2evect1, pca3, b3evect1, b1mean),
                                     overwrite=True)

            pg = grass.mapcalc_start('%s_green = (%s * %f) + (%s * %f) + (%s * %f) + %f'
                                     % (out, panmatch, b1evect2, pca2,
                                        b2evect2, pca3, b3evect2, b2mean),
                                     overwrite=True)

            pr = grass.mapcalc_start('%s_red = (%s * %f) + (%s * %f) + (%s * ''%f) + %f'
                                     % (out, panmatch, b1evect3, pca2,
                                        b2evect3, pca3, b3evect3, b3mean),
                                     overwrite=True)

            pr.wait()
            pg.wait()
            pb.wait()

        # Cleanup
        grass.run_command('g.remove', flags='f', quiet=True, type="raster",
                          pattern='tmp%s*,%s' % (pid, panmatch))

    # Could add other sharpening algorithms here, e.g. wavelet transformation

    grass.message(_("Assigning grey equalized color tables to output images..."))
    # equalized grey scales give best contrast
    for ch in ['red', 'green', 'blue']:
        grass.run_command('r.colors', quiet=True, map="%s_%s" % (out, ch),
                          flags="e", color='grey')

    # Landsat too blue-ish because panchromatic band less sensitive to blue
    # light, so output blue channed can be modified
    if bladjust:
        grass.message(_("Adjusting blue channel color table..."))
        rules = grass.tempfile()
        colors = open(rules, 'w')
        colors.write('5 0 0 0\n20 200 200 200\n40 230 230 230\n67 255 255 255 \n')
        colors.close()

        grass.run_command('r.colors', map="%s_blue" % out, rules=rules)
        os.remove(rules)

    # output notice
    grass.verbose(_("The following pan-sharpened output maps have been generated:"))
    for ch in ['red', 'green', 'blue']:
        grass.verbose(_("%s_%s") % (out, ch))

    grass.verbose(_("To visualize output, run: g.region -p raster=%s_red" % out))
    grass.verbose(_("d.rgb r=%s_red g=%s_green b=%s_blue" % (out, out, out)))
    grass.verbose(_("If desired, combine channels into a single RGB map with 'r.composite'."))
    grass.verbose(_("Channel colors can be rebalanced using i.colors.enhance."))

    # write cmd history:
    for ch in ['red', 'green', 'blue']:
        grass.raster_history("%s_%s" % (out, ch))

    # create a group with the three output
    grass.run_command('i.group', group=out,
                      input="{n}_red,{n}_blue,{n}_green".format(n=out))

    # Cleanup
    grass.run_command('g.remove', flags="f", type="raster",
                      pattern="tmp%s*" % pid, quiet=True)
Esempio n. 42
0
def main():
    global tmpmap
    tmpmap = None

    map = options['map']
    zero = flags['z']
    bands = flags['b']

    if not zero:
        s = gscript.read_command('r.univar', flags='g', map=map)
        kv = gscript.parse_key_val(s)
        global mean, stddev
        mean = float(kv['mean'])
        stddev = float(kv['stddev'])

        if not bands:
            # smooth free floating blue/white/red
            rules = '\n'.join(["0% blue",
                               "%f blue" % z(-2),
                               "%f white" % mean,
                               "%f red" % z(+2),
                               "100% red"])
        else:
            # banded free floating  black/red/yellow/green/yellow/red/black

            # reclass with labels only works for category (integer) based maps
            # r.reclass input="$GIS_OPT_MAP" output="${GIS_OPT_MAP}.stdevs" <<
            # EOF

            # >3 S.D. outliers colored black so they show up in d.histogram w/ white background
            rules = '\n'.join(["0% black",
                               "%f black" % z(-3),
                               "%f red" % z(-3),
                               "%f red" % z(-2),
                               "%f yellow" % z(-2),
                               "%f yellow" % z(-1),
                               "%f green" % z(-1),
                               "%f green" % z(+1),
                               "%f yellow" % z(+1),
                               "%f yellow" % z(+2),
                               "%f red" % z(+2),
                               "%f red" % z(+3),
                               "%f black" % z(+3),
                               "100% black"])
    else:
        tmpmap = "r_col_stdev_abs_%d" % os.getpid()
        gscript.mapcalc("$tmp = abs($map)", tmp=tmpmap, map=map)

        # data centered on 0  (e.g. map of deviations)
        info = gscript.raster_info(tmpmap)
        maxv = info['max']

        # current r.univar truncates percentage to the base integer
        s = gscript.read_command('r.univar', flags='eg', map=map,
                                 percentile=[95.45,
                                             68.2689,
                                             99.7300])
        kv = gscript.parse_key_val(s)

        stddev1 = float(kv['percentile_68_2689'])
        stddev2 = float(kv['percentile_95_45'])
        stddev3 = float(kv['percentile_99_73'])

        if not bands:
            # zero centered smooth blue/white/red
            rules = '\n'.join(["%f blue" % -maxv,
                               "%f blue" % -stddev2,
                               "0 white",
                               "%f red" % stddev2,
                               "%f red" % maxv])
        else:
            # zero centered banded  black/red/yellow/green/yellow/red/black

            # >3 S.D. outliers colored black so they show up in d.histogram w/ white background
            rules = '\n'.join(["%f black" % -maxv,
                               "%f black" % -stddev3,
                               "%f red" % -stddev3,
                               "%f red" % -stddev2,
                               "%f yellow" % -stddev2,
                               "%f yellow" % -stddev1,
                               "%f green" % -stddev1,
                               "%f green" % stddev1,
                               "%f yellow" % stddev1,
                               "%f yellow" % stddev2,
                               "%f red" % stddev2,
                               "%f red" % stddev3,
                               "%f black" % stddev3,
                               "%f black" % maxv, ])

    gscript.write_command('r.colors', map=map, rules='-', stdin=rules)
Esempio n. 43
0
def main():
    raster = options['raster']
    maskcats = options['maskcats']
    vector = options['vector']
    layer = options['layer']
    cats = options['cats']
    where = options['where']
    remove = flags['r']
    invert = flags['i']

    if not remove and not raster and not vector:
        grass.fatal(_("Either parameter <raster> ot parameter <vector> is required"))

    mapset = grass.gisenv()['MAPSET']
    exists = bool(grass.find_file('MASK', element='cell', mapset=mapset)['file'])

    if remove:
        # -> remove
        if exists:
            if sys.platform == 'win32':
                grass.run_command('g.remove', flags='if', quiet=True,
                                  type='raster', name='MASK')
            else:
                grass.run_command('g.remove', flags='f', quiet=True,
                                  type='raster', name='MASK')
            grass.message(_("Raster MASK removed"))
        else:
            grass.fatal(_("No existing MASK to remove"))
    else:
        # -> create
        if exists:
            if not grass.overwrite():
                grass.fatal(_("MASK already found in current mapset. Delete first or overwrite."))
            else:
                grass.warning(_("MASK already exists and will be overwritten"))
                grass.run_command('g.remove', flags='f', quiet=True,
                                  type='raster', name='MASK')

        if raster:
            # check if input raster exists
            if not grass.find_file(raster)['file']:
                grass.fatal(_("Raster map <%s> not found") % raster)

            if maskcats != '*' and not remove:
                if grass.raster_info(raster)['datatype'] != "CELL":
                    grass.fatal(_("The raster map <%s> must be integer (CELL type) "
                                  " in order to use the 'maskcats' parameter") % raster)

            p = grass.feed_command(
                'r.reclass',
                input=raster,
                output='MASK',
                overwrite=True,
                rules='-')
            p.stdin.write("%s = 1" % maskcats)
            p.stdin.close()
            p.wait()
        elif vector:
            vector_name = grass.find_file(vector, 'vector')['fullname']
            if not vector_name:
                grass.fatal(_("Vector map <%s> not found") % vector)

            # parser bug?
            if len(cats) == 0:
                cats = None
            if len(where) == 0:
                where = None

            if grass.vector_info_topo(vector_name)['areas'] < 1:
                grass.warning(_("No area found in vector map <%s>. "
                                "Creating a convex hull for MASK.") % vector_name)
                global tmp_hull
                tmp_hull = "tmp_hull_%d" % os.getpid()
                to_rast_input = tmp_hull
                # force 'flat' convex hull for 3D vector maps
                try:
                    grass.run_command('v.hull', flags='f', quiet=True,
                                      input=vector_name, output=tmp_hull,
                                      layer=layer, cats=cats, where=where)
                except CalledModuleError:
                    grass.fatal(
                        _("Unable to create a convex hull for vector map <%s>") %
                        vector_name)
            else:
                to_rast_input = vector_name

            env = os.environ.copy()
            if grass.verbosity() > 1:
                env['GRASS_VERBOSE'] = '1'
            grass.run_command('v.to.rast', input=to_rast_input, layer=layer,
                              output='MASK', use='val', val='1',
                              type='area', cats=cats, where=where, env=env)

        if invert:
            global tmp
            tmp = "r_mask_%d" % os.getpid()
            grass.run_command('g.rename', raster=('MASK', tmp), quiet=True)
            grass.message(_("Creating inverted raster MASK..."))
            grass.mapcalc("MASK = if(isnull($tmp), 1, null())", tmp=tmp)
            grass.verbose(_("Inverted raster MASK created"))
        else:
            grass.verbose(_("Raster MASK created"))

        grass.message(_("All subsequent raster operations will be limited to "
                        "the MASK area. Removing or renaming raster map named "
                        "'MASK' will restore raster operations to normal."))
Esempio n. 44
0
def reclass(inf, outf, lim, clump, diag, les):
    infile = inf
    outfile = outf
    lesser = les
    limit = lim
    clumped = clump
    diagonal = diag

    s = grass.read_command("g.region", flags='p')
    kv = grass.parse_key_val(s, sep=':')
    s = kv['projection'].strip().split()
    if s == '0':
        grass.fatal(_("xy-locations are not supported"))
        grass.fatal(_("Need projected data with grids in meters"))

    if not grass.find_file(infile)['name']:
        grass.fatal(_("Raster map <%s> not found") % infile)

    if clumped and diagonal:
        grass.fatal(_("flags c and d are mutually exclusive"))

    if clumped:
        clumpfile = infile
    else:
        clumpfile = "%s.clump.%s" % (infile.split('@')[0], outfile)
        TMPRAST.append(clumpfile)

        if not grass.overwrite():
            if grass.find_file(clumpfile)['name']:
                grass.fatal(_("Temporary raster map <%s> exists") % clumpfile)
        if diagonal:
            grass.message(_("Generating a clumped raster file including "
                            "diagonal neighbors..."))
            grass.run_command('r.clump', flags='d', input=infile,
                              output=clumpfile)
        else:
            grass.message(_("Generating a clumped raster file ..."))
            grass.run_command('r.clump', input=infile, output=clumpfile)

    if lesser:
        grass.message(_("Generating a reclass map with area size less than "
                        "or equal to %f hectares...") % limit)
    else:
        grass.message(_("Generating a reclass map with area size greater "
                        "than or equal to %f hectares...") % limit)

    recfile = outfile + '.recl'
    TMPRAST.append(recfile)

    sflags = 'aln'
    if grass.raster_info(infile)['datatype'] in ('FCELL', 'DCELL'):
        sflags += 'i'
    p1 = grass.pipe_command('r.stats', flags=sflags, input=(clumpfile, infile),
                            sep=';')
    p2 = grass.feed_command('r.reclass', input=clumpfile, output=recfile,
                            rules='-')
    rules = ''
    for line in p1.stdout:
        f = line.rstrip(os.linesep).split(';')
        if len(f) < 5:
            continue
        hectares = float(f[4]) * 0.0001
        if lesser:
            test = hectares <= limit
        else:
            test = hectares >= limit
        if test:
            rules += "%s = %s %s\n" % (f[0], f[2], f[3])
    if rules:
        p2.stdin.write(rules)
    p1.wait()
    p2.stdin.close()
    p2.wait()
    if p2.returncode != 0:
        if lesser:
            grass.fatal(_("No areas of size less than or equal to %f "
                          "hectares found.") % limit)
        else:
            grass.fatal(_("No areas of size greater than or equal to %f "
                          "hectares found.") % limit)
    grass.mapcalc("$outfile = $recfile", outfile=outfile, recfile=recfile)
Esempio n. 45
0
oneoutletbasin = 'C:\Mystuff\grassgisdatabase\basin_out23.tif' 
print "r.water.outlet"

print g.run_command('r.water.outlet',overwrite=True,\
                    input = 'dra1v23', output= 'oneoutletbasin',\
                    coordinates=[444470.550695,4397299.50548])



# read map
a = garray.array()
a.read(acc_v23)

print a

print g.raster_info(acc_v23)['datatype']
stop

print g.run_command('r.out.gdal',overwrite=True,\
        input = "oneoutletbasin",type='Float32', \
        output='C:\Mystuff\grassgisdatabase\onebasinProg.tif',nodata=-9999)

print g.read_command('g.list', _type = 'rast')
##stop
print g.run_command('r.out.gdal',overwrite=True,\
 input='acc_v23',type='Float64', \
 output='C:\Mystuff\grassgisdatabase\missioncreek_fac23.tif', format='GTiff')

print 'drainages'
# We create a new array and read map2d_1 to modify it
print g.run_command('r.out.gdal',overwrite=True, type='Float32',\
xy = []                            
for i in range(len(X_coordinateDAM)):
    xy.append(str(X_coordinateDAM[i]) + "," + str(Y_coordinateDAM[i]))

# 1c. Input destination CSV-file
g=open(r"#Specify the path and name.csv",'wb')
writer=csv.writer(g,delimiter=',',quotechar='"',quoting=csv.QUOTE_MINIMAL)

# 2a.GRASS -> open the DEM in GRASS
DEM = grass.run_command("r.in.gdal",input=path_to_DEM,output="DEM",overwrite=True)

# 2b.GRASS -> set region
region = grass.run_command("g.region",flags="d",rast="DEM",overwrite=True)

# 3.Write metadata for csv
nsres = grass.raster_info('DEM')['nsres']
ewres = grass.raster_info('DEM')['ewres']
writer.writerow(["Estimating reservoir:",Reservoir_name])
writer.writerow(["Resolution (Nsres/ewres)",nsres,ewres])
writer.writerow(["Dam Locations (X1,Y1..Xn,Yn):",xy])
writer.writerow(["Waterlevel","Volume","Area"])

# 4.GRASS -> create drainage direction map and drainage accumulation map
drain_dir_acc = grass.run_command("r.watershed",elevation="DEM",drainage="drain_dir",accumulation="drain_acc",overwrite=True)
for i in range(len(X_coordinateDAM)):
    # 5. Get coordinates corresponding to DEM (instead of coordinates of the dam)
    circle = grass.run_command("r.circle",flags="b",coordinate=xy[i],min=0,max=VARIABLE,output="circle",overwrite=True)
    grass.mapcalc("$inter1=abs(if(isnull($circle),null(),drain_acc,drain_acc))",inter1="inter1",circle="circle",drain_acc="drain_acc",overwrite=True)
    univar = grass.read_command('r.info', map='inter1',flags="r")
    maximum = float(univar.split('\n')[1].split('=')[1])
    grass.mapcalc("$inter2=if($inter1>$maximum-0.1,1,null())",inter2="inter2",inter1="inter1",maximum=maximum,overwrite=True)
Esempio n. 47
0
def get_limit(map):
    return gscript.raster_info(map)['max']
Esempio n. 48
0
def main():
    # User inputs
    friction = options['friction']              # Input friction raster
    inpoints = options['points']                # Input point layer
    rastout = options['rastout']                # Output least cost path raster
    radius = int(options['radius'])             # Point search radius
    n_closepoints = int(options['nearpoints'])  # Number of closest points
    vectout = options['vectout']                # Vector layer output
    knight = "k" if flags['k'] else ""          # Knight's move flag
    costatt = "e" if flags['c'] else ""         # Calculate total cost values for paths and add them to attribute table
    
    # Check no vector or raster output is chosen, raise an error
    if (not vectout) and (not rastout):
        grass.message("No output chosen!")
        sys.exit()
        
    # Check overwrite settings
    # If output raster file exists, but overwrite option isn't selected
    if not grass.overwrite():
        if grass.find_file(rastout)['name']:
            grass.message(_("Output raster map <%s> already exists") % rastout)
            sys.exit()
            
    # If output vector file exists, but overwrite option isn't selected
    if not grass.overwrite():
        if grass.find_file(vectout, element = 'vector')['name']:
            grass.message(_("Output vector map <%s> already exists") % vectout)
            sys.exit()
    
    # If overwrite is chosen, remove the previous layers before any action (to lessen the probability of some random errors)
    if grass.overwrite():
        grass.run_command("g.remove", rast = rastout, vect = vectout, quiet = True)
        
    # Get a region resolution to be used in cost attribute calculation, because the default will be in map units
    if vectout and (costatt == "e"): 
        # Get raster calculation region information
        regiondata = grass.read_command("g.region", flags = 'p')
        regvalues = grass.parse_key_val(regiondata, sep= ':')
        # Assign variables for necessary region info bits
        nsres = float(regvalues['nsres'])
        ewres = float(regvalues['ewres'])
        regionres = (nsres + ewres) / 2.0
        rescoefficient = regionres
       
    # Get process id (pid) and create temporary layer names which are also added to tmp_rlayers list
    pid = os.getpid()                           # Process ID, used for getting unique temporary filenames
    costmap1 = "tmp_cost_%d" % pid              # Cost surface for point 1
    tmp_rlayers.append(costmap1)
    costmap2 = "tmp_cost_%d_%i" % (pid, 2)      # Cost surface from point 2 (parallel process)
    tmp_rlayers.append(costmap2)
    costdir1 = "tmp_costdir_%d" % pid           # Temporary cost direction raster 1
    tmp_rlayers.append(costdir1)
    costdir2 = "tmp_costdir_%d_%i" % (pid, 2)   # Temporary cost direction raster 2
    tmp_rlayers.append(costdir2)
    lcpmap1 = "tmp_lcp_%d" % pid                # Least cost path map from costmap1
    tmp_rlayers.append(lcpmap1)
    lcpmap2 = "tmp_lcp_%d_%i" % (pid, 2)        # Least cost path map from costmap2 (parallel process)
    tmp_rlayers.append(lcpmap2)
    lcptemp = "tmp_lcptemp_%d" % pid            # Temporary file for mapcalc
    tmp_rlayers.append(lcptemp)
    region = "tmp_region_%d" % pid              # Temporary vector layer of computational region
    tmp_vlayers.append(region)
    points = "tmp_points_%d" % pid              # Temporary point layer which holds points only inside the region
    tmp_vlayers.append(points)
    if vectout: # if vector output is needed, create the temporary vectorlayers too
        vectdrain1 = "tmp_vectdrain_%d" % pid
        tmp_vlayers.append(vectdrain1)
        vectdrain2 = "tmp_vectdrain2_%d" % pid
        tmp_vlayers.append(vectdrain2)
    
    # Make sure input data points are inside raster computational region: create a region polygon and select points that are inside it
    grass.run_command('v.in.region', overwrite = True, output = region)
    grass.run_command('v.select', overwrite = True, flags = "tc", ainput = inpoints, atype = 'point', binput = region, btype = 'area', output = points , operator = 'within')
    
    # Create a new PointLayerInfo class instance using input point layer and get the categories list as well as total feature count of the layer
    pointlayer = PointLayerInfo(points)
    points_cats = pointlayer.featcats           # A list() of layer feature categories
    points_featcount = pointlayer.featcount     # integer of feature count in point layer
    points_coordsdict = pointlayer.coordsdict   # dict() of point coordinates as tuple (x,y)
    
    # Create an empty dictionaries for storing cost distances between points
    costdict1 = dict()
    costdict2 = dict()
    
    # Create the first mapcalc process, so that it can be checked and stopped in the loop without using more complicated ways
    mapcalc = grass.Popen("")
    lcp1 = grass.Popen("")
    lcp2 = grass.Popen("")
    
    # The main loop for least cost path creation. For each point a cost surface is created, least cost paths created and then added to the general output file. Loop uses a range which has as many items as there are points in the input point layer. To make use of parallel processing, the step is 2, although the "item" is always the first of the selected pair.
    for item in range(0,points_featcount,2):
        
        # Get category number of the point from the point_cats list
        cat1 = points_cats[item]
        
        # Set p2 (i.e. using second or parallel process) to be False by default and make it True if there are enough points left to do so. In that case set it to true and also get the category number of the point from the point_cats list
        p2 = False
        if item+1 < points_featcount:
            p2 = True
            cat2 = points_cats[item+1]
        
        # Create a new PointLayerInfo object from input point layer with centerpoint (from which distances area measured in the class) feature as currently selected point cat
        point1 = PointLayerInfo(points, cat1)
        if p2:  # The same for p2 if needed
            point2 = PointLayerInfo(points, cat2)
        
        # begin cost surface process with the start coordinate of currently selected point. Do the same for second process
        costsurf1 = grass.start_command('r.cost', flags=knight, overwrite=True, input=friction, output=costmap1, outdir=costdir1, start_coordinates=point1.centercoord())
        if p2:
            costsurf2 = grass.start_command('r.cost', flags=knight, overwrite=True, input=friction, output=costmap2, outdir=costdir2, start_coordinates=point2.centercoord())
        
        # Create the drainlist (list of feature coordinates where lcp from current point is made to) depending on whether radius and/or n_closepoints are used. Drainlist point coordinates will be used for r.drain. See PointLayerInfo class below for explanation of the process.
        if radius and n_closepoints:    # If radius and n_closepoints are used
            drainlist1 = point1.near_points_in_radius(n_closepoints, radius)
            if p2:
                drainlist2 = point2.near_points_in_radius(n_closepoints, radius)
        elif radius:                    # If radius is used
            drainlist1 = point1.points_in_radius(radius)
            if p2:
                drainlist2 = point2.points_in_radius(radius)
        elif n_closepoints:             # If n_closepoints is used
            drainlist1 = point1.near_points(n_closepoints)
            if p2:
                drainlist2 = point2.near_points(n_closepoints)
        else:                           # If neither radius or n_closepoints are used
            drainlist1 = point1.cats_without_centerpoint()
            if p2:
                drainlist2 = point2.cats_without_centerpoint()
            
        # Do the least cost path calculation procedures
        drain_coords1 = ""   # An empty string that will be populated with point coordinates which in turn will be used for r.drain start coordinates
        for drainpoint in drainlist1:    # Iterate through all points in drainlist
            drain_x, drain_y = point1.coordsdict[drainpoint]    # variables are assigned coordinate values from the coordinate dictionary
            drain_coords1 = drain_coords1 + str(drain_x) + "," + str(drain_y) + ","     # Add those coordinates to the string that is usable by r.drain
            
        if p2:  # The same thing for second process, see previous section for comments
            drain_coords2 = ""
            for drainpoint in drainlist2:
                drain_x, drain_y = point2.coordsdict[drainpoint]
                drain_coords2 = drain_coords2 + str(drain_x) + "," + str(drain_y) + ","
        
        # Wait for the previous processes to finish their processing
        costsurf1.wait()   
        costsurf2.wait()
        mapcalc.wait()
        
        # If vector output is needed, do the r.drain for each point in the drainlist separately to get the cost values
        if vectout:
            if costatt == "e":
                for drainpoint in drainlist1:   # Each point cat in the drainlist is being iterated
                    drain_x, drain_y = point1.coordsdict[drainpoint]        # Currently selected point's coordinates
                    drain_onecoord = str(str(drain_x) + "," + str(drain_y)) # The coordinate to be used in r.drain on the next line
                    grass.run_command('r.drain', overwrite=True, flags="ad", input=costmap1, indir=costdir1, output = lcpmap1, start_coordinates = drain_onecoord)
                    # Get raster max value (=total cost value for one path) and store it in dictionary with point cat being its key
                    rastinfo = grass.raster_info(lcpmap1)
                    costdict1[drainpoint] = rescoefficient * rastinfo['min']
                    
                if p2:  # Same procedure as in the previous section for parallel process
                    for drainpoint in drainlist2:
                        drain_x, drain_y = point2.coordsdict[drainpoint]
                        drain_onecoord = str(str(drain_x) + "," + str(drain_y))
                        grass.run_command('r.drain', overwrite=True, flags="ad", input=costmap2, indir=costdir2, output = lcpmap2, start_coordinates = drain_onecoord)
                        rastinfo = grass.raster_info(lcpmap2)
                        costdict2[drainpoint] = rescoefficient * rastinfo['min']
            
            # Finally create the vector layer with all paths from the current point. It also (whether we want it or not) creates a raster output
            if len(drainlist1) > 0:
                lcp1 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap1, indir=costdir1, output = lcpmap1, vector_output = vectdrain1,start_coordinates=drain_coords1)
            if p2 and (len(drainlist2) > 0):
                lcp2 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap2, indir=costdir2, output = lcpmap2, vector_output = vectdrain2,start_coordinates=drain_coords2)
        
        # If raster output is needed, but path maps have not been made yet (i.e. vectout must be False) then make those
        if not vectout and (len(drainlist1) > 0):
            lcp1 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap1, indir=costdir1, output = lcpmap1, start_coordinates=drain_coords1)
            if p2 and (len(drainlist2) > 0):
                lcp2 = grass.start_command('r.drain', overwrite=True, flags="d", input=costmap2, indir=costdir2, output = lcpmap2, start_coordinates=drain_coords2)

        # Wait for the lcp processes to finish
        lcp1.wait()
        lcp2.wait()
        
        # If raster output is needed, do the mapcalc stuff: merge the path rasters
        if rastout:
            if len(drainlist1) == 0:
                lcpmap1 = 0
            if len(drainlist2) == 0:
                lcpmap2 = 0
            if cat1 == points_cats[0]:   # If it's the very first iteration
                if p2:  # Technically this should not be False in any situation, but let it be here for additional safety
                    # Add lcpmap1 and lcpmap2 together
                    mapcalc = grass.mapcalc_start("$outmap = if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1)", outmap = rastout, tempmap1 = lcpmap1, tempmap2 = lcpmap2, overwrite=True)
                else:   # Just in case
                    mapcalc = grass.mapcalc_start("$outmap = if(isnull($tempmap1),0,1)", outmap = rastout, tempmap1 = lcpmap1, overwrite=True)
            else:
                # Rename the cumulative lcp map from previous iteration so that mapcalc can use it (x=x+y logic doesn't work with mapcalc)
                grass.run_command('g.rename', rast = rastout + ',' + lcptemp, overwrite=True)
                # rastout = Previous LCP + Current LCP
                if p2:
                    mapcalc = grass.mapcalc_start("$outmap = $inmap + if(isnull($tempmap1),0,1) + if(isnull($tempmap2),0,1)", inmap = lcptemp, outmap = rastout, tempmap1 = lcpmap1, tempmap2 = lcpmap2)
                else:
                    mapcalc = grass.mapcalc_start("$outmap = $inmap + if(isnull($tempmap1),0,1)", inmap = lcptemp, outmap = rastout, tempmap1 = lcpmap1)
        
        # If vector output is needed, do all necessary things like merging the vectors and getting values for attribute table (if specified)
        if vectout:
            if costatt == "e":  # Only if cost attributes are needed
                if len(drainlist1) > 0:
                    # Process 1
                    # Add attribute table to the vector path layer
                    grass.run_command('v.db.addtable', map = vectdrain1)
                    # Get path Euclidean distances and add them to the new column in attribute table. Also add the current point cat to the attribute "from_point"
                    grass.run_command('v.db.addcolumn', map = vectdrain1, columns = "length double precision, from_point int, to_point int, cost double precision")
                    grass.run_command('v.to.db', map = vectdrain1, type = "line", option = "length", columns = "length")
                    grass.run_command('v.db.update', map = vectdrain1, column = "from_point", value = str(cat1))
                
                # Same as previous section but for process 2
                if p2 and (len(drainlist2) > 0):
                    grass.run_command('v.db.addtable', map = vectdrain2)
                    grass.run_command('v.db.addcolumn', map = vectdrain2, columns = "length double precision, from_point int, to_point int, cost double precision")
                    grass.run_command('v.to.db', map = vectdrain2, type = "line", option = "length", columns = "length")
                    grass.run_command('v.db.update', map = vectdrain2, column = "from_point", value = str(cat2))
                
                
                # A loop to update the path attribute values to the attribute table
                if len(drainlist1) > 0:
                    drainseq = 1    # This is just a helper counter because for newly created vector layer the cats start from 1 and just go successively, so no need to introduce any unnecessary catlist
                    for drainpoint in drainlist1:
                        # Update to_point column with values from drainlist
                        grass.run_command('v.db.update', map = vectdrain1, column = "to_point", value = str(drainpoint), where = "cat = " + str(drainseq))
                        # Update the cost column using costdict created earlier
                        grass.run_command('v.db.update', map = vectdrain1, column = "cost", value = costdict1[drainpoint], where = "cat = " + str(drainseq))
                        drainseq += 1
                    
                # The same for process 2
                if p2 and (len(drainlist2) > 0):
                    drainseq = 1    # Reset the counter
                    for drainpoint in drainlist2:
                        grass.run_command('v.db.update', map = vectdrain2, column = "to_point", value = str(drainpoint), where = "cat = " + str(drainseq))
                        grass.run_command('v.db.update', map = vectdrain2, column = "cost", value = costdict2[drainpoint], where = "cat = " + str(drainseq))
                        drainseq += 1
                
            # Patch vector layers
            # For both processes, first make sure that drainlists for current iteration are not empty. If they are not (i.e. the drainlist for current iteration > 0), then drain vectors will be used in v.patch, otherwise empty strings will be used in patching. This is to make sure that vectors from previous iterations are not used.
            if len(drainlist1) > 0:
                vect1 = vectdrain1
            else:
                vect1 = ""
            if len(drainlist2) > 0:
                vect2 = vectdrain2
            else:
                vect2 = ""
            
            # If BOTH drain processes resulted in vectors, create a comma character to be used in v.patch (input parameter must be a string type and layers should be separated by comma)
            if (len(drainlist1) > 0) and (len(drainlist2) > 0):
                comma = ","
            else:
                comma = ""
            
            # Finally do the patching
            if cat1 == points_cats[0]:  # If it's the very first iteration
                if p2:  # If iteration has 2 points
                    grass.run_command('v.patch', overwrite = True, flags=costatt, input = vect1 + comma + vect2, output = vectout)
                else:   # Technically this should never be called (because not having 2 points per iteration can happen only for the very last iteration), but I'll leave it here just in case or for future reference
                    grass.run_command('g.rename', overwrite = True, vect = vect1 + "," + vectout)
            else:
                if grass.find_file(vectout, element='vector')['name']:  # Check whether vectout exists or not (this can happen when the first iteration did not produce any vectors, i.e. search radius was too small). If it does exist, add "a" (append) flag to v.patch, otherwise omit it.
                    append = costatt + "a"
                else:
                    append = costatt
                # Choose between two patching scenarios: 1 or 2 process versions.
                if p2:
                    grass.run_command('v.patch', overwrite = True, flags=append, input = vect1 + comma + vect2, output = vectout)
                else:
                    grass.run_command('v.patch', overwrite = True, flags=append, input = vect1, output = vectout)
    
    
    # Make 0 values of raster into NULLs
    if rastout:
        mapcalc.wait()
        nullproc = grass.run_command('r.null', map = rastout, setnull = "0")

    grass.message("All done!")
Esempio n. 49
0
def main():
    map = options['map']
    nlines = options['lines']
    rast = options['raster']
    omit = flags['n']
    flip = flags['f']
    smooth = flags['s']

    #for -n flag of d.legend
    if not grass.find_file(map)['file']:
        grass.fatal(_("Raster map <%s> not found") % map)

    # for rast=
    if rast and not grass.find_file(rast)['file']:
        grass.fatal(_("Raster map <%s> not found") % rast)

    s = grass.read_command('d.info', flags = 'f')
    if not s:
        sys.exit(1)
    
    f = tuple([float(x) for x in s.split()[1:5]])
    
    grass.run_command('d.erase')
    os.environ['GRASS_PNG_READ'] = 'TRUE'

    #draw title
    
    # set vertical divide at 65 instead of 80 if real labels in cats/ file??
    make_frame(f, 90, 100, 70, 100)
    # use map name without mapset suffix
    mapname = map.split('@')[0]
    grass.run_command('d.text', color='black', size=5, at='5,97', align='cl', text=mapname)

    #draw legend
    
    # set legend vertical position and size based on number of categories
    cats = grass.read_command('r.describe', map=map, flags = '1n')
    ncats = len(cats.strip().split('\n'))
    
    # Only need to adjust legend size if number of categories is between 1 and 10
    if ncats < 2: ncats = 2
    if ncats > 10: ncats = 10
    
    VSpacing = (100 - (ncats * 10) + 10)
    
    if not nlines:
        nlines = None

    if rast:
        lmap = rast
    else:
        lmap = map

    kv = grass.raster_info(map = lmap)
    if kv['datatype'] is 'CELL':
        leg_at = None
    else:
        leg_at = '%f,95,5,10' %VSpacing        

# checking for histogram causes more problems than it solves
#    histfiledir = grass.find_file(lmap, 'cell_misc')['file']
#    has_hist = os.path.isfile(os.path.join(histfiledir, 'histogram'))

    lflags = ''
    if flip:
        lflags += 'f'
    if omit:
        lflags += 'n'
    if smooth:
        lflags += 's'

#    if has_hist or omit:
#        lflags += 'n'

    make_frame(f, 0, 90, 70, 100)
    grass.run_command('d.legend', flags = lflags, rast = lmap, lines = nlines, at = leg_at)

    #draw map
    make_frame(f, 0, 100, 0, 70)
    grass.run_command('d.rast', map = map)
Esempio n. 50
0
def main():
    map = options["map"]
    nlines = options["lines"]
    rast = options["raster"]
    omit = flags["n"]
    flip = flags["f"]
    smooth = flags["s"]

    # for -n flag of d.legend
    if not grass.find_file(map)["file"]:
        grass.fatal(_("Raster map <%s> not found") % map)

    # for rast=
    if rast and not grass.find_file(rast)["file"]:
        grass.fatal(_("Raster map <%s> not found") % rast)

    s = grass.read_command("d.info", flags="f")
    if not s:
        sys.exit(1)

    # fixes trunk r64459
    s = s.split(":")[1]
    f = tuple([float(x) for x in s.split()])

    grass.run_command("d.erase")
    os.environ["GRASS_RENDER_FILE_READ"] = "TRUE"

    # draw title

    # set vertical divide at 65 instead of 80 if real labels in cats/ file??
    make_frame(f, 90, 100, 70, 100)
    # use map name without mapset suffix
    mapname = map.split("@")[0]
    grass.run_command("d.text", color="black", size=5, at="5,97", align="cl", text=mapname)

    # draw legend

    # set legend vertical position and size based on number of categories
    cats = grass.read_command("r.describe", map=map, flags="1n")
    ncats = len(cats.strip().split("\n"))

    # Only need to adjust legend size if number of categories is between 1 and 10
    if ncats < 2:
        ncats = 2
    if ncats > 10:
        ncats = 10

    VSpacing = 100 - (ncats * 10) + 10

    if not nlines:
        nlines = None

    if rast:
        lmap = rast
    else:
        lmap = map

    kv = grass.raster_info(map=lmap)
    if kv["datatype"] is "CELL":
        leg_at = None
    else:
        leg_at = "%f,95,5,10" % VSpacing

    # checking for histogram causes more problems than it solves
    #    histfiledir = grass.find_file(lmap, 'cell_misc')['file']
    #    has_hist = os.path.isfile(os.path.join(histfiledir, 'histogram'))

    lflags = ""
    if flip:
        lflags += "f"
    if omit:
        lflags += "n"
    if smooth:
        lflags += "s"

    #    if has_hist or omit:
    #        lflags += 'n'

    make_frame(f, 0, 90, 70, 100)
    grass.run_command("d.legend", flags=lflags, raster=lmap, lines=nlines, at=leg_at)

    # draw map
    make_frame(f, 0, 100, 0, 70)
    grass.run_command("d.rast", map=map)
def multiscalesmooth(input, smooth, sd, alpha=0.05):

    chisqa = (2.807 - 0.6422 * math.log10(alpha) - 3.410 *
        math.pow(alpha, 0.3411))
    chisqb = (-5.871 - 3.675 * math.log10(alpha) + 4.690 *
        math.pow(alpha, 0.3377))

    gs.message("Preparing initial grids", flag='i')

    # create copy of initial grid of values using current region
    gs.mapcalc('z0 = ${input}', input=input, quiet=True)
    tmp_rast.add('z0')

    # set number of aggregation levels and neighborhood size
    NUM_LEVELS = 4
    NUM_CELLS = 3

    # expand region to accommodate integer number of cells at coarsest
    # level, by adding roungly equal number of cells on either side
    # (with one extra on top/right if an odd number of cells is needed)
    max_size = NUM_CELLS**NUM_LEVELS
    region = gs.region()
    extra = region['cols'] % max_size
    if (0 < extra):
        addx = (max_size-extra)/2.0
    else:
        addx = 0.0
    extra = region['rows'] % max_size
    if (0 < extra):
        addy = (max_size-extra)/2.0
    else:
        addy = 0.0
    gs.run_command('g.region', flags='a',
        w = region['w'] - math.floor(addx) * region['ewres'],
        e = region['e'] + math.ceil(addx) * region['ewres'],
        s = region['s'] - math.floor(addy) * region['nsres'],
        n = region['n'] + math.ceil(addy) * region['nsres'])
    gs.debug('\n'.join(gs.parse_command('g.region', 'up').keys()))

    # create initial grid of variances; sd can be a raster or a constant
    gs.mapcalc('v0 = if(isnull(z0), null(), ${sd}^2)', sd=sd, quiet=True)
    tmp_rast.add('v0')
    # set initial "group variance" to individual msmt variance (noise)
    gs.run_command('g.copy', rast='v0,v.g')
    tmp_rast.add('v.g')
    # weights for aggregation, based on total variance
    gs.mapcalc('w = if(isnull(v0), 0, 1/v0)', quiet=True)
    tmp_rast.add('w')
    # squared weights
    gs.mapcalc('wsq = w^2', quiet=True)
    tmp_rast.add('wsq')
    # effective number of measurements
    gs.mapcalc('n = if(isnull(z0), 0, 1)', quiet=True)
    tmp_rast.add('n')

    # aggregate to broader scales
    for j in range(NUM_LEVELS):
        i = j + 1
        gs.message('Aggregating from %d to %d' % (j, i), flag='i')
        gs.debug(_('Region dimensions: %d x %d' % (gs.region()['rows'],
            gs.region()['cols'])))

        # rename previous (finer scale) weights grid
        gs.run_command('g.rename', rast='w,w.finer', overwrite=True,
            quiet=True)
        tmp_rast.add('w.finer')

        # calc neighborhood weights, num cells, effective num cells
        coarsen_region()
        gs.run_command('r.resamp.stats', method='sum', input='w.finer',
            output='w', quiet=True)
        gs.run_command('r.resamp.stats', method='sum', input='wsq',
            output='wsq', overwrite=True, quiet=True)
        gs.run_command('r.resamp.stats', method='sum', input='n',
            output='n', overwrite=True, quiet=True)

        # calc variance-weighted neighborhood mean
        refine_region()
        gs.mapcalc('tmp = w.finer * z%d / w' % j, quiet=True,
            overwrite=True)
        tmp_rast.add('tmp')
        coarsen_region()
        gs.run_command('r.resamp.stats', method='sum', input='tmp',
            output='z%d' % i, quiet=True)
        tmp_rast.add('z%d' % i)

        # calc between-cell variance, taken over neighborhood
        refine_region()
        gs.mapcalc('tmp = w.finer * (z%d - z%d)^2 / w' % (j, i),
            quiet=True, overwrite=True)
        tmp_rast.add('tmp')
        coarsen_region()
        gs.run_command('r.resamp.stats', method='sum', input='tmp',
            output='v.bg', overwrite=True, quiet=True)
        tmp_rast.add('v.bg')

        # calc wtd avg of within-cell variance, taken over neighborhood
        if (i==1):
            gs.mapcalc('v.wg = 0', quiet=True, overwrite=True)
            tmp_rast.add('v.wg')
        else:
            refine_region()
            gs.mapcalc('tmp = w.finer * v.g / w', quiet=True,
                overwrite=True)
            tmp_rast.add('tmp')
            coarsen_region()
            gs.run_command('r.resamp.stats', method='sum', input='tmp',
                output='v.wg', overwrite=True, quiet=True)

        # calc total group variance
        # ~= total variance of cell vals in the underlying neighborhood
        gs.mapcalc('v.g = v.bg + v.wg', quiet=True, overwrite=True)
        tmp_rast.add('v.g')

        # calc chisq critical values (where df = n.eff - 1)
        gs.mapcalc('chisq = 1 + ${chisqa}/sqrt(${df}) + ${chisqb}/${df}',
            chisqa=chisqa, chisqb=chisqb, df='(w^2/wsq - 1)', quiet=True)
        tmp_rast.add('chisq')
        # set coarsened cell variances: if group variance is small
        # relative to noise variance (mean of finer scale variances),
        # use variance of neighborhood mean instead of group variance
        gs.mapcalc('v%d = if(v.g/chisq < ${mv}, ${vm}, v.g)' % i,
            vm = '(1.0/w)', mv = '(n/w)', quiet=True)
        tmp_rast.add('v%d' % i)

    # get arbitrarily large value to fill null variance cells
    bigvar = gs.raster_info('v0')['max'] * 10

    # prep for refinement phase
    gs.run_command('g.rename', rast='z%d,%s' % (NUM_LEVELS, smooth),
        quiet=True)
    tmp_rast.remove('z%d' % NUM_LEVELS)
    gs.run_command('g.rename', rast='v%d,v.smooth' % NUM_LEVELS,
        quiet=True)
    tmp_rast.add('v.smooth')
    tmp_rast.remove('v%d' % NUM_LEVELS)

    # refine, smooth, and combine each layer in turn
    for j in reversed(range(NUM_LEVELS)):

        i = j + 1
        gs.message('Refining from %d to %d' % (i, j), flag='i')

        # create smoothed higher resolution versions of z and v
        # using weight matrix equivalent to ArcGIS circle with radius 2
        refine_region()
        gs.run_command('r.neighbors', flags='ac', input=smooth,
            output='zs', method='average', size=5, overwrite=True,
            quiet=True)
        tmp_rast.add('zs')
        gs.run_command('r.neighbors', flags='ac', input='v.smooth',
            output='vs', method='average', size=5, overwrite=True,
            quiet=True)
        tmp_rast.add('vs')

        # combine two levels using least variance, using no-null
        # versions of finer z and v
        z_c = 'if(isnull(z%d), 0, z%d)' % (j, j)
        v_c = 'if(isnull(v%d), %f, v%d)' % (j, bigvar, j)
        gs.mapcalc('${smooth} = (${z_c}/${v_c} + zs/vs) / (1/${v_c} + 1/vs)',
            smooth=smooth, z_c=z_c, v_c=v_c, quiet=True, overwrite=True)
        gs.mapcalc('v.smooth = 1 / (1/${v_c} + 1/vs)', v_c = v_c,
            quiet=True, overwrite=True)

    cleanup()
    return None
Esempio n. 52
0
    def __init__(self,**optionsandflags):
        '''Process all arguments and prepare processing'''
        # add all options and flags as attributes (only nonempty ones)
        self.options = {}
        for o in optionsandflags:
            if optionsandflags[o]!='': self.options[o] = optionsandflags[o]
        self.__dict__.update(self.options)

        # dictionary of maps where the value will be averaged over all hydrotopes
        self.floatmaps = {}

        # default columns
        self.strcolumns = [self.subbasins,self.landuse, self.soil]

        # managment and wetland
        for r in ['management','wetland']:
            self.__dict__[r] = self._maskOrBlank(r)
            self.strcolumns += [self.__dict__[r]]


        # check contours and create raster if needed
        if 'contours' in self.options:
            try:
                self.contours = map(int,self.contours.split(','))
                if len(self.contours)==1: self.contours = self.contours[0]
            except:
                grass.fatal(('''Contours should be either an interval [integer]
                or a list of breaks separated by commas.'''))
            # create contourrast
            self.mkContours()
        else:
            self.contourrast = self._maskOrBlank('contourrast')
        # add to columns
        self.strcolumns += [self.contourrast]
        self.floatmaps[self.contourrast] = self.elevation

        # glaciers
        self.glaciers = self._maskOrBlank('glaciers')
        self.strcolumns += [self.glaciers]

        # other raster to include?
        if 'more' in self.options:
            self.more = self.more.split(',')
            self.strcolumns += self.more

        # check if all input maps are int/CELL maps
        gm('Check if all input are integer raster...')
        for m in self.strcolumns:
            if grass.raster_info(m)['datatype']!='CELL':
                grass.fatal('%s is not an integer/CELL raster, convert using int() in r.mapcalc' %m)

        # check that all input maps have no NULLs in catchment over subbasins area
        g_run('r.mask',raster=self.subbasins,overwrite=True)

        gm('Checking for NULLs in input maps...')
        pow2 = 2**np.arange(len(self.strcolumns))
        ifnull = ' + '.join(['isnull(%s)*%s' %(m,i) for m,i in zip(self.strcolumns,pow2)])
        grass.mapcalc('null__areas=%s' %ifnull, overwrite=True)
        g_run('r.null',map='null__areas',setnull=0,quiet=True)
        null = grass.parse_command('r.stats',input='null__areas',flags='aN',separator='=')

        if len(null)>0:
            gm("In any of the input maps are NULL/no data values over the subbasins area.")
            gm(" See the null__area raster with this legend including their combinations.")
            for m,i in zip(self.strcolumns,pow2): gm("%s = %s" %(i,m))
            gm('null__area   area [km2]')
            for m in sorted(null.keys()): gm("%s        %s" %(m,float(null[m])*10**-6))
            gm("How should they appear in the .str file?")
            gm("Set them with r.null")
            grass.fatal('Exiting!')
        g_run('r.mask', flags='r', quiet=True)

        return
Esempio n. 53
0
File: base.py Progetto: caomw/grass
    def InitRasterPairs(self, rasterList, plottype):
        """Initialize or update raster dictionary with raster pairs for
            bivariate scatterplots
        """
        
        if len(rasterList) == 0: return
        
        rdict = {} # initialize a dictionary
        for rpair in rasterList:
            idx = rasterList.index(rpair)
            
            try:
                ret0 = grass.raster_info(rpair[0])
                ret1 = grass.raster_info(rpair[1])

            except:
                continue
                # if r.info cannot parse map, skip it

            self.raster[rpair] = UserSettings.Get(group = plottype, key = 'rasters') # some default settings
            rdict[rpair] = {} # initialize sub-dictionaries for each raster in the list
            rdict[rpair][0] = {}
            rdict[rpair][1] = {}
            rdict[rpair][0]['units'] = ''
            rdict[rpair][1]['units'] = ''

            if ret0['units'] not in ('(none)', '"none"', '', None):
                rdict[rpair][0]['units'] = ret0['units']
            if ret1['units'] not in ('(none)', '"none"', '', None):
                rdict[rpair][1]['units'] = ret1['units']
                
            rdict[rpair]['plegend'] = rpair[0].split('@')[0] + ' vs ' + rpair[1].split('@')[0]
            rdict[rpair]['datalist'] = [] # list of cell value,frequency pairs for plotting histogram
            rdict[rpair][0]['datatype'] = ret0['datatype']
            rdict[rpair][1]['datatype'] = ret1['datatype']
                 
            #    
            #initialize with saved values
            #
            if self.properties['raster']['ptype'] != None and \
                self.properties['raster']['ptype'] != '':
                rdict[rpair]['ptype'] = self.properties['raster']['ptype']
            else:
                rdict[rpair]['ptype'] = 'dot'
            if self.properties['raster']['psize'] != None:
                rdict[rpair]['psize'] = self.properties['raster']['psize']
            else:
                 rdict[rpair]['psize'] = 1
            if self.properties['raster']['pfill'] != None and \
                self.properties['raster']['pfill'] != '':
                rdict[rpair]['pfill'] = self.properties['raster']['pfill']
            else:
                 rdict[rpair]['pfill'] = 'solid'
            
            if idx <= len(self.colorList):
                rdict[rpair]['pcolor'] = self.colorDict[self.colorList[idx]]
            else:
                r = randint(0, 255)
                b = randint(0, 255)
                g = randint(0, 255)
                rdict[rpair]['pcolor'] = ((r,g,b,255))
            
        return rdict
Esempio n. 54
0
def main():

    pan = options['pan']
    msxlst = options['msx'].split(',')
    outputsuffix = options['suffix']
    custom_ratio = options['ratio']
    center = options['center']
    center2 = options['center2']
    modulation = options['modulation']
    modulation2 = options['modulation2']

    if options['trim']:
        trimming_factor = float(options['trim'])
    else:
        trimming_factor = False

    histogram_match = flags['l']
    second_pass = flags['2']
    color_match = flags['c']

    #    # Check & warn user about "ns == ew" resolution of current region ======
    #    region = grass.region()
    #    nsr = region['nsres']
    #    ewr = region['ewres']
    #
    #    if nsr != ewr:
    #        msg = ('>>> Region's North:South ({ns}) and East:West ({ew}) '
    #               'resolutions do not match!')
    #        msg = msg.format(ns=nsr, ew=ewr)
    #        grass.message(msg, flag='w')

    mapset = grass.gisenv()['MAPSET']  # Current Mapset?
    region = grass.region()  # and region settings

    # List images and their properties

    # pygrass.raster.abstract.Info can not cope with
    # Info(name@mapset, mapset)
    # -> fully qualified names and input images from other mapsets are
    # not supported
    # -> use r.info via raster_info

    imglst = [pan]
    imglst.extend(msxlst)  # List of input imagery

    images = {}
    for img in imglst:  # Retrieving Image Info
        # images[img] = Info(img, mapset)
        # images[img].read()
        try:
            images[img] = grass.raster_info(img)
        except:
            grass.fatal(_("msx input not found"))

    panres = images[pan]['nsres']  # Panchromatic resolution

    grass.use_temp_region()  # to safely modify the region
    if flags['a']:
        run('g.region', align=pan)  # Respect extent, change resolution
    else:
        run('g.region', res=panres)  # Respect extent, change resolution
        grass.message(
            "|! Region's resolution matched to Pan's ({p})".format(p=panres))

    # Loop Algorithm over Multi-Spectral images

    for msx in msxlst:
        grass.message("\nProcessing image: {m}".format(m=msx))

        # Tracking command history -- Why don't do this all r.* modules?
        cmd_history = []

        #
        # 1. Compute Ratio
        #

        grass.message("\n|1 Determining ratio of low to high resolution")

        # Custom Ratio? Skip standard computation method.
        if custom_ratio:
            ratio = float(custom_ratio)
            grass.warning('Using custom ratio, overriding standard method!')

        # Multi-Spectral resolution(s), multiple
        else:
            # Image resolutions
            grass.message("   > Retrieving image resolutions")

            msxres = images[msx]['nsres']

            # check
            if panres == msxres:
                msg = ("The Panchromatic's image resolution ({pr}) "
                       "equals to the Multi-Spectral's one ({mr}). "
                       "Something is probably not right! "
                       "Please check your input images.")
                msg = msg.format(pr=panres, mr=msxres)
                grass.fatal(_(msg))

            # compute ratio
            ratio = msxres / panres
            msg_ratio = ('   >> Resolution ratio '
                         'low ({m:.{dec}f}) to high ({p:.{dec}f}): {r:.1f}')
            msg_ratio = msg_ratio.format(m=msxres, p=panres, r=ratio, dec=3)
            grass.message(msg_ratio)

        # 2nd Pass requested, yet Ratio < 5.5
        if second_pass and ratio < 5.5:
            grass.message(
                "   >>> Resolution ratio < 5.5, skipping 2nd pass.\n"
                "   >>> If you insist, force it via the <ratio> option!",
                flag='i')
            second_pass = bool(0)

        #
        # 2. High Pass Filtering
        #

        grass.message('\n|2 High Pass Filtering the Panchromatic Image')

        tmpfile = grass.tempfile()  # Temporary file - replace with os.getpid?
        tmp = 'tmp.' + grass.basename(tmpfile)  # use its basename
        tmp_pan_hpf = '{tmp}_pan_hpf'.format(tmp=tmp)  # HPF image
        tmp_msx_blnr = '{tmp}_msx_blnr'.format(tmp=tmp)  # Upsampled MSx
        tmp_msx_hpf = '{tmp}_msx_hpf'.format(tmp=tmp)  # Fused image
        tmp_msx_mapcalc = tmp_msx_hpf + '_mapcalc'
        tmp_hpf_matrix = grass.tempfile()  # ASCII filter

        # Construct and apply Filter
        hpf = get_high_pass_filter(ratio, center)
        hpf_ascii(center, hpf, tmp_hpf_matrix, second_pass)
        run('r.mfilter',
            input=pan,
            filter=tmp_hpf_matrix,
            output=tmp_pan_hpf,
            title='High Pass Filtered Panchromatic image',
            overwrite=True)

        # 2nd pass
        if second_pass and ratio > 5.5:
            # Temporary files
            # 2nd Pass HPF image
            tmp_pan_hpf_2 = '{tmp}_pan_hpf_2'.format(tmp=tmp)
            # 2nd Pass ASCII filter
            tmp_hpf_matrix_2 = grass.tempfile()
            # Construct and apply 2nd Filter
            hpf_2 = get_high_pass_filter(ratio, center2)
            hpf_ascii(center2, hpf_2, tmp_hpf_matrix_2, second_pass)
            run('r.mfilter',
                input=pan,
                filter=tmp_hpf_matrix_2,
                output=tmp_pan_hpf_2,
                title='2-High-Pass Filtered Panchromatic Image',
                overwrite=True)

        #
        # 3. Upsampling low resolution image
        #

        grass.message("\n|3 Upsampling (bilinearly) low resolution image")

        run('r.resamp.interp',
            method='bilinear',
            input=msx,
            output=tmp_msx_blnr,
            overwrite=True)

        #
        # 4. Weighting the High Pass Filtered image(s)
        #

        grass.message("\n|4 Weighting the High-Pass-Filtered image (HPFi)")

        # Compute (1st Pass) Weighting
        msg_w = "   > Weighting = StdDev(MSx) / StdDev(HPFi) * " \
            "Modulating Factor"
        grass.message(msg_w)

        # StdDev of Multi-Spectral Image(s)
        msx_avg = avg(msx)
        msx_sd = stddev(msx)
        grass.message("   >> StdDev of <{m}>: {sd:.3f}".format(m=msx,
                                                               sd=msx_sd))

        # StdDev of HPF Image
        hpf_sd = stddev(tmp_pan_hpf)
        grass.message("   >> StdDev of HPFi: {sd:.3f}".format(sd=hpf_sd))

        # Modulating factor
        modulator = get_modulator_factor(modulation, ratio)
        grass.message("   >> Modulating Factor: {m:.2f}".format(m=modulator))

        # weighting HPFi
        weighting = hpf_weight(msx_sd, hpf_sd, modulator, 1)

        #
        # 5. Adding weighted HPF image to upsampled Multi-Spectral band
        #

        grass.message("\n|5 Adding weighted HPFi to upsampled image")
        fusion = '{hpf} = {msx} + {pan} * {wgt}'
        fusion = fusion.format(hpf=tmp_msx_hpf,
                               msx=tmp_msx_blnr,
                               pan=tmp_pan_hpf,
                               wgt=weighting)
        grass.mapcalc(fusion)

        # command history
        hst = 'Weigthing applied: {msd:.3f} / {hsd:.3f} * {mod:.3f}'
        cmd_history.append(hst.format(msd=msx_sd, hsd=hpf_sd, mod=modulator))

        if second_pass and ratio > 5.5:

            #
            # 4+ 2nd Pass Weighting the High Pass Filtered image
            #

            grass.message("\n|4+ 2nd Pass Weighting the HPFi")

            # StdDev of HPF Image #2
            hpf_2_sd = stddev(tmp_pan_hpf_2)
            grass.message(
                "   >> StdDev of 2nd HPFi: {h:.3f}".format(h=hpf_2_sd))

            # Modulating factor #2
            modulator_2 = get_modulator_factor2(modulation2)
            msg = '   >> 2nd Pass Modulating Factor: {m:.2f}'
            grass.message(msg.format(m=modulator_2))

            # 2nd Pass weighting
            weighting_2 = hpf_weight(msx_sd, hpf_2_sd, modulator_2, 2)

            #
            # 5+ Adding weighted HPF image to upsampled Multi-Spectral band
            #

            grass.message("\n|5+ Adding small-kernel-based weighted "
                          "2nd HPFi back to fused image")

            add_back = '{final} = {msx_hpf} + {pan_hpf} * {wgt}'
            # r.mapcalc: do not use input as output
            add_back = add_back.format(final=tmp_msx_mapcalc,
                                       msx_hpf=tmp_msx_hpf,
                                       pan_hpf=tmp_pan_hpf_2,
                                       wgt=weighting_2)
            grass.mapcalc(add_back)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

            # 2nd Pass history entry
            hst = "2nd Pass Weighting: {m:.3f} / {h:.3f} * {mod:.3f}"
            cmd_history.append(
                hst.format(m=msx_sd, h=hpf_2_sd, mod=modulator_2))

        #
        # 6. Stretching linearly the HPF-Sharpened image(s) to match the Mean
        #     and Standard Deviation of the input Multi-Sectral image(s)
        #

        if histogram_match:

            # adapt output StdDev and Mean to the input(ted) ones
            # technically, this is not histogram matching but
            # normalizing to the input's mean + stddev
            grass.message("\n|+ Matching histogram of Pansharpened image "
                          "to %s" % (msx))

            # Collect stats for linear histogram matching
            msx_hpf_avg = avg(tmp_msx_hpf)
            msx_hpf_sd = stddev(tmp_msx_hpf)

            msx_info = images[msx]
            outfn = 'round'
            if msx_info['datatype'] == 'FCELL':
                outfn = 'float'
            elif msx_info['datatype'] == 'DCELL':
                outfn = 'double'

            # expression for mapcalc
            lhm = "{out} = {outfn}(double({hpf} - {hpfavg}) / {hpfsd} * " \
                          "{msxsd} + {msxavg})"
            # r.mapcalc: do not use input as output
            lhm = lhm.format(out=tmp_msx_mapcalc,
                             outfn=outfn,
                             hpf=tmp_msx_hpf,
                             hpfavg=msx_hpf_avg,
                             hpfsd=msx_hpf_sd,
                             msxsd=msx_sd,
                             msxavg=msx_avg)

            # compute
            grass.mapcalc(lhm, quiet=True, overwrite=True)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

            # snap outliers to input range
            snapout = "{out} = {outfn}(if({hpf} < {oldmin}, {oldmin}, " \
                              "if({hpf} > {oldmax}, {oldmax}, {hpf})))"
            snapout = snapout.format(out=tmp_msx_mapcalc,
                                     outfn=outfn,
                                     hpf=tmp_msx_hpf,
                                     oldmin=msx_info['min'],
                                     oldmax=msx_info['max'])

            grass.mapcalc(snapout, quiet=True, overwrite=True)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

            # update history string
            cmd_history.append("Linear Histogram Matching: %s" % lhm)
        else:
            # scale result to input using quantiles
            grass.message("\n|+ Quantile scaling of Pansharpened image "
                          "to %s" % (msx))

            msx_info = images[msx]
            outfn = 'round'
            if msx_info['datatype'] == 'FCELL':
                outfn = 'float'
            elif msx_info['datatype'] == 'DCELL':
                outfn = 'double'

            # quantile scaling
            percentiles = "10,50,90"
            allq = grass.read_command('r.quantile',
                                      input=msx,
                                      percentiles=percentiles,
                                      quiet=True)
            allq = allq.splitlines()
            msx_plo = float(allq[0].split(':')[2])
            msx_med = float(allq[1].split(':')[2])
            msx_phi = float(allq[2].split(':')[2])

            allq = grass.read_command('r.quantile',
                                      input=tmp_msx_hpf,
                                      percentiles=percentiles,
                                      quiet=True)
            allq = allq.splitlines()
            hpf_plo = float(allq[0].split(':')[2])
            hpf_med = float(allq[1].split(':')[2])
            hpf_phi = float(allq[2].split(':')[2])

            # scale factors
            sfplo = (msx_med - msx_plo) / (hpf_med - hpf_plo)
            sfphi = (msx_phi - msx_med) / (hpf_phi - hpf_med)

            scale = "{out} = {outfn}(double({hpf} - {hpf_med}) * " \
                            "if({hpf} < {hpf_med}, {sfplo}, " \
                            "{sfphi}) + {msx_med})"
            scale = scale.format(out=tmp_msx_mapcalc,
                                 outfn=outfn,
                                 hpf=tmp_msx_hpf,
                                 hpf_med=hpf_med,
                                 sfplo=sfplo,
                                 sfphi=sfphi,
                                 msx_med=msx_med)
            grass.mapcalc(scale, quiet=True)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

            # snap outliers to input range
            snapout = "{out} = {outfn}(if({hpf} < {oldmin}, {oldmin}, " \
                              "if({hpf} > {oldmax}, {oldmax}, {hpf})))"
            snapout = snapout.format(out=tmp_msx_mapcalc,
                                     outfn=outfn,
                                     hpf=tmp_msx_hpf,
                                     oldmin=msx_info['min'],
                                     oldmax=msx_info['max'])

            grass.mapcalc(snapout, quiet=True, overwrite=True)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

            # update history string
            cmd_history.append("Linear Scaling: %s" % scale)

        if color_match:
            grass.message("\n|* Matching output to input color table")
            run('r.colors', map=tmp_msx_hpf, raster=msx)

        #
        # Optional. Trim to remove black border effect (rectangular only)
        #

        if trimming_factor:

            tf = trimming_factor

            # communicate
            msg = '\n|* Trimming output image border pixels by '
            msg += '{factor} times the low resolution\n'.format(factor=tf)
            nsew = '   > Input extent: n: {n}, s: {s}, e: {e}, w: {w}'
            nsew = nsew.format(n=region['n'],
                               s=region['s'],
                               e=region['e'],
                               w=region['w'])
            msg += nsew

            grass.message(msg)

            # re-set borders
            region.n -= tf * images[msx]['nsres']
            region.s += tf * images[msx]['nsres']
            region.e -= tf * images[msx]['ewres']
            region.w += tf * images[msx]['ewres']

            # communicate and act
            msg = '   > Output extent: n: {n}, s: {s}, e: {e}, w: {w}'
            msg = msg.format(n=region['n'],
                             s=region['s'],
                             e=region['e'],
                             w=region['w'])
            grass.message(msg)

            # modify only the extent
            run('g.region',
                n=region['n'],
                s=region['s'],
                e=region['e'],
                w=region['w'])
            # r.mapcalc: do not use input as output
            trim = "{out} = {input}".format(out=tmp_msx_mapcalc,
                                            input=tmp_msx_hpf)
            grass.mapcalc(trim)
            run('g.remove', flags="f", type="raster", name=tmp_msx_hpf)
            run("g.rename", raster=(tmp_msx_mapcalc, tmp_msx_hpf))

        #
        # End of Algorithm

        # history entry
        run("r.support", map=tmp_msx_hpf, history="\n".join(cmd_history))

        # add suffix to basename & rename end product
        msx_name = "{base}{suffix}"
        msx_name = msx_name.format(base=msx.split('@')[0], suffix=outputsuffix)
        run("g.rename", raster=(tmp_msx_hpf, msx_name))

        # remove temporary files
        cleanup()

    # visualising-related information
    grass.del_temp_region()  # restoring previous region settings
    grass.message("\n|! Original Region restored")
    grass.message(
        "\n>>> Hint, rebalancing colors (via i.colors.enhance) "
        "may improve appearance of RGB composites!",
        flag='i')
Esempio n. 55
0
def main():
    global TMPLOC, SRCGISRC, GISDBASE, TMP_REG_NAME

    GDALdatasource = options['input']
    output = options['output']
    method = options['resample']
    memory = options['memory']
    bands = options['band']
    tgtres = options['resolution']
    title = options["title"]
    if options['resolution_value']:
        if tgtres != 'value':
            grass.fatal(_("To set custom resolution value, select 'value' in resolution option"))
        tgtres_value = float(options['resolution_value'])
        if tgtres_value <= 0:
            grass.fatal(_("Resolution value can't be smaller than 0"))
    elif tgtres == 'value':
         grass.fatal(_("Please provide the resolution for the imported dataset or change to 'estimated' resolution"))

    grassenv = grass.gisenv()
    tgtloc = grassenv['LOCATION_NAME']
    tgtmapset = grassenv['MAPSET']
    GISDBASE = grassenv['GISDBASE']
    tgtgisrc = os.environ['GISRC']
    SRCGISRC = grass.tempfile()

    TMPLOC = 'temp_import_location_' + str(os.getpid())

    f = open(SRCGISRC, 'w')
    f.write('MAPSET: PERMANENT\n')
    f.write('GISDBASE: %s\n' % GISDBASE)
    f.write('LOCATION_NAME: %s\n' % TMPLOC)
    f.write('GUI: text\n')
    f.close()

    tgtsrs = grass.read_command('g.proj', flags='j', quiet=True)

    # create temp location from input without import
    grass.verbose(_("Creating temporary location for <%s>...") % GDALdatasource)
    parameters = dict(input=GDALdatasource, output=output,
                      memory=memory, flags='c', title=title,
                      location=TMPLOC, quiet=True)
    if bands:
        parameters['band'] = bands
    try:
        grass.run_command('r.in.gdal', **parameters)
    except CalledModuleError:
        grass.fatal(_("Unable to read GDAL dataset <%s>") % GDALdatasource)

    # switch to temp location
    os.environ['GISRC'] = str(SRCGISRC)

    # switch to target location
    os.environ['GISRC'] = str(tgtgisrc)

    # try r.in.gdal directly first
    additional_flags = 'l' if flags['l'] else ''
    if flags['o']:
        additional_flags += 'o'
    if flags['o'] or grass.run_command('r.in.gdal', input=GDALdatasource, flags='j',
                                       errors='status', quiet=True) == 0:
        parameters = dict(input=GDALdatasource, output=output,
                          memory=memory, flags='k' + additional_flags)
        if bands:
            parameters['band'] = bands
        try:
            grass.run_command('r.in.gdal', **parameters)
            grass.verbose(_("Input <%s> successfully imported without reprojection") % GDALdatasource)
            return 0
        except CalledModuleError as e:
            grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource)
    
    # make sure target is not xy
    if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
        grass.fatal(_("Coordinate reference system not available for current location <%s>") % tgtloc)

    # switch to temp location
    os.environ['GISRC'] = str(SRCGISRC)

    # make sure input is not xy
    if grass.parse_command('g.proj', flags='g')['name'] == 'xy_location_unprojected':
        grass.fatal(_("Coordinate reference system not available for input <%s>") % GDALdatasource)

    # import into temp location
    grass.verbose(_("Importing <%s> to temporary location...") % GDALdatasource)
    parameters = dict(input=GDALdatasource, output=output,
                      memory=memory, flags='k' + additional_flags)
    if bands:
        parameters['band'] = bands
    try:
        grass.run_command('r.in.gdal', **parameters)
    except CalledModuleError:
        grass.fatal(_("Unable to import GDAL dataset <%s>") % GDALdatasource)

    outfiles = grass.list_grouped('raster')['PERMANENT']

    # is output a group?
    group = False
    path = os.path.join(GISDBASE, TMPLOC, 'group', output)
    if os.path.exists(path):
        group = True
        path = os.path.join(GISDBASE, TMPLOC, 'group', output, 'POINTS')
        if os.path.exists(path):
            grass.fatal(_("Input contains GCPs, rectification is required"))

    # switch to target location
    os.environ['GISRC'] = str(tgtgisrc)

    region = grass.region()

    rflags = None
    if flags['n']:
        rflags = 'n'

    for outfile in outfiles:

        n = region['n']
        s = region['s']
        e = region['e']
        w = region['w']

        grass.use_temp_region()

        if options['extent'] == 'input':
            # r.proj -g
            try:
                tgtextents = grass.read_command('r.proj', location=TMPLOC,
                                                mapset='PERMANENT',
                                                input=outfile, flags='g',
                                                memory=memory, quiet=True)
            except CalledModuleError:
                grass.fatal(_("Unable to get reprojected map extent"))
            try:
                srcregion = grass.parse_key_val(tgtextents, val_type=float, vsep=' ')
                n = srcregion['n']
                s = srcregion['s']
                e = srcregion['e']
                w = srcregion['w']
            except ValueError:  # import into latlong, expect 53:39:06.894826N
                srcregion = grass.parse_key_val(tgtextents, vsep=' ')
                n = grass.float_or_dms(srcregion['n'][:-1]) * \
                    (-1 if srcregion['n'][-1] == 'S' else 1)
                s = grass.float_or_dms(srcregion['s'][:-1]) * \
                    (-1 if srcregion['s'][-1] == 'S' else 1)
                e = grass.float_or_dms(srcregion['e'][:-1]) * \
                    (-1 if srcregion['e'][-1] == 'W' else 1)
                w = grass.float_or_dms(srcregion['w'][:-1]) * \
                    (-1 if srcregion['w'][-1] == 'W' else 1)

            grass.run_command('g.region', n=n, s=s, e=e, w=w)

        # v.in.region in tgt
        vreg = TMP_REG_NAME = 'vreg_tmp_' + str(os.getpid())
        grass.run_command('v.in.region', output=vreg, quiet=True)

        grass.del_temp_region()

        # reproject to src
        # switch to temp location
        os.environ['GISRC'] = str(SRCGISRC)
        try:
            grass.run_command('v.proj', input=vreg, output=vreg,
                              location=tgtloc, mapset=tgtmapset, quiet=True)
        except CalledModuleError:
            grass.fatal(_("Unable to reproject to source location"))

        # set region from region vector
        grass.run_command('g.region', raster=outfile)
        grass.run_command('g.region', vector=vreg)
        # align to first band
        grass.run_command('g.region', align=outfile)
        # get number of cells
        cells = grass.region()['cells']

        estres = math.sqrt((n - s) * (e - w) / cells)
        # remove from source location for multi bands import
        grass.run_command('g.remove', type='vector', name=vreg,
                          flags='f', quiet=True)

        os.environ['GISRC'] = str(tgtgisrc)
        grass.run_command('g.remove', type='vector', name=vreg,
                          flags='f', quiet=True)

        grass.message(_("Estimated target resolution for input band <{out}>: {res}").format(out=outfile, res=estres))
        if flags['e']:
            continue

        if options['extent'] == 'input':
            grass.use_temp_region()
            grass.run_command('g.region', n=n, s=s, e=e, w=w)

        res = None
        if tgtres == 'estimated':
            res = estres
        elif tgtres == 'value':
            res = tgtres_value
            grass.message(_("Using given resolution for input band <{out}>: {res}").format(out=outfile, res=res))
            # align to requested resolution
            grass.run_command('g.region', res=res, flags='a')
        else:
            curr_reg = grass.region()
            grass.message(_("Using current region resolution for input band "
                            "<{out}>: nsres={ns}, ewres={ew}").format(out=outfile, ns=curr_reg['nsres'],
                                                                      ew=curr_reg['ewres']))

        # r.proj
        grass.message(_("Reprojecting <%s>...") % outfile)
        try:
            grass.run_command('r.proj', location=TMPLOC,
                              mapset='PERMANENT', input=outfile,
                              method=method, resolution=res,
                              memory=memory, flags=rflags, quiet=True)
        except CalledModuleError:
            grass.fatal(_("Unable to to reproject raster <%s>") % outfile)

        if grass.raster_info(outfile)['min'] is None:
            grass.fatal(_("The reprojected raster <%s> is empty") % outfile)

        if options['extent'] == 'input':
            grass.del_temp_region()

    if flags['e']:
        return 0

    if group:
        grass.run_command('i.group', group=output, input=','.join(outfiles))

    # TODO: write metadata with r.support

    return 0
def run_analyses(settings, analysesFile, update, giface, eventHandler, scanFilter, **kwargs):
    """Runs all functions in specified Python file which start with 'run_'.
    The Python file is reloaded every time"""

    scan_params = settings['tangible']['scan']
    scan_name = settings['tangible']['output']['scan']
    if scanFilter['filter']:
        try:
            info = gscript.raster_info(scan_name + 'tmp')
        except CalledModuleError:
            print 'error in r.info'
            return
        if scanFilter['debug']:
            try:
                print info['max'] - info['min']
            except TypeError:  # unsupported operand type(s) for -: 'NoneType' and 'NoneType'
                return
        threshold = scanFilter['threshold']
        if info['max'] - info['min'] > threshold:
            scanFilter['counter'] += 1
            return
    try:
        gscript.run_command('g.copy', raster=[scan_name + 'tmp', scan_name], overwrite=True, quiet=True)
    except CalledModuleError:
        print 'error copying scanned data from temporary name'
        return
    # workaround weird georeferencing
    # filters cases when extent and elev values are in inconsistent state
    # probably it reads it before the header is written
    try:
        info = gscript.raster_info(scan_name)
    except CalledModuleError:
        print 'error in r.info'
        return
    try:
        if (abs(info['north'] - info['south']) / (info['max'] - info['min'])) < 1:
            return
    except ZeroDivisionError:
        return
    env = get_environment(rast=scan_name)
    if not analysesFile or not os.path.exists(analysesFile):
        return
    # run analyses
    try:
        myanalyses = imp.load_source('myanalyses', analysesFile)
    except StandardError as e:
        print e
        return

    functions = [func for func in dir(myanalyses) \
        if (func.startswith('run_') and func != 'run_command') or func.startswith('drawing_')]
    for func in functions:
        exec('del myanalyses.' + func)
    try:
        myanalyses = imp.load_source('myanalyses', analysesFile)
    except StandardError as e:
        print e
        return
    # color output
    color = None
    if settings['tangible']['output']['color']:
        color = settings['tangible']['output']['color_name']
    # blender path
    blender_path = None
    if settings['tangible']['output']['blender']:
        blender_path = settings['tangible']['output']['blender_path']
    # drawing needs different parameters
    # functions postprocessing drawing results start with 'drawing'
    # functions postprocessing scanning results start with 'run'

    if settings['tangible']['drawing']['active']:
        functions = [func for func in dir(myanalyses) if func.startswith('drawing_')]
        for func in functions:
            try:
                exec('myanalyses.' + func + "(real_elev=scan_params['elevation'],"
                                            " scanned_elev=scan_name,"
                                            " blender_path=blender_path,"
                                            " zexag=scan_params['zexag'],"
                                            " draw_vector=settings['tangible']['drawing']['name'],"
                                            " draw_vector_append=settings['tangible']['drawing']['append'],"
                                            " draw_vector_append_name=settings['tangible']['drawing']['appendName'],"
                                            " giface=giface, update=update,"
                                            " eventHandler=eventHandler, env=env, **kwargs)")
            except (CalledModuleError, StandardError, ScriptError) as e:
                print traceback.print_exc()
    else:
        functions = [func for func in dir(myanalyses) if func.startswith('run_') and func != 'run_command']
        for func in functions:
            try:
                exec('myanalyses.' + func + "(real_elev=scan_params['elevation'],"
                                            " scanned_elev=scan_name,"
                                            " scanned_color=color,"
                                            " blender_path=blender_path,"
                                            " zexag=scan_params['zexag'],"
                                            " giface=giface, update=update,"
                                            " eventHandler=eventHandler, env=env, **kwargs)")
            except (CalledModuleError, StandardError, ScriptError) as e:
                print traceback.print_exc()
Esempio n. 57
0
def main():
    
    # temporary region
    gscript.use_temp_region()
    
    # set graphics driver
    driver = "cairo"
    
    # set rendering directory
    render = os.path.normpath("C:/Users/Brendan/Documents/grassdata/rendering/fusion")
    
    # set maps
    highres_dem = "uav_dsm@fusion"
    lowres_dem = "lidar_dem@fusion"
    
    # set parameters
    overwrite = True
    tension = 20
    smooth = 1
    npmin = 80
    dmin = 0.3
    
    # assign variables
    highres_sample = "highres_sample"
    lowres_sample = "lowres_sample"
    cover = "cover"
    fused_points="fused_points"
    fusion = "fusion"
    dx = "dx"
    dy = "dy"
    
    # set parameters for resampling
    info = gscript.raster_info(highres_dem)
    highres_npoints = int(info.cols) * int(info.rows) / 10
    info = gscript.raster_info(lowres_dem)
    lowres_npoints = int(info.cols) * int(info.rows) / 10
    
    # randomly sample high resolution dem
    gscript.run_command('g.region', raster=highres_dem)
    gscript.run_command('r.random', input=highres_dem, npoints=highres_npoints, vector=highres_sample, flags='d', overwrite=overwrite)
    
    # set cover map
    gscript.run_command('g.region', raster=lowres_dem)
    gscript.run_command('r.mapcalc', expression="{cover} = if(isnull({highres_dem}),{lowres_dem},null())".format(cover=cover, lowres_dem=lowres_dem, highres_dem=highres_dem), overwrite=overwrite)
    
    # randomly sample low resolution dem
    gscript.run_command('g.region', raster=lowres_dem)
    gscript.run_command('r.random', input=lowres_dem, npoints=lowres_npoints, cover=cover, vector=lowres_sample, flags='d', overwrite=overwrite)
    
    # patch
    gscript.run_command('v.patch', input=(highres_sample,lowres_sample), output=fused_points ,flags='b', overwrite=overwrite)
    
    # interpolation with partial derivatives
    gscript.run_command('v.surf.rst', input=fused_points, elevation=fusion, slope=dx, aspect=dy, tension=tension, smooth=smooth, npmin=npmin, dmin=dmin, flags='d', overwrite=overwrite)
    gscript.run_command('r.colors', map=fusion, color="elevation")
    
    # render elevation
    gscript.run_command('g.region', raster=lowres_dem)
    info = gscript.parse_command('r.info', map=fusion, flags='g')
    relief = "relief"
    gscript.run_command('d.mon', start=driver, width=info.cols, height=info.rows, output=os.path.join(render,fusion+".png"), overwrite=overwrite)
    gscript.run_command('r.relief', input=fusion, output=relief, zscale=1, overwrite=overwrite)
    gscript.run_command('r.colors', map=fusion, color="elevation")
    gscript.run_command('d.shade', shade=relief, color=fusion, brighten=25)
    gscript.run_command('d.legend', raster=fusion, at=(5,50,5,7))
    gscript.run_command('d.mon', stop=driver)
    
    # remove temporary maps
    gscript.run_command('g.remove', type='vector', name=['highres_sample', 'lowres_sample', 'fused_points'], flags='f')
    gscript.run_command('g.remove', type='raster', name='cover', flags='f')