Exemple #1
0
    def _computeRegions(self,
                        count,
                        startRegion,
                        endRegion=None,
                        zoomValue=None):
        """Computes regions based on start region and end region or zoom value
        for each of the animation frames."""
        region = dict(gcore.region())  # cast to dict, otherwise deepcopy error
        if startRegion:
            region = dict(
                parse_key_val(
                    gcore.read_command("g.region",
                                       flags="gu",
                                       region=startRegion),
                    val_type=float,
                ))

        del region["cells"]
        del region["cols"]
        del region["rows"]
        if "projection" in region:
            del region["projection"]
        if "zone" in region:
            del region["zone"]
        regions = []
        for i in range(self._mapCount):
            regions.append(copy.copy(region))
        self._regions = regions
        if not (endRegion or zoomValue):
            return

        startRegionDict = parse_key_val(
            gcore.read_command("g.region", flags="gu", region=startRegion),
            val_type=float,
        )
        if endRegion:
            endRegionDict = parse_key_val(
                gcore.read_command("g.region", flags="gu", region=endRegion),
                val_type=float,
            )
            for key in ("n", "s", "e", "w", "nsres", "ewres"):
                values = interpolate(startRegionDict[key], endRegionDict[key],
                                     self._mapCount)
                for value, region in zip(values, regions):
                    region[key] = value

        elif zoomValue:
            for i in range(self._mapCount):
                regions[i]["n"] -= zoomValue[0] * i
                regions[i]["e"] -= zoomValue[1] * i
                regions[i]["s"] += zoomValue[0] * i
                regions[i]["w"] += zoomValue[1] * i

                # handle cases when north < south and similarly EW
                if (regions[i]["n"] < regions[i]["s"]
                        or regions[i]["e"] < regions[i]["w"]):
                    regions[i] = regions[i - 1]

        self._regions = regions
Exemple #2
0
    def _computeRegions(self,
                        width,
                        height,
                        count,
                        startRegion,
                        endRegion=None,
                        zoomValue=None):
        """Computes regions based on start region and end region or zoom value
        for each of the animation frames."""
        currRegion = dict(
            gcore.region())  # cast to dict, otherwise deepcopy error
        del currRegion['cells']
        del currRegion['cols']
        del currRegion['rows']
        regions = []
        for i in range(self._mapCount):
            if endRegion or zoomValue:
                regions.append(copy.copy(currRegion))
            else:
                regions.append(None)
        if not startRegion:
            self._regions = regions
            return

        startRegionDict = parse_key_val(gcore.read_command('g.region',
                                                           flags='gu',
                                                           region=startRegion),
                                        val_type=float)
        if endRegion:
            endRegionDict = parse_key_val(gcore.read_command('g.region',
                                                             flags='gu',
                                                             region=endRegion),
                                          val_type=float)
            for key in ('n', 's', 'e', 'w'):
                values = interpolate(startRegionDict[key], endRegionDict[key],
                                     self._mapCount)
                for value, region in zip(values, regions):
                    region[key] = value

        elif zoomValue:
            for i in range(self._mapCount):
                regions[i]['n'] -= zoomValue[0] * i
                regions[i]['e'] -= zoomValue[1] * i
                regions[i]['s'] += zoomValue[0] * i
                regions[i]['w'] += zoomValue[1] * i

                # handle cases when north < south and similarly EW
                if regions[i]['n'] < regions[i]['s'] or \
                   regions[i]['e'] < regions[i]['w']:
                    regions[i] = regions[i - 1]

        for region in regions:
            mapwidth = abs(region['e'] - region['w'])
            mapheight = abs(region['n'] - region['s'])
            region['nsres'] = mapheight / height
            region['ewres'] = mapwidth / width

        self._regions = regions
Exemple #3
0
    def _computeRegions(self,
                        count,
                        startRegion,
                        endRegion=None,
                        zoomValue=None):
        """Computes regions based on start region and end region or zoom value
        for each of the animation frames."""
        region = dict(gcore.region())  # cast to dict, otherwise deepcopy error
        if startRegion:
            region = dict(
                parse_key_val(gcore.read_command('g.region',
                                                 flags='gu',
                                                 region=startRegion),
                              val_type=float))

        del region['cells']
        del region['cols']
        del region['rows']
        if 'projection' in region:
            del region['projection']
        if 'zone' in region:
            del region['zone']
        regions = []
        for i in range(self._mapCount):
            regions.append(copy.copy(region))
        self._regions = regions
        if not (endRegion or zoomValue):
            return

        startRegionDict = parse_key_val(gcore.read_command('g.region',
                                                           flags='gu',
                                                           region=startRegion),
                                        val_type=float)
        if endRegion:
            endRegionDict = parse_key_val(gcore.read_command('g.region',
                                                             flags='gu',
                                                             region=endRegion),
                                          val_type=float)
            for key in ('n', 's', 'e', 'w', 'nsres', 'ewres'):
                values = interpolate(startRegionDict[key], endRegionDict[key],
                                     self._mapCount)
                for value, region in zip(values, regions):
                    region[key] = value

        elif zoomValue:
            for i in range(self._mapCount):
                regions[i]['n'] -= zoomValue[0] * i
                regions[i]['e'] -= zoomValue[1] * i
                regions[i]['s'] += zoomValue[0] * i
                regions[i]['w'] += zoomValue[1] * i

                # handle cases when north < south and similarly EW
                if regions[i]['n'] < regions[i]['s'] or \
                   regions[i]['e'] < regions[i]['w']:
                    regions[i] = regions[i - 1]

        self._regions = regions
Exemple #4
0
    def _computeRegions(self, width, height, count, startRegion, endRegion=None, zoomValue=None):
        """Computes regions based on start region and end region or zoom value
        for each of the animation frames."""
        currRegion = dict(gcore.region())  # cast to dict, otherwise deepcopy error
        del currRegion['cells']
        del currRegion['cols']
        del currRegion['rows']
        regions = []
        for i in range(self._mapCount):
            if endRegion or zoomValue:
                regions.append(copy.copy(currRegion))
            else:
                regions.append(None)
        if not startRegion:
            self._regions = regions
            return

        startRegionDict = parse_key_val(gcore.read_command('g.region', flags='gu',
                                                                 region=startRegion),
                                              val_type=float)
        if endRegion:
            endRegionDict = parse_key_val(gcore.read_command('g.region', flags='gu',
                                                                   region=endRegion),
                                                val_type=float)
            for key in ('n', 's', 'e', 'w'):
                values = interpolate(startRegionDict[key], endRegionDict[key], self._mapCount)
                for value, region in zip(values, regions):
                    region[key] = value

        elif zoomValue:
            for i in range(self._mapCount):
                regions[i]['n'] -= zoomValue[0] * i
                regions[i]['e'] -= zoomValue[1] * i
                regions[i]['s'] += zoomValue[0] * i
                regions[i]['w'] += zoomValue[1] * i

                # handle cases when north < south and similarly EW
                if regions[i]['n'] < regions[i]['s'] or \
                   regions[i]['e'] < regions[i]['w']:
                        regions[i] = regions[i - 1]

        for region in regions:
            mapwidth = abs(region['e'] - region['w'])
            mapheight = abs(region['n'] - region['s'])
            region['nsres'] = mapheight / height
            region['ewres'] = mapwidth / width

        self._regions = regions
Exemple #5
0
    def MeasureArea(self, coords):
        """Calculate area and print to output window.

        :param coords: list of E, N coordinates
        """
        # TODO: make sure appending first point is needed for m.measure
        coordinates = coords + [coords[0]]
        coordinates = ','.join([str(item)
                                for sublist in coordinates for item in
                                sublist])
        result = RunCommand(
            'm.measure',
            flags='g',
            coordinates=coordinates,
            read=True).strip()
        result = parse_key_val(result)
        if 'units' not in result:
            self._giface.WriteWarning(
                _("Units not recognized, measurement failed."))
            unit = ''
        else:
            unit = result['units'].split(',')[1]
        if 'area' not in result:
            text = _("Area: {area} {unit}\n").format(area=0, unit=unit)
        else:
            text = _("Area: {area} {unit}\n").format(
                area=result['area'], unit=unit)
        self._giface.WriteLog(text, notification=Notification.MAKE_VISIBLE)
Exemple #6
0
    def MeasureArea(self, coords):
        """Calculate area and print to output window.

        :param coords: list of E, N coordinates
        """
        # TODO: make sure appending first point is needed for m.measure
        coordinates = coords + [coords[0]]
        coordinates = ','.join([str(item)
                                for sublist in coordinates for item in
                                sublist])
        result = RunCommand(
            'm.measure',
            flags='g',
            coordinates=coordinates,
            read=True).strip()
        result = parse_key_val(result)
        if 'units' not in result:
            self._giface.WriteWarning(
                _("Units not recognized, measurement failed."))
            unit = ''
        else:
            unit = result['units'].split(',')[1]
        if 'area' not in result:
            text = _("Area: {area} {unit}\n").format(area=0, unit=unit)
        else:
            text = _("Area: {area} {unit}\n").format(
                area=result['area'], unit=unit)
        self._giface.WriteLog(text, notification=Notification.MAKE_VISIBLE)
Exemple #7
0
    def linear_regression(self, x, y):
        """
        Simple wrapper around the GRASS GIS module r.regression.line
        
        Parameters
        ----------
        x : str
            Name of GRASS GIS raster map to use as the x-variable. Has to be within the RasterStack
            object.
        
        y : str
            Name of GRASS GIS raster map to use as the y-variable.
        
        Returns
        -------
        dict
            Containing the regression statistics.
        """

        regr = r.regression_line(mapx=x, mapy=y, flags="g",
                                 stdout_=PIPE).outputs.stdout.strip()

        regr = parse_key_val(regr, sep="=")

        return regr
Exemple #8
0
def parse_tiles(tiles):
    # convert r.tileset output into list of dicts
    tiles = [i.split(';') for i in tiles]
    tiles = [[parse_key_val(i) for i in t] for t in tiles]

    tiles_reg = []
    for index, tile in enumerate(tiles):
        tiles_reg.append({})
        for param in tile:
            tiles_reg[index].update(param)

    return(tiles_reg)
Exemple #9
0
def map_exists(name, type, mapset=None):
    """Check if map exists

    :param name: name of the map (without a Mapset)
    :param type: data type ('raster', 'raster_3d', and 'vector')
    :param mapset: Mapset (you can use dot to refer to the current Mapset)
    """
    # change type to element used by find file
    # otherwise, we are not checking the input,
    # so anything accepted by g.findfile will work
    # also supporting both short and full names
    # but this can change in the
    # future (this function documentation is clear about what's legal)
    if type == "raster" or type == "rast":
        type = "cell"
    elif type == "raster_3d" or type == "rast3d" or type == "raster3d":
        type = "grid3"
    elif type == "vect":
        type = "vector"

    extra_params = {}
    if mapset:
        if mapset == ".":
            mapset = get_current_mapset()
        extra_params.update({"mapset": mapset})

    # g.findfile returns non-zero when file was not found
    # so we ignore return code and just focus on stdout
    process = start_command(
        "g.findfile",
        flags="n",
        element=type,
        file=name,
        mapset=mapset,
        stdout=PIPE,
        stderr=PIPE,
        **extra_params,
    )
    output, errors = process.communicate()
    info = parse_key_val(output)
    # file is the key questioned in grass.script.core find_file()
    # return code should be equivalent to checking the output
    # g.findfile returns non-zero when nothing found but scripts are used to
    # check the output, so it is unclear what should be or is the actual
    # g.findfile interface
    # see also #2475 for discussion about types/files
    if info["file"]:
        return True
    else:
        return False
Exemple #10
0
    def multiple_regression(self,
                            xs,
                            y,
                            estimates=None,
                            residuals=None,
                            overwrite=False):
        """
        Simple wrapper around the GRASS GIS module r.regression.multi

        Parameters
        ----------
        x : str
            Name of GRASS GIS raster map to use as the x-variable. Has to be
            within the RasterStack object.

        y : str
            Name of GRASS GIS raster map to use as the y-variable.

        estimates : str (opt)
            Optionally specify a name to create a raster map of the regression
            estimate.

        residuals : str (opt)
            Optionally specify a name to create a raste rmap of the residuals.

        overwrite : bool (default is False)
            Overwrite existing GRASS GIS rasters for estimates and residuals.

        Returns
        -------
        dict
            Containing the regression statistics.
        """

        regr = r.regression_multi(
            mapx=xs,
            mapy=y,
            flags="g",
            residuals=residuals,
            estimates=estimates,
            overwrite=overwrite,
            stdout_=PIPE,
        ).outputs.stdout.strip()

        regr = parse_key_val(regr, sep="=")

        return regr
Exemple #11
0
def main():
    os.environ["GRASS_RENDER_IMMEDIATE"] = "png"
    os.environ["GRASS_RENDER_FILE"] = options["output"]
    os.environ["GRASS_RENDER_FILE_COMPRESSION"] = options["compression"]
    os.environ["GRASS_RENDER_WIDTH"] = options["width"]
    os.environ["GRASS_RENDER_HEIGHT"] = options["height"]

    if flags["w"]:
        # get display region info
        s = grass.read_command("d.info", flags="g")
        win = grassutils.parse_key_val(s, val_type=float)

    monitor_old = None
    genv = gisenv()
    if "MONITOR" in genv:
        monitor_old = genv["MONITOR"]
        g.gisenv(unset="MONITOR")

    if options["rgb_column"]:
        d.vect(
            map=options["input"],
            rgb_column=options["rgb_column"],
            flags="a",
            quiet=True,
        )
    else:
        d.vect(map=options["input"])

    if monitor_old:
        g.gisenv(set="MONITOR=%s" % monitor_old)

    if flags["w"]:

        wldfile = options["output"].split(".")[0] + ".wld"
        file_ = open(wldfile, "w")
        file_.write("%36.15f \n" % win["ewres"])
        file_.write("%36.15f \n" % 0.0)
        file_.write("%36.15f \n" % 0.0)
        file_.write("%36.15f \n" % (-1 * win["nsres"]))
        file_.write("%36.15f \n" % (win["w"] + win["ewres"] / 2.0))
        file_.write("%36.15f \n" % (win["n"] - win["nsres"] / 2.0))
        file_.close()
Exemple #12
0
def main():
    os.environ['GRASS_RENDER_IMMEDIATE'] = 'png'
    os.environ['GRASS_RENDER_FILE'] = options['output']
    os.environ['GRASS_RENDER_FILE_COMPRESSION'] = options['compression']
    os.environ['GRASS_RENDER_WIDTH'] = options['width']
    os.environ['GRASS_RENDER_HEIGHT'] = options['height']

    if flags['w']:
        # get display region info
        s = grass.read_command('d.info', flags='g')
        win = grassutils.parse_key_val(s, val_type=float)

    monitor_old = None
    genv = gisenv()
    if 'MONITOR' in genv:
        monitor_old = genv['MONITOR']
        g.gisenv(unset='MONITOR')

    if options['rgb_column']:
        d.vect(map=options['input'],
               rgb_column=options['rgb_column'],
               flags='a',
               quiet=True)
    else:
        d.vect(map=options['input'])

    if monitor_old:
        g.gisenv(set='MONITOR=%s' % monitor_old)

    if flags['w']:

        wldfile = options['output'].split('.')[0] + '.wld'
        file_ = open(wldfile, "w")
        file_.write("%36.15f \n" % win['ewres'])
        file_.write("%36.15f \n" % 0.0)
        file_.write("%36.15f \n" % 0.0)
        file_.write("%36.15f \n" % (-1 * win['nsres']))
        file_.write("%36.15f \n" % (win['w'] + win['ewres'] / 2.0))
        file_.write("%36.15f \n" % (win['n'] - win['nsres'] / 2.0))
        file_.close()
    def test_shell_script_style(self):

        self.assertDictEqual(parse_key_val(R_UNIVAR_KEYVAL_INT, val_type=int),
                             R_UNIVAR_KEYVAL_INT_DICT)
Exemple #14
0
def main():
    fileorig = options['input']
    filevect = options['output']
    
    if not filevect:
	filevect = basename(fileorig, 'txt')

    #are we in LatLong location?
    s = grass.read_command("g.proj", flags='j')
    kv = parse_key_val(s)
    if kv['+proj'] != 'longlat':
	grass.fatal(_("This module only operates in LatLong/WGS84 locations"))

    #### setup temporary file
    tmpfile = grass.tempfile()

    coldescs = [("RC",		"rc integer"),
		("UFI",		"uf1 integer"),
		("UNI",		"uni integer"),
		("LAT",		"lat double precision"),
		("LONG",	"lon double precision"),
		("DMS_LAT",	"dms_lat varchar(6)"),
		("DMS_LONG",	"dms_long varchar(7)"),
		("UTM",		"utm varchar(4)"),
		("JOG",		"jog varchar(7)"),
		("FC",		"fc varchar(1)"),
		("DSG",		"dsg varchar(5)"),
		("PC",		"pc integer"),
		("CC1",		"cci varchar(2)"),
		("ADM1",	"adm1 varchar(2)"),
		("ADM2",	"adm2 varchar(200)"),
		("DIM",		"dim integer"),
		("CC2",		"cc2 varchar(2)"),
		("NT",		"nt varchar(1)"),
		("LC",		"lc varchar(3)"),
		("SHORT_FORM",	"shortform varchar(128)"),
		("GENERIC",	"generic varchar(128)"),
		("SORT_NAME",	"sortname varchar(200)"),
		("FULL_NAME",	"fullname varchar(200)"),
		("FULL_NAME_ND","funamesd varchar(200)"),
		("MODIFY_DATE",	"mod_date date")]

    colnames = [desc[0] for desc in coldescs]
    coltypes = dict([(desc[0], 'integer' in desc[1]) for desc in coldescs])

    header = None
    num_places = 0
    inf = file(fileorig)
    outf = file(tmpfile, 'wb')
    for line in inf:
	fields = line.rstrip('\r\n').split('\t')
	if not header:
	    header = fields
	    continue
	vars = dict(zip(header, fields))
	fields2 = []
	for col in colnames:
	    if col in vars:
		if coltypes[col] and vars[col] == '':
		    fields2.append('0')
		else:
		    fields2.append(vars[col])
	    else:
		if coltypes[col]:
		    fields2.append('0')
		else:
		    fields2.append('')
	line2 = ';'.join(fields2) + '\n'
	outf.write(line2)
	num_places += 1
    outf.close()
    inf.close()

    grass.message(_("Converted %d place names.") % num_places)

    #TODO: fix dms_lat,dms_long DDMMSS -> DD:MM:SS
    # Solution:
    # IN=DDMMSS
    # DEG=`echo $IN | cut -b1,2`
    # MIN=`echo $IN | cut -b3,4`
    # SEC=`echo $IN | cut -b5,6`
    # DEG_STR="$DEG:$MIN:$SEC"
    
    #modifications (to match DBF 10 char column name limit):
    # short_form   -> shortform
    # sort_name    -> sortname
    # full_name    -> fullname
    # full_name_sd -> funamesd

    # pump data into GRASS:

    columns = [desc[1] for desc in coldescs]

    grass.run_command('v.in.ascii', cat = 0, x = 5, y = 4, sep = ';',
		      input = tmpfile, output = filevect,
		      columns = columns)

    try_remove(tmpfile)

    # write cmd history:
    vgrass.vector_history(filevect)
Exemple #15
0
def main():

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    return 0
Exemple #16
0
def main():
    coords = options['coordinates']
    input = options['input']
    output = options['output']
    fs = options['separator']
    proj_in = options['proj_in']
    proj_out = options['proj_out']
    ll_in = flags['i']
    ll_out = flags['o']
    decimal = flags['d']
    copy_input = flags['e']
    include_header = flags['c']

    #### check for cs2cs
    if not grass.find_program('cs2cs'):
	grass.fatal(_("cs2cs program not found, install PROJ.4 first: http://proj.maptools.org"))

    #### check for overenthusiasm
    if proj_in and ll_in:
	grass.fatal(_("Choose only one input parameter method"))

    if proj_out and ll_out:
	grass.fatal(_("Choose only one output parameter method")) 

    if ll_in and ll_out:
	grass.fatal(_("Choise only one auto-projection parameter method"))

    if output and not grass.overwrite() and os.path.exists(output):
	grass.fatal(_("Output file already exists")) 

    if not coords and not input:
        grass.fatal(_("One of <coordinates> and <input> must be given"))
    if coords and input:
        grass.fatal(_("Options <coordinates> and <input> are mutually exclusive"))

    #### parse field separator
    # FIXME: input_x,y needs to split on multiple whitespace between them
    if fs == ',':
        ifs = ofs = ','
    else:
	try:
	    ifs, ofs = fs.split(',')
	except ValueError:
	    ifs = ofs = fs

    ifs = separator(ifs)
    ofs = separator(ofs)

    #### set up projection params
    s = grass.read_command("g.proj", flags='j')
    kv = parse_key_val(s)
    if "XY location" in kv['+proj'] and (ll_in or ll_out):
	grass.fatal(_("Unable to project to or from a XY location")) 

    in_proj = None

    if ll_in:
	in_proj = "+proj=longlat +datum=WGS84"
	grass.verbose("Assuming LL WGS84 as input, current projection as output ")

    if ll_out:
	in_proj = grass.read_command('g.proj', flags = 'jf')

    if proj_in:
	in_proj = proj_in

    if not in_proj:
	grass.verbose("Assuming current location as input")
        in_proj = grass.read_command('g.proj', flags = 'jf')
    
    in_proj = in_proj.strip()
    grass.verbose("Input parameters: '%s'" % in_proj)

    out_proj = None

    if ll_out:
	out_proj = "+proj=longlat +datum=WGS84"
	grass.verbose("Assuming current projection as input, LL WGS84 as output ")

    if ll_in:
	out_proj = grass.read_command('g.proj', flags = 'jf')

    if proj_out:
	out_proj = proj_out

    if not out_proj:
	grass.fatal(_("Missing output projection parameters "))
    out_proj = out_proj.strip()
    grass.verbose("Output parameters: '%s'" % out_proj)

    #### set up input file
    if coords:
        x, y = coords.split(',')
        tmpfile = grass.tempfile()
        fd = open(tmpfile, "w")
        fd.write("%s%s%s\n" % (x, ifs, y))
        fd.close()
        inf = file(tmpfile)
    else:
        if input == '-':
            infile = None
            inf = sys.stdin
        else:
            infile = input
            if not os.path.exists(infile):
                grass.fatal(_("Unable to read input data"))
            inf = file(infile)
            grass.debug("input file=[%s]" % infile)
    
    #### set up output file
    if not output:
	outfile = None
	outf = sys.stdout
    else:
	outfile = output
	outf = open(outfile, 'w')
	grass.debug("output file=[%s]" % outfile) 

    #### set up output style
    if not decimal:
	outfmt = ["-w5"]
    else:
	outfmt = ["-f", "%.8f"]
    if not copy_input:
	copyinp = []
    else:
	copyinp = ["-E"]

    #### do the conversion
    # Convert cs2cs DMS format to GRASS DMS format:
    #   cs2cs | sed -e 's/d/:/g' -e "s/'/:/g"  -e 's/"//g'

    cmd = ['cs2cs'] + copyinp + outfmt + in_proj.split() + ['+to'] + out_proj.split()
    p = grass.Popen(cmd, stdin = grass.PIPE, stdout = grass.PIPE)

    tr = TrThread(ifs, inf, p.stdin)
    tr.start()

    if not copy_input:
	if include_header:
	    outf.write("x%sy%sz\n" % (ofs, ofs))
	for line in p.stdout:
            try:
                xy, z = line.split(' ', 1)
                x, y = xy.split('\t')
            except ValueError:
                grass.fatal(line)
            
	    outf.write('%s%s%s%s%s\n' % \
                       (x.strip(), ofs, y.strip(), ofs, z.strip()))
    else:
	if include_header:
	    outf.write("input_x%sinput_y%sx%sy%sz\n" % (ofs, ofs, ofs, ofs))
	for line in p.stdout:
            inXYZ, x, rest = line.split('\t')
            inX, inY = inXYZ.split(' ')[:2]
	    y, z = rest.split(' ', 1)
	    outf.write('%s%s%s%s%s%s%s%s%s\n' % \
                       (inX.strip(), ofs, inY.strip(), ofs, x.strip(), \
		        ofs, y.strip(), ofs, z.strip()))

    p.wait()

    if p.returncode != 0:
	grass.warning(_("Projection transform probably failed, please investigate"))
Exemple #17
0
def main():
    fileorig = options['input']
    filevect = options['output']

    if not filevect:
        filevect = basename(fileorig, 'txt')

    #are we in LatLong location?
    s = grass.read_command("g.proj", flags='j')
    kv = parse_key_val(s)
    if kv['+proj'] != 'longlat':
        grass.fatal(_("This module only operates in LatLong/WGS84 locations"))

    #### setup temporary file
    tmpfile = grass.tempfile()

    coldescs = [("RC", "rc integer"), ("UFI", "uf1 integer"),
                ("UNI", "uni integer"), ("LAT", "lat double precision"),
                ("LONG", "lon double precision"),
                ("DMS_LAT", "dms_lat varchar(6)"),
                ("DMS_LONG", "dms_long varchar(7)"), ("UTM", "utm varchar(4)"),
                ("JOG", "jog varchar(7)"), ("FC", "fc varchar(1)"),
                ("DSG", "dsg varchar(5)"), ("PC", "pc integer"),
                ("CC1", "cci varchar(2)"), ("ADM1", "adm1 varchar(2)"),
                ("ADM2", "adm2 varchar(200)"), ("DIM", "dim integer"),
                ("CC2", "cc2 varchar(2)"), ("NT", "nt varchar(1)"),
                ("LC", "lc varchar(3)"),
                ("SHORT_FORM", "shortform varchar(128)"),
                ("GENERIC", "generic varchar(128)"),
                ("SORT_NAME", "sortname varchar(200)"),
                ("FULL_NAME", "fullname varchar(200)"),
                ("FULL_NAME_ND", "funamesd varchar(200)"),
                ("MODIFY_DATE", "mod_date date")]

    colnames = [desc[0] for desc in coldescs]
    coltypes = dict([(desc[0], 'integer' in desc[1]) for desc in coldescs])

    header = None
    num_places = 0
    inf = file(fileorig)
    outf = file(tmpfile, 'wb')
    for line in inf:
        fields = line.rstrip('\r\n').split('\t')
        if not header:
            header = fields
            continue
        vars = dict(zip(header, fields))
        fields2 = []
        for col in colnames:
            if col in vars:
                if coltypes[col] and vars[col] == '':
                    fields2.append('0')
                else:
                    fields2.append(vars[col])
            else:
                if coltypes[col]:
                    fields2.append('0')
                else:
                    fields2.append('')
        line2 = ';'.join(fields2) + '\n'
        outf.write(line2)
        num_places += 1
    outf.close()
    inf.close()

    grass.message(_("Converted %d place names.") % num_places)

    #TODO: fix dms_lat,dms_long DDMMSS -> DD:MM:SS
    # Solution:
    # IN=DDMMSS
    # DEG=`echo $IN | cut -b1,2`
    # MIN=`echo $IN | cut -b3,4`
    # SEC=`echo $IN | cut -b5,6`
    # DEG_STR="$DEG:$MIN:$SEC"

    #modifications (to match DBF 10 char column name limit):
    # short_form   -> shortform
    # sort_name    -> sortname
    # full_name    -> fullname
    # full_name_sd -> funamesd

    # pump data into GRASS:

    columns = [desc[1] for desc in coldescs]

    grass.run_command('v.in.ascii',
                      cat=0,
                      x=5,
                      y=4,
                      sep=';',
                      input=tmpfile,
                      output=filevect,
                      columns=columns)

    try_remove(tmpfile)

    # write cmd history:
    vgrass.vector_history(filevect)
Exemple #18
0
def main():
    coords = options["coordinates"]
    input = options["input"]
    output = options["output"]
    fs = options["separator"]
    proj_in = options["proj_in"]
    proj_out = options["proj_out"]
    ll_in = flags["i"]
    ll_out = flags["o"]
    decimal = flags["d"]
    copy_input = flags["e"]
    include_header = flags["c"]

    # check for cs2cs
    if not gcore.find_program("cs2cs"):
        gcore.fatal(
            _("cs2cs program not found, install PROJ first: \
            https://proj.org"))

    # parse field separator
    # FIXME: input_x,y needs to split on multiple whitespace between them
    if fs == ",":
        ifs = ofs = ","
    else:
        try:
            ifs, ofs = fs.split(",")
        except ValueError:
            ifs = ofs = fs

    ifs = separator(ifs)
    ofs = separator(ofs)

    # set up projection params
    s = gcore.read_command("g.proj", flags="j")
    kv = parse_key_val(s)
    if "XY location" in kv["+proj"] and (ll_in or ll_out):
        gcore.fatal(_("Unable to project to or from a XY location"))

    in_proj = None

    if ll_in:
        in_proj = "+proj=longlat +datum=WGS84"
        gcore.verbose(
            "Assuming LL WGS84 as input, current projection as output ")

    if ll_out:
        in_proj = gcore.read_command("g.proj", flags="jf")

    if proj_in:
        if "+" in proj_in:
            in_proj = proj_in
        else:
            gcore.fatal(_("Invalid PROJ.4 input specification"))

    if not in_proj:
        gcore.verbose("Assuming current location as input")
        in_proj = gcore.read_command("g.proj", flags="jf")

    in_proj = in_proj.strip()
    gcore.verbose("Input parameters: '%s'" % in_proj)

    out_proj = None

    if ll_out:
        out_proj = "+proj=longlat +datum=WGS84"
        gcore.verbose(
            "Assuming current projection as input, LL WGS84 as output ")

    if ll_in:
        out_proj = gcore.read_command("g.proj", flags="jf")

    if proj_out:
        if "+" in proj_out:
            out_proj = proj_out
        else:
            gcore.fatal(_("Invalid PROJ.4 output specification"))

    if not out_proj:
        gcore.fatal(_("Missing output projection parameters "))
    out_proj = out_proj.strip()
    gcore.verbose("Output parameters: '%s'" % out_proj)

    # set up input file
    if coords:
        x, y = coords.split(",")
        tmpfile = gcore.tempfile()
        fd = open(tmpfile, "w")
        fd.write("%s%s%s\n" % (x, ifs, y))
        fd.close()
        inf = open(tmpfile)
    else:
        if input == "-":
            infile = None
            inf = sys.stdin
        else:
            infile = input
            if not os.path.exists(infile):
                gcore.fatal(_("Unable to read input data"))
            inf = open(infile)
            gcore.debug("input file=[%s]" % infile)

    # set up output file
    if not output:
        outfile = None
        outf = sys.stdout
    else:
        outfile = output
        outf = open(outfile, "w")
        gcore.debug("output file=[%s]" % outfile)

    # set up output style
    if not decimal:
        outfmt = ["-w5"]
    else:
        outfmt = ["-f", "%.8f"]
    if not copy_input:
        copyinp = []
    else:
        copyinp = ["-E"]

    # do the conversion
    # Convert cs2cs DMS format to GRASS DMS format:
    #   cs2cs | sed -e 's/d/:/g' -e "s/'/:/g"  -e 's/"//g'

    cmd = ["cs2cs"
           ] + copyinp + outfmt + in_proj.split() + ["+to"] + out_proj.split()

    p = gcore.Popen(cmd, stdin=gcore.PIPE, stdout=gcore.PIPE)

    tr = TrThread(ifs, inf, p.stdin)
    tr.start()

    if not copy_input:
        if include_header:
            outf.write("x%sy%sz\n" % (ofs, ofs))
        for line in p.stdout:
            try:
                xy, z = decode(line).split(" ", 1)
                x, y = xy.split("\t")
            except ValueError:
                gcore.fatal(line)

            outf.write("%s%s%s%s%s\n" %
                       (x.strip(), ofs, y.strip(), ofs, z.strip()))
    else:
        if include_header:
            outf.write("input_x%sinput_y%sx%sy%sz\n" % (ofs, ofs, ofs, ofs))
        for line in p.stdout:
            inXYZ, x, rest = decode(line).split("\t")
            inX, inY = inXYZ.split(" ")[:2]
            y, z = rest.split(" ", 1)
            outf.write("%s%s%s%s%s%s%s%s%s\n" % (
                inX.strip(),
                ofs,
                inY.strip(),
                ofs,
                x.strip(),
                ofs,
                y.strip(),
                ofs,
                z.strip(),
            ))

    p.wait()

    if p.returncode != 0:
        gcore.warning(
            _("Projection transform probably failed, please investigate"))
Exemple #19
0
    def test_shell_script_style(self):

        self.assertDictEqual(parse_key_val(R_UNIVAR_KEYVAL_INT, val_type=int), R_UNIVAR_KEYVAL_INT_DICT)
Exemple #20
0
def main():
    fileorig = options["input"]
    filevect = options["output"]

    if not filevect:
        filevect = basename(fileorig, "txt")

    # are we in LatLong location?
    s = grass.read_command("g.proj", flags="j")
    kv = parse_key_val(s)
    if kv["+proj"] != "longlat":
        grass.fatal(_("This module only operates in LatLong/WGS84 locations"))

    #### setup temporary file
    tmpfile = grass.tempfile()

    coldescs = [
        ("RC", "rc integer"),
        ("UFI", "uf1 integer"),
        ("UNI", "uni integer"),
        ("LAT", "lat double precision"),
        ("LONG", "lon double precision"),
        ("DMS_LAT", "dms_lat integer"),
        ("DMS_LONG", "dms_long integer"),
        ("MGRS", "mgrs varchar(15)"),
        ("JOG", "jog varchar(7)"),
        ("FC", "fc varchar(1)"),
        ("DSG", "dsg varchar(6)"),
        ("PC", "pc integer"),
        ("CC1", "cci varchar(255)"),
        ("ADM1", "adm1 varchar(2)"),
        ("POP", "pop integer"),
        ("ELEV", "elev double precision"),
        ("CC2", "cc2 varchar(255)"),
        ("NT", "nt varchar(2)"),
        ("LC", "lc varchar(3)"),
        ("SHORT_FORM", "shortform varchar(128)"),
        ("GENERIC", "generic varchar(128)"),
        ("SORT_NAME_RO", "sortnamero varchar(255)"),
        ("FULL_NAME_RO", "fullnamero varchar(255)"),
        ("FULL_NAME_ND_RO", "funamesdro varchar(255)"),
        ("SORT_NAME_RG", "sortnamerg varchar(255)"),
        ("FULL_NAME_RG", "fullnamerg varchar(255)"),
        ("FULL_NAME_ND_RG", "funamesdrg varchar(255)"),
        ("NOTE", "note varchar(4000)"),
        ("MODIFY_DATE", "mod_date date"),
        ("DISPLAY", "display varchar(255)"),
        ("NAME_RANK", "namerank integer"),
        ("NAME_LINK", "namelink integer"),
        ("TRANSL_CD", "translcd varchar(32)"),
        ("NM_MODIFY_DATE", "nmmodifydate varchar(10)"),
    ]

    colnames = [desc[0] for desc in coldescs]
    coltypes = dict([(desc[0], "integer" in desc[1]) for desc in coldescs])

    header = None
    num_places = 0
    inf = open(fileorig)
    outf = open(tmpfile, "wb")
    for line in inf:
        fields = line.rstrip("\r\n").split("\t")
        if not header:
            header = fields
            continue
        vars = dict(zip(header, fields))
        fields2 = []
        for col in colnames:
            if col in vars:
                if coltypes[col] and vars[col] == "":
                    fields2.append("0")
                else:
                    fields2.append(vars[col])
            else:
                if coltypes[col]:
                    fields2.append("0")
                else:
                    fields2.append("")
        line2 = ";".join(fields2) + "\n"
        outf.write(line2)
        num_places += 1
    outf.close()
    inf.close()

    grass.message(_("Converted %d place names.") % num_places)

    # TODO: fix dms_lat,dms_long DDMMSS -> DD:MM:SS
    # Solution:
    # IN=DDMMSS
    # DEG=`echo $IN | cut -b1,2`
    # MIN=`echo $IN | cut -b3,4`
    # SEC=`echo $IN | cut -b5,6`
    # DEG_STR="$DEG:$MIN:$SEC"

    # modifications (to match DBF 10 char column name limit):
    # short_form   -> shortform
    # sort_name    -> sortname
    # full_name    -> fullname
    # full_name_sd -> funamesd

    # pump data into GRASS:

    columns = [desc[1] for desc in coldescs]

    grass.run_command(
        "v.in.ascii",
        cat=0,
        x=5,
        y=4,
        sep=";",
        input=tmpfile,
        output=filevect,
        columns=columns,
    )

    try_remove(tmpfile)

    # write cmd history:
    vgrass.vector_history(filevect)
Exemple #21
0
def main():
    shell = flags['g']
    serial = flags['s']
    bands = options['input'].split(',')

    if len(bands) < 4:
        grass.fatal(_("At least four input maps required"))

    output = options['output']
    # calculate the Stddev for TM bands
    grass.message(_("Calculating standard deviations for all bands..."))
    stddev = {}

    if serial:
        for band in bands:
            grass.verbose("band %d" % band)
            s = grass.read_command('r.univar', flags='g', map=band)
            kv = parse_key_val(s)
            stddev[band] = float(kv['stddev'])
    else:
        # run all bands in parallel
        if "WORKERS" in os.environ:
            workers = int(os.environ["WORKERS"])
        else:
            workers = len(bands)
        proc = {}
        pout = {}

        # spawn jobs in the background
        n = 0
        for band in bands:
            proc[band] = grass.pipe_command('r.univar', flags='g', map=band)
            if n % workers is 0:
                # wait for the ones launched so far to finish
                for bandp in bands[:n]:
                    if not proc[bandp].stdout.closed:
                        pout[bandp] = proc[bandp].communicate()[0]
                    proc[bandp].wait()
            n = n + 1

        # wait for jobs to finish, collect the output
        for band in bands:
            if not proc[band].stdout.closed:
                pout[band] = proc[band].communicate()[0]
            proc[band].wait()

    # parse the results
        for band in bands:
            kv = parse_key_val(pout[band])
            stddev[band] = float(kv['stddev'])


    grass.message(_("Calculating Correlation Matrix..."))
    correlation = {}
    s = grass.read_command('r.covar', flags='r', map=[band for band in bands],
                           quiet=True)

    # We need to skip the first line, since r.covar prints the number of values
    lines = s.splitlines()
    for i, row in zip(bands, lines[1:]):
        for j, cell in zip(bands, row.split(' ')):
            correlation[i, j] = float(cell)

    # Calculate all combinations
    grass.message(_("Calculating OIF for all band combinations..."))

    oif = []
    for p in perms(bands):
        oif.append((oifcalc(stddev, correlation, *p), p))
    oif.sort(reverse=True)

    grass.verbose(_("The Optimum Index Factor analysis result " \
                    "(best combination shown first):"))

    if shell:
        fmt = "%s,%s,%s:%.4f\n"
    else:
        fmt = "%s, %s, %s:  %.4f\n"

    if not output or output == '-':
        for v, p in oif:
            sys.stdout.write(fmt % (p + (v,)))
    else:
        outf = file(output, 'w')
        for v, p in oif:
            outf.write(fmt % (p + (v,)))
        outf.close()
Exemple #22
0
def main():
    coords = options['coordinates']
    input = options['input']
    output = options['output']
    fs = options['separator']
    proj_in = options['proj_in']
    proj_out = options['proj_out']
    ll_in = flags['i']
    ll_out = flags['o']
    decimal = flags['d']
    copy_input = flags['e']
    include_header = flags['c']

    # check for cs2cs
    if not gcore.find_program('cs2cs'):
        gcore.fatal(
            _("cs2cs program not found, install PROJ.4 first: \
            http://proj.maptools.org"))

    # check for overenthusiasm
    if proj_in and ll_in:
        gcore.fatal(_("Choose only one input parameter method"))

    if proj_out and ll_out:
        gcore.fatal(_("Choose only one output parameter method"))

    if ll_in and ll_out:
        gcore.fatal(_("Choose only one auto-projection parameter method"))

    if output and not gcore.overwrite() and os.path.exists(output):
        gcore.fatal(_("Output file already exists"))

    if not coords and not input:
        gcore.fatal(_("One of <coordinates> and <input> must be given"))
    if coords and input:
        gcore.fatal(
            _("Options <coordinates> and <input> are mutually exclusive"))

    # parse field separator
    # FIXME: input_x,y needs to split on multiple whitespace between them
    if fs == ',':
        ifs = ofs = ','
    else:
        try:
            ifs, ofs = fs.split(',')
        except ValueError:
            ifs = ofs = fs

    ifs = separator(ifs)
    ofs = separator(ofs)

    # set up projection params
    s = gcore.read_command("g.proj", flags='j')
    kv = parse_key_val(s)
    if "XY location" in kv['+proj'] and (ll_in or ll_out):
        gcore.fatal(_("Unable to project to or from a XY location"))

    in_proj = None

    if ll_in:
        in_proj = "+proj=longlat +datum=WGS84"
        gcore.verbose(
            "Assuming LL WGS84 as input, current projection as output ")

    if ll_out:
        in_proj = gcore.read_command('g.proj', flags='jf')

    if proj_in:
        if '+' in proj_in:
            in_proj = proj_in
        else:
            gcore.fatal(_("Invalid PROJ.4 input specification"))

    if not in_proj:
        gcore.verbose("Assuming current location as input")
        in_proj = gcore.read_command('g.proj', flags='jf')

    in_proj = in_proj.strip()
    gcore.verbose("Input parameters: '%s'" % in_proj)

    out_proj = None

    if ll_out:
        out_proj = "+proj=longlat +datum=WGS84"
        gcore.verbose(
            "Assuming current projection as input, LL WGS84 as output ")

    if ll_in:
        out_proj = gcore.read_command('g.proj', flags='jf')

    if proj_out:
        if '+' in proj_out:
            out_proj = proj_out
        else:
            gcore.fatal(_("Invalid PROJ.4 output specification"))

    if not out_proj:
        gcore.fatal(_("Missing output projection parameters "))
    out_proj = out_proj.strip()
    gcore.verbose("Output parameters: '%s'" % out_proj)

    # set up input file
    if coords:
        x, y = coords.split(',')
        tmpfile = gcore.tempfile()
        fd = open(tmpfile, "w")
        fd.write("%s%s%s\n" % (x, ifs, y))
        fd.close()
        inf = file(tmpfile)
    else:
        if input == '-':
            infile = None
            inf = sys.stdin
        else:
            infile = input
            if not os.path.exists(infile):
                gcore.fatal(_("Unable to read input data"))
            inf = file(infile)
            gcore.debug("input file=[%s]" % infile)

    # set up output file
    if not output:
        outfile = None
        outf = sys.stdout
    else:
        outfile = output
        outf = open(outfile, 'w')
        gcore.debug("output file=[%s]" % outfile)

    # set up output style
    if not decimal:
        outfmt = ["-w5"]
    else:
        outfmt = ["-f", "%.8f"]
    if not copy_input:
        copyinp = []
    else:
        copyinp = ["-E"]

    # do the conversion
    # Convert cs2cs DMS format to GRASS DMS format:
    #   cs2cs | sed -e 's/d/:/g' -e "s/'/:/g"  -e 's/"//g'

    cmd = ['cs2cs'] + copyinp + outfmt + \
        in_proj.split() + ['+to'] + out_proj.split()

    p = gcore.Popen(cmd, stdin=gcore.PIPE, stdout=gcore.PIPE)

    tr = TrThread(ifs, inf, p.stdin)
    tr.start()

    if not copy_input:
        if include_header:
            outf.write("x%sy%sz\n" % (ofs, ofs))
        for line in p.stdout:
            try:
                xy, z = line.split(' ', 1)
                x, y = xy.split('\t')
            except ValueError:
                gcore.fatal(line)

            outf.write('%s%s%s%s%s\n' %
                       (x.strip(), ofs, y.strip(), ofs, z.strip()))
    else:
        if include_header:
            outf.write("input_x%sinput_y%sx%sy%sz\n" % (ofs, ofs, ofs, ofs))
        for line in p.stdout:
            inXYZ, x, rest = line.split('\t')
            inX, inY = inXYZ.split(' ')[:2]
            y, z = rest.split(' ', 1)
            outf.write('%s%s%s%s%s%s%s%s%s\n' %
                       (inX.strip(), ofs, inY.strip(), ofs, x.strip(), ofs,
                        y.strip(), ofs, z.strip()))

    p.wait()

    if p.returncode != 0:
        gcore.warning(
            _("Projection transform probably failed, please investigate"))
Exemple #23
0
def main():
    options, flags = gcore.parser()

    location = options["location"]
    mapset = options["mapset"]
    dbase = options["dbase"]

    resolution = options["resolution"]
    if resolution:
        resolution = float(resolution)
    method = options["method"]
    curr_region = flags["r"]

    transform_z = flags["z"]
    overwrite = flags["o"]

    if not curr_region:
        gcore.use_temp_region()
        atexit.register(gcore.del_temp_region)
    if overwrite or gcore.overwrite():
        overwrite = True
    else:
        overwrite = False
    #
    # r.proj
    #
    parameters = dict(location=location,
                      mapset=mapset,
                      flags="l",
                      overwrite=overwrite)
    if dbase:
        parameters.update(dict(dbase=dbase))
    # first run r.proj to see if it works
    try:
        gcore.run_command("r.proj", quiet=True, **parameters)
    except CalledModuleError:
        gcore.fatal(
            _("Module r.proj failed. Please check the error messages above."))
    # run again to get the raster maps
    rasters = gcore.read_command("r.proj", **parameters)
    rasters = rasters.strip().split()
    gcore.info(
        _("{num} raster maps will be reprojected from mapset <{mapsetS}> "
          "to mapset <{mapsetT}>.").format(num=len(rasters),
                                           mapsetS=mapset,
                                           mapsetT=gcore.gisenv()["MAPSET"]))

    parameters = dict(location=location,
                      mapset=mapset,
                      method=method,
                      overwrite=overwrite)
    if resolution:
        parameters.update(dict(resolution=resolution))
    if dbase:
        parameters.update(dict(dbase=dbase))
    for raster in rasters:
        if not curr_region:
            bounds = gcore.read_command("r.proj",
                                        input=raster,
                                        flags="g",
                                        **parameters)
            bounds = parse_key_val(bounds, vsep=" ")
            gcore.run_command("g.region", **bounds)

        gcore.run_command("r.proj", input=raster, **parameters)

    #
    # v.proj
    #
    parameters = dict(location=location,
                      mapset=mapset,
                      flags="l",
                      overwrite=overwrite)
    if dbase:
        parameters.update(dict(dbase=dbase))
    # first run v.proj to see if it works
    try:
        gcore.run_command("v.proj", quiet=True, **parameters)
    except CalledModuleError:
        gcore.fatal(
            _("Module v.proj failed. Please check the error messages above."))
    # run again to get the vector maps
    vectors = gcore.read_command("v.proj", **parameters)
    vectors = vectors.strip().split()
    gcore.info(
        _("{num} vectors maps will be reprojected from mapset <{mapsetS}> "
          "to mapset <{mapsetT}>.").format(num=len(vectors),
                                           mapsetS=mapset,
                                           mapsetT=gcore.gisenv()["MAPSET"]))

    parameters = dict(location=location, mapset=mapset, overwrite=overwrite)
    if transform_z:
        parameters.update(dict(flags="z"))
    for vector in vectors:
        gcore.run_command("v.proj", input=vector, **parameters)
Exemple #24
0
def main():
    shell = flags['g']
    serial = flags['s']
    bands = options['input'].split(',')

    if len(bands) < 4:
        grass.fatal(_("At least four input maps required"))

    output = options['output']
    # calculate the Stddev for TM bands
    grass.message(_("Calculating standard deviations for all bands..."))
    stddev = {}

    if serial:
        for band in bands:
            grass.verbose("band %d" % band)
            s = grass.read_command('r.univar', flags='g', map=band)
            kv = parse_key_val(s)
            stddev[band] = float(kv['stddev'])
    else:
        # run all bands in parallel
        if "WORKERS" in os.environ:
            workers = int(os.environ["WORKERS"])
        else:
            workers = len(bands)
        proc = {}
        pout = {}

        # spawn jobs in the background
        n = 0
        for band in bands:
            proc[band] = grass.pipe_command('r.univar', flags='g', map=band)
            if n % workers is 0:
                # wait for the ones launched so far to finish
                for bandp in bands[:n]:
                    if not proc[bandp].stdout.closed:
                        pout[bandp] = proc[bandp].communicate()[0]
                    proc[bandp].wait()
            n = n + 1

        # wait for jobs to finish, collect the output
        for band in bands:
            if not proc[band].stdout.closed:
                pout[band] = proc[band].communicate()[0]
            proc[band].wait()

    # parse the results
        for band in bands:
            kv = parse_key_val(pout[band])
            stddev[band] = float(kv['stddev'])

    grass.message(_("Calculating Correlation Matrix..."))
    correlation = {}
    s = grass.read_command('r.covar',
                           flags='r',
                           map=[band for band in bands],
                           quiet=True)

    # We need to skip the first line, since r.covar prints the number of values
    lines = s.splitlines()
    for i, row in zip(bands, lines[1:]):
        for j, cell in zip(bands, row.split(' ')):
            correlation[i, j] = float(cell)

    # Calculate all combinations
    grass.message(_("Calculating OIF for all band combinations..."))

    oif = []
    for p in perms(bands):
        oif.append((oifcalc(stddev, correlation, *p), p))
    oif.sort(reverse=True)

    grass.verbose(
        _("The Optimum Index Factor analysis result "
          "(best combination shown first):"))

    if shell:
        fmt = "%s,%s,%s:%.4f\n"
    else:
        fmt = "%s, %s, %s:  %.4f\n"

    if not output or output == '-':
        for v, p in oif:
            sys.stdout.write(fmt % (p + (v, )))
    else:
        outf = file(output, 'w')
        for v, p in oif:
            outf.write(fmt % (p + (v, )))
        outf.close()
Exemple #25
0
    def plot(self, reg=None, cmap=None, norm=None, figsize=None,
             title_fontsize=8, label_fontsize=6, legend_fontsize=6,
             share_legend=False, names=None, fig_kwds=None, legend_kwds=None,
             subplots_kwds=None):
        """Plot a Raster object as a raster matrix

        Parameters
        ----------
        reg : grass.pygrass.gis.region.Region
            The region used for the plotting extent.

        cmap : str (opt), default=None
            Specify a single cmap to apply to all of the RasterLayers.
            This overrides the color map that is assigned the GRASS GIS raster.

        norm :  matplotlib.colors.Normalize (opt), default=None
            A matplotlib.colors.Normalize to apply to all of the rasters.
            This overrides any color maps that are associated to each GRASS GIS
            raster.

        figsize : tuple (opt), default=None
            Size of the resulting matplotlib.figure.Figure.

        out_shape : tuple, default=(100, 100)
            Number of rows, cols to read from the raster datasets for plotting.

        title_fontsize : any number, default=8
            Size in pts of titles.

        label_fontsize : any number, default=6
            Size in pts of axis ticklabels.

        legend_fontsize : any number, default=6
            Size in pts of legend ticklabels.

        share_legend : bool, default=False
            Optionally share a single legend between the plots. This assumes
            that all of the GRASS GIS rasters are using the same color scale,
            and the color scale used for plotting is taken from the last raster
            in the RasterStack.

        names : list (opt), default=None
            Optionally supply a list of names for each RasterLayer to override
            the default layer names for the titles.

        fig_kwds : dict (opt), default=None
            Additional arguments to pass to the matplotlib.pyplot.figure call
            when creating the figure object.

        legend_kwds : dict (opt), default=None
            Additional arguments to pass to the matplotlib.pyplot.colorbar call
            when creating the colorbar object.

        subplots_kwds : dict (opt), default=None
            Additional arguments to pass to the
            matplotlib.pyplot.subplots_adjust function. These are used to
            control the spacing and position of each subplot, and can include
            {left=None, bottom=None, right=None, top=None, wspace=None,
            hspace=None}.

        Returns
        -------
        axs : numpy.ndarray
            array of matplotlib.axes._subplots.AxesSubplot or a single
            matplotlib.axes._subplots.AxesSubplot if Raster object contains
            only a single layer.
        """
        # some checks
        if reg is None:
            raise AttributeError("argument `reg` requires a region object.")

        if norm:
            if not isinstance(norm, mpl.colors.Normalize):
                raise AttributeError(
                    "norm argument should be a \
                    matplotlib.colors.Normalize object")

        # override grass raster colors
        if cmap:
            cmaps = [cmap for i in range(self.count)]
            if norm:
                norms = [norm for i in range(self.count)]
            else:
                norms = [None for i in range(self.count)]
        else:
            scales = [convert_grass_color(name) for name in self.names]
            cmaps, norms = zip(*scales)

        # override map titles
        if names is None:
            names = []

            for src in self.iloc:
                nm = gr.info(
                    src.fullname(), flags="e", stdout_=PIPE).outputs.stdout
                title = parse_key_val(nm)["title"]
                title = title.replace('"', "")
                names.append(title)
        else:
            if len(names) != self.count:
                raise AttributeError("arguments 'names' needs to be the same "
                                     "length as the number of RasterLayer "
                                     "objects")

        if fig_kwds is None:
            fig_kwds = {}

        if legend_kwds is None:
            legend_kwds = {}

        if subplots_kwds is None:
            subplots_kwds = {}

        if figsize:
            fig_kwds["figsize"] = figsize

        # estimate required number of rows and columns in figure
        rows = int(np.sqrt(self.count))
        cols = int(math.ceil(np.sqrt(self.count)))

        if rows * cols < self.count:
            rows += 1

        fig, axs = plt.subplots(rows, cols, **fig_kwds)

        if isinstance(axs, np.ndarray):
            # axs.flat is an iterator over the row-order flattened axs array
            for ax, n, cmap, norm, name in zip(
                    axs.flat, range(self.count), cmaps, norms, names
            ):
                arr = self.read(index=n)
                arr = arr.squeeze()
                ax.set_title(name, fontsize=title_fontsize, y=1.00)
                extent = [reg.west, reg.east, reg.south, reg.north]
                im = ax.imshow(arr, extent=extent, cmap=cmap, norm=norm)

                if share_legend is False:
                    divider = make_axes_locatable(ax)

                    if "orientation" not in legend_kwds.keys():
                        legend_kwds["orientation"] = "vertical"

                    if legend_kwds["orientation"] == "vertical":
                        legend_pos = "right"

                    elif legend_kwds["orientation"] == "horizontal":
                        legend_pos = "bottom"

                    cax = divider.append_axes(legend_pos, size="10%", pad=0.1)
                    cbar = plt.colorbar(im, cax=cax, **legend_kwds)
                    cbar.ax.tick_params(labelsize=legend_fontsize)

                # hide tick labels by default when multiple rows or cols
                ax.axes.get_xaxis().set_ticklabels([])
                ax.axes.get_yaxis().set_ticklabels([])

                # show y-axis tick labels on first subplot
                if n == 0 and rows > 1:
                    ticks_loc = ax.get_yticks().tolist()
                    ax.yaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
                    ax.set_yticklabels(
                        ax.yaxis.get_majorticklocs().astype("int"),
                        fontsize=label_fontsize)

                if n == 0 and rows == 1:
                    ticks_loc = ax.get_xticks().tolist()
                    ax.xaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
                    ax.set_xticklabels(
                        ax.xaxis.get_majorticklocs().astype("int"),
                        fontsize=label_fontsize)

                    ticks_loc = ax.get_yticks().tolist()
                    ax.yaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
                    ax.set_yticklabels(
                        ax.yaxis.get_majorticklocs().astype("int"),
                        fontsize=label_fontsize)

                if rows > 1 and n == (rows * cols) - cols:
                    ticks_loc = ax.get_xticks().tolist()
                    ax.xaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
                    ax.set_xticklabels(
                        ax.xaxis.get_majorticklocs().astype("int"),
                        fontsize=label_fontsize)

            for ax in axs.flat[axs.size - 1: self.count - 1: -1]:
                ax.set_visible(False)

            if share_legend is True:
                cbar_ax = fig.add_axes([0.9, 0.15, 0.03, 0.7])
                cbar = fig.colorbar(im, cax=cbar_ax, **legend_kwds)
                cbar.ax.tick_params(labelsize=legend_fontsize)

            plt.subplots_adjust(**subplots_kwds)

        else:
            arr = self.read(index=0)
            arr = arr.squeeze()
            cmap = cmaps[0]
            norm = norms[0]
            axs.set_title(names[0], fontsize=title_fontsize, y=1.00)
            extent = [reg.west, reg.east, reg.south, reg.north]
            im = axs.imshow(arr, extent=extent, cmap=cmap, norm=norm)

            divider = make_axes_locatable(axs)

            if "orientation" not in legend_kwds.keys():
                legend_kwds["orientation"] = "vertical"

            if legend_kwds["orientation"] == "vertical":
                legend_pos = "right"

            elif legend_kwds["orientation"] == "horizontal":
                legend_pos = "bottom"

            cax = divider.append_axes(legend_pos, size="10%", pad=0.1)
            cbar = plt.colorbar(im, cax=cax, **legend_kwds)
            cbar.ax.tick_params(labelsize=legend_fontsize)

        return axs