def _getFlowacc(self,elevation,flowacc,fieldblock): """!Flowaccumulation by module r.terraflow using MFD-algorithm @return flowacc raster map with upslope contributing area per cell width """ self._debug("_getFlowacc", "started") if fieldblock: elevationfieldblock = outprefix + "elevationfieldblock" self.tmp_rast.append(elevationfieldblock) self._getElevationFieldblock(elevation, fieldblock, elevationfieldblock) elevation = elevationfieldblock raster = {} for map in ["filled", "direction", "swatershed", "tci"]: raster[map] = outprefix + map self.tmp_rast.append(raster[map]) statsfile = self._tempfile() streamdir = self._tempdir() gscript.run_command('r.terraflow', elevation = elevation, filled = raster['filled'], direction = raster['direction'], swatershed = raster['swatershed'], accumulation = flowacc, tci = raster['tci'], stats = statsfile, stream_dir=streamdir, quiet=quiet ) gscript.mapcalc("$flowacc = $flowacc / $resolution", overwrite=True, flowacc = flowacc, resolution = resolution) self._debug("_getFlowacc", "finished") return flowacc
def areaFrag(ListmapsFrag): #erodindo for i in ListmapsFrag: grass.run_command('g.region',rast=i) Lista_escalafragM,listmeters=escala_frag(i,Form1.escala_frag) #print escalafragM x=0 for a in Lista_escalafragM: meters=int(listmeters[x]) #print a grass.run_command('r.neighbors',input=i,output=i+"_ero_"+`meters`+'m',method='minimum',size=a,overwrite = True) grass.run_command('r.neighbors',input=i+"_ero_"+`meters`+'m',output=i+"_dila_"+`meters`+'m',method='maximum',size=a,overwrite = True) expressao1=i+"_FRAG"+`meters`+"m_mata=if("+i+"_dila_"+`meters`+'m'+">0,"+i+"_dila_"+`meters`+'m'+",null())" grass.mapcalc(expressao1, overwrite = True, quiet = True) expressao2=i+"_FRAG"+`meters`+"m_mata_lpo=if("+i+">=0,"+i+"_FRAG"+`meters`+"m_mata,null())" grass.mapcalc(expressao2, overwrite = True, quiet = True) grass.run_command('r.clump',input=i+"_FRAG"+`meters`+"m_mata_lpo",output=i+"_FRAG"+`meters`+"m_mata_clump",overwrite = True) grass.run_command('g.region',rast=i+"_FRAG"+`meters`+"m_mata_clump") nametxtreclass=rulesreclass(i+"_FRAG"+`meters`+"m_mata_clump",Form1.dirout) grass.run_command('r.reclass',input=i+"_FRAG"+`meters`+"m_mata_clump",output=i+"_FRAG"+`meters`+"m_mata_clump_AreaHA",rules=nametxtreclass, overwrite = True) grass.run_command('g.region',rast=i+"_FRAG"+`meters`+"m_mata_clump_AreaHA") grass.run_command('r.out.gdal',input=i+"_FRAG"+`meters`+"m_mata_clump_AreaHA",out=i+"_FRAG"+`meters`+"m_mata_clump_AreaHA.tif") x=x+1 os.remove(nametxtreclass)
def _getLsfac(self,flowacc,slope,lsfactor): """! Calculate LS-factor (topologie factor) flowaccumulation and slope are combined to LS-factor flowacc = uplslope area per unit width (measure of water flow m^2/m), slope in degrees, 22.1m is the length of standard USLE plot, 0.09 = 9 percent = 5.15 degree is slope of standard USLE plot, m and n are empirical constants, which can adjusted according to the type of flow: m=0.2..0.6, n=1.0..1.3 lower values for prevailing sheet flow, higher valus for prevailing rill flow default: m=0.4, n=1.3 (Mitasova 1999) @return raster map name with lsfac """ constant_m = options['constant_m'] # default 0.4 constant_n = options['constant_n'] # default 1.3 resolution = options['resolution'] # default 2 # is it /22.13 nach Renard et al. 1997? formula_lsfactor = "$lsfactor = (1+$m)*exp($flowacc * $resolution /22.1,$m)*exp(sin($slope)/0.09,$n)" gscript.mapcalc(formula_lsfactor, lsfactor = lsfactor, flowacc = flowacc, slope = slope, resolution=resolution, m = constant_m, n = constant_n, quiet=quiet) return lsfactor
def main(): images = options['input'].split(',') output = options['output'] count = len(images) msg = _('Do not forget to set region properly to cover all images.') gscript.warning(msg) offset = 0 offsets = [] parms = {} for n, img in enumerate(images): offsets.append(offset) parms['image%d' % (n + 1)] = img parms['offset%d' % (n + 1)] = offset offset += get_limit(img) + 1 gscript.message(_("Mosaicing %d images...") % count) gscript.mapcalc("$output = " + make_expression(1, count), output=output, **parms) # modify the color table: p = gscript.feed_command('r.colors', map=output, rules='-') for img, offset in zip(images, offsets): print(img, offset) copy_colors(p.stdin, img, offset) p.stdin.close() p.wait() gscript.message(_("Done. Raster map <%s> created.") % output) # write cmd history: gscript.raster_history(output)
def main(angle_file,w,s,rname,dist,ms): f = open(angle_file,'r') a = int(f.read()) f.close() start = a - w/2 end = a + w/2 + s gscript.run_command('g.mapset',mapset=ms) out_pattern = 'horangle_d{}'.format(dist) pos_out_pattern = '{}_pos'.format(out_pattern) neg_out_pattern = '{}_neg'.format(out_pattern) # get negative dem to use in looking for negative horizon angles gscript.mapcalc('dem_neg = -dem@PERMANENT',overwrite=True,verbose=True) # get horizon angle and potential negative horizon angle for any zero values for i in [(rname,pos_out_pattern),('dem_neg',neg_out_pattern)]: gscript.run_command('r.horizon', elevation=i[0], step=s, start=start, end=end, maxdistance=dist, output=i[1]) # get maximum angle including negatives for i in range(start,end,s): gscript.mapcalc('horangle_d{0}_{1} = horangle_d{0}_pos_{1} - horangle_d{0}_neg_{1}'.format(dist,i), overwrite=True, verbose=True) for i in [pos_out_pattern,neg_out_pattern]: gscript.run_command('g.remove', type='rast',pattern='{}*'.format(i),flags='f') gscript.run_command('g.mapset',mapset='PERMANENT')
def convert_map(output, field): """Convert imported raster map unit and format.""" # prepare for unit conversion if flags['c'] and field in ['tmin', 'tmax', 'tmean']: grass.message("Converting <%s> to degree Celcius..." % output) a = 0.1 b = 0 elif flags['k'] and field in ['tmin', 'tmax', 'tmean']: grass.message("Converting <%s> to Kelvin..." % output) a = 0.1 b = 273.15 elif flags['y'] and field == 'prec': grass.message("Converting <%s> to meter per year..." % output) a = 0.012 b = 0 elif flags['f']: grass.message("Converting <%s> to floating-point..." % output) a = 1 b = 0 else: a = None b = None # convert unit and format if a or b: grass.use_temp_region() grass.run_command('g.region', rast=output) grass.mapcalc('$output=float($output*%s+%s)' % (a, b), output=output) grass.del_temp_region()
def determine_delta_emissivity(outname, landcover_map, delta_lse_expression): """ Produce a delta emissivity map based on the FROM-GLC map covering the region of interest. """ msg = ('\n|i Determining delta land surface emissivity based on a ' 'look-up table ') if info: msg += ('| Expression:\n\n {exp}') msg = msg.format(exp=delta_lse_expression) g.message(msg) delta_lse_expression = replace_dummies(delta_lse_expression, instring=DUMMY_MAPCALC_STRING_FROM_GLC, outstring=landcover_map) delta_lse_equation = equation.format(result=outname, expression=delta_lse_expression) grass.mapcalc(delta_lse_equation, overwrite=True) if info: run('r.info', map=outname, flags='r') del(delta_lse_expression) del(delta_lse_equation) # save delta land surface emissivity map? if delta_emissivity_output: run('g.rename', raster=(outname, delta_emissivity_output))
def convert_map(output, variable): """Convert imported raster map unit and format.""" # prepare for unit conversion if flags['c'] and variable in ['tmin', 'tmax', 'tmean']: grass.message("Converting {} to degree Celcius...".format(output)) a = 0.1 b = 0 elif flags['k'] and variable in ['tmin', 'tmax', 'tmean']: grass.message("Converting {} to Kelvin...".format(output)) a = 0.1 b = 273.15 elif flags['y'] and variable == 'prec': grass.message("Converting {} to meter per year...".format(output)) a = 0.012 b = 0 elif flags['f']: grass.message("Converting {} to floating-point...".format(output)) a = 1 b = 0 else: a = None b = None # convert unit and format if a or b: grass.use_temp_region() grass.run_command('g.region', rast=output) grass.mapcalc('$output=float($output*$a+$b)', a=a, b=b, output=output, overwrite=True) grass.del_temp_region()
def estimate_column_water_vapor(outname, ratio, cwv_expression): """ *** This function is NOT used. It was part of an initial step-by-step approach, while coding and testing. Kept for future plans!? *** """ msg = "\n|i Estimating atmospheric column water vapor " msg += '| Mapcalc expression: ' msg += cwv_expression g.message(msg) cwv_expression = replace_dummies(cwv_expression, instring=DUMMY_Rji, outstring=ratio) cwv_equation = equation.format(result=outname, expression=cwv_expression) grass.mapcalc(cwv_equation, overwrite=True) if info: run('r.info', map=outname, flags='r') # save Column Water Vapor map? if cwv_output: run('g.rename', raster=(outname, cwv_output))
def estimate_ratio_ji(outname, tmp_ti_mean, tmp_tj_mean, ratio_expression): """ *** This function is NOT used. It was part of an initial step-by-step approach, while coding and testing. Kept for future plans!? *** Estimate Ratio ji for the Column Water Vapor retrieval equation. """ msg = '\n |i Estimating ratio Rji...' msg += '\n' + ratio_expression g.message(msg) ratio_expression = replace_dummies(ratio_expression, in_ti=DUMMY_Ti_MEAN, out_ti=tmp_ti_mean, in_tj=DUMMY_Tj_MEAN, out_tj=tmp_tj_mean) ratio_equation = equation.format(result=outname, expression=ratio_expression) grass.mapcalc(ratio_equation, overwrite=True) if info: run('r.info', map=outname, flags='r')
def digital_numbers_to_radiance(outname, band, radiance_expression): """ Convert Digital Number values to TOA Radiance. For details, see in Landsat8 class. Zero (0) DNs set to NULL here (not via the class' function). """ if null: msg = "\n|i Setting zero (0) Digital Numbers in {band} to NULL" msg = msg.format(band=band) g.message(msg) run('r.null', map=band, setnull=0) msg = "\n|i Rescaling {band} digital numbers to spectral radiance " msg = msg.format(band=band) if info: msg += '| Expression: ' msg += radiance_expression g.message(msg) radiance_expression = replace_dummies(radiance_expression, instring=DUMMY_MAPCALC_STRING_DN, outstring=band) radiance_equation = equation.format(result=outname, expression=radiance_expression) grass.mapcalc(radiance_equation, overwrite=True) if info: run('r.info', map=outname, flags='r') #run('r.univar', map=outname) del(radiance_expression) del(radiance_equation)
def mkHydrotopes(self): """Calculates hydrotope map for the maps in mapslist in the catchment and writes a structure file with category values of the maps in the same order plus an area and cell column """ g_run('r.mask',raster=self.subbasins,overwrite=True) # maps list ml=','.join(self.strcolumns) # take cross product of maps g_run('r.cross', overwrite=True, flags='z', input=ml, output='hydrotopes__rcross') # read basic structure file info from hydrotope map struct = readinStr(self.strcolumns) # replace all float maps with float values for intmap,floatmap in self.floatmaps.items(): # get mean hydrotope array with columns: hydrotope cats, mean catval = hydrotopeQ(floatmap, 'hydrotopes__rcross') # exchange column in strct with mean hydrotope value struct[intmap][catval['cat']] = catval['mean'] # write structure file self.writeStr(struct) # report hydrotope count and check max number of hydrotopes in subbasins nmax = np.max(np.bincount(struct[self.subbasins].astype(int))) grass.message('''%s hydrotopes created, %5.2f per subbasin on average, max. number of hydrotopes per subbasin %i ''' %(len(struct),len(struct)/len(np.unique(struct[self.subbasins])),nmax)) # start hydrotope count at 1 instead of 0 grass.mapcalc('$output=$input+1', output=self.hydrotopes, input='hydrotopes__rcross') return struct
def mkContours(self): """Make a contour map of the given DEM, in the given catchment""" # check what breaks to take, if int find nice breaks, if list take as breaks if type(self.contours) is int: interval = self.contours # get stats of DEM for nice breaks stats=grass.parse_command('r.univar',map=self.elevation,flags='g') # make nice breaks minelev = int(float(stats['min'])/interval+1)*interval maxelev = int(float(stats['max'])/interval)*interval breaks = range(minelev,maxelev+1,interval) else: breaks = self.contours if len(breaks)<2: grass.fatal('Need at least 2 contour breaks: %s \nRange of elevation: %s - %s' %(breaks,stats['min'],stats['max'])) grass.message(('Contour breaks:',str(breaks))) # form mapcalc expression and execute exp = self.contourrast+'= if(%s<%s,1)' %(self.elevation, breaks[0]) # for the first, smaller than for b in breaks: exp+='+ if(%s>=%s,1)' %(self.elevation,b) # for all greater eq than grass.mapcalc(exp, overwrite=True) grass.message(('Calculated contourmap: %s' %self.contourrast)) return
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
def _generate_harmonics(time_names, freq, prefix): """Generate (constant) rasters of harmonics t0, t1, t2, ..., t_{N-1}) where t0 = 0, t_{N-1} = 2*pi freq -- frequencies for sin() and cos() rasters prefix -- prefix for the raster names return list of names for the result rasters """ names = dict() for i in time_names: harm = dict() t = get_time(len(time_names), i) for f in freq: sin_output = prefix + 'sin' + _time_to_name(i) + _freq_to_name(f) grass.mapcalc("${out} = sin(${f} * ${t})", out=sin_output, t=t, f=f, quiet=True, overwrite=grass.overwrite()) cos_output = prefix + 'cos' + _time_to_name(i) + _freq_to_name(f) grass.mapcalc("${out} = cos(${f} * ${t})", out=cos_output, t=t, f=f, quiet=True, overwrite=grass.overwrite()) harm[f] = dict(sin=sin_output, cos=cos_output) names[i] = harm return names
def mask_data(band_filter, cfmask_filter, cloud_mask_value, file_separator): # do cleanup first grass.run_command('g.remove', type='raster', pattern='*_masked', flags='f', quiet=True) # find band1 raster maps first bands1 = grass.list_grouped('raster', pattern='*{}1*'.format(band_filter))[mapset] count = len(bands1) i = 0 for b1 in bands1: i += 1 basename = b1.split(file_separator)[0] grass.message("Processing <{0}> ({1}/{2})...".format(basename, i, count)) grass.percent(i, count, 5) # set computational region based on first band grass.run_command('g.region', raster=b1) maskname = '{}{}{}'.format(basename, file_separator, cfmask_filter) mask = grass.find_file(maskname, element='raster')['fullname'] # apply cloud mask if found if mask: grass.run_command('r.mask', flags='i', raster=maskname, maskcats=cloud_mask_value, overwrite=True, quiet=True) else: grass.warning("Mask missing for <{}>".format(basename)) # create copy of band with mask applied bands = grass.list_grouped('raster', pattern='{}{}{}*'.format(basename, file_separator, band_filter))[mapset] for b in bands: grass.mapcalc('{name}_masked={name}'.format(name=b), quiet=True, overwrite=True) grass.run_command('r.colors', map=b, color='grey.eq') # remove mask if applied if mask: grass.run_command('r.mask', flags='r', quiet=True)
def preprocessing(localpath,mapset,canr,ow): gsetup.init(gisbase, gisdbase, location, mapset) set_region(bregion,C) # Canopy Raster - 2nd test boocan = raster_exists(canr,mapset) if(boocan == False): str_error = "Canopy raster does not exist. Please run ssr_lidar.py first" return str_error print 'canopy rester exists: ',boocan # Regrid from Input Raster to Target Cell size if(demsource != dem): grass.run_command("r.resample",input=demsource,output=dem,overwrite=ow) if(canr != can): grass.run_command("r.resample",input=canr,output=can,overwrite=ow) # Slope and Aspect grass.run_command("r.slope.aspect", elevation=dem, slope=sloped, \ aspect=aspectd, prec="float", zfactor=1, overwrite=ow) grass.run_command("r.slope.aspect", elevation=can, slope=slopec, \ aspect=aspectc, prec="float", zfactor=1, overwrite=ow) # Vegetation height grass.mapcalc("$vegheight = $can - $dem", overwrite = ow, \ vegheight = vegheight, can = can, dem = dem) # Albedo albedofile = localpath+'albedo_recode.txt' grass.run_command("r.recode",flags="a",input=vegheight,output=albedo,\ rules=albedofile, overwrite=ow) # return to main str_result = 'Preprocessing: completed successfully using canopy raster: ',canr return str_result
def dn_to_reflectance(dir, dict, bands): """ Convert Digital Number values to reflectance for each band in the directory dir using the metadata values from dict See http://landsat.usgs.gov/Landsat8_Using_Product.php for details """ basedir = os.path.basename(dir) cnt = 0 for b in bands: tif_file = basedir+"_B"+str(b)+".TIF" tif_path = os.path.join(dir, tif_file) grass.message("Working on %s " % tif_path) # Import the tile rast = basedir.lower()+"_b"+str(b) grass.run_command('r.in.gdal', input=tif_path, output=rast, overwrite=True) grass.run_command('g.region', rast=rast, flags='p') rho = rast+"_reflect" # Get metadata values from the dict mult = '{:f}'.format(dict["REFLECTANCE_MULT_BAND_"+str(b)]) add = '{:f}'.format(dict["REFLECTANCE_ADD_BAND_"+str(b)]) sun = dict["SUN_ELEVATION"] zenith = '{:f}'.format(90.0-sun) # Prepare mapcalc expression expr = rho+" = ("+str(mult)+"*"+rast+"+("+str(add)+"))/cos("+zenith+")" grass.message("Calculating expression: %s" % expr) grass.mapcalc(expr, overwrite=True) grass.message("Created reflectance raster: %s" % rho) cnt += 1 grass.message("Completed %s reflectance rasters" % cnt)
def mask_clouds(qa_band, qa_pixel): """ ToDo: - a better, independent mechanism for QA. --> see also Landsat8 class. - support for multiple qa_pixel values (eg. input as a list of values) Create and apply a cloud mask based on the Quality Assessment Band (BQA.) Source: <http://landsat.usgs.gov/L8QualityAssessmentBand.php See also: http://courses.neteler.org/processing-landsat8-data-in-grass-gis-7/#Applying_the_Landsat_8_Quality_Assessment_%28QA%29_Band """ msg = ('\n|i Masking for pixel values <{qap}> ' 'in the Quality Assessment band.'.format(qap=qa_pixel)) g.message(msg) tmp_cloudmask = tmp_map_name('cloudmask') qabits_expression = 'if({band} == {pixel}, 1, null())'.format(band=qa_band, pixel=qa_pixel) cloud_masking_equation = equation.format(result=tmp_cloudmask, expression=qabits_expression) grass.mapcalc(cloud_masking_equation) r.mask(raster=tmp_cloudmask, flags='i', overwrite=True) # save for debuging #save_map(tmp_cloudmask) del(qabits_expression) del(cloud_masking_equation)
def _process_with_orig_map(self): #grass.mapcalc("$out_map = if($original_map, 0) + if($map_to_add, 0)", grass.mapcalc("$out_map = $original_map + !isnull($map_to_add)", overwrite=True, original_map = self.original_map, map_to_add = self.map_to_add, out_map = self.out_map)
def main(): options, unused = gscript.parser() input = options['input'] red = options['red'] green = options['green'] blue = options['blue'] if not gscript.find_file(input)['file']: gscript.fatal(_("Raster map <%s> not found") % input) expressions = [] maps = [] if red: expressions.append('%s = r#${input}' % red) maps.append(red) if green: expressions.append('%s = g#${input}' % green) maps.append(green) if blue: expressions.append('%s = b#${input}' % blue) maps.append(blue) expr = ';'.join(expressions) gscript.mapcalc(expr, input=input) for name in maps: gscript.run_command('r.colors', map=name, color='grey255') gscript.raster_history(name)
def radiance_to_brightness_temperature(outname, radiance, temperature_expression): """ Convert Spectral Radiance to At-Satellite Brightness Temperature. For details see Landsat8 class. """ temperature_expression = replace_dummies(temperature_expression, instring=DUMMY_MAPCALC_STRING_RADIANCE, outstring=radiance) msg = "\n|i Converting spectral radiance to at-Satellite Temperature " if info: msg += "| Expression: " + str(temperature_expression) g.message(msg) temperature_equation = equation.format(result=outname, expression=temperature_expression) grass.mapcalc(temperature_equation, overwrite=True) if info: run('r.info', map=outname, flags='r') #run('r.univar', map=outname) del(temperature_expression) del(temperature_equation)
def main(): first = options['first'] second = options['second'] output = options['output_prefix'] percent = options['percent'] mapset = grass.gisenv()['MAPSET'] if not grass.overwrite(): for ch in ['r','g','b']: map = '%s.%s' % (output, ch) if grass.find_file(map, element = 'cell', mapset = mapset)['file']: grass.fatal(_("Raster map <%s> already exists.") % map) percent = float(percent) perc_inv = 100.0 - percent frac1 = percent / 100.0 frac2 = perc_inv / 100.0 grass.message(_("Calculating the three component maps...")) template = string.Template("$$output.$ch = if(isnull($$first), $ch#$$second, if(isnull($$second), $ch#$$first, $$frac1 * $ch#$$first + $$frac2 * $ch#$$second))") cmd = [template.substitute(ch = ch) for ch in ['r','g','b']] cmd = ';'.join(cmd) grass.mapcalc(cmd, output = output, first = first, second = second, frac1 = frac1, frac2 = frac2) for ch in ['r','g','b']: map = "%s.%s" % (output, ch) grass.run_command('r.colors', map = map, color = 'grey255') grass.run_command('r.support', map = map, history="", title = "Color blend of %s and %s" % (first, second), description = "generated by r.blend") grass.run_command('r.support', map = map, history = "r.blend %s channel." % ch) grass.run_command('r.support', map = map, history = " %d%% of %s, %d%% of %s" % (percent, first, perc_inv, second)) grass.run_command('r.support', map = map, history = "") grass.run_command('r.support', map = map, history = os.environ['CMDLINE']) if flags['c']: grass.run_command('r.composite', r = '%s.r' % output, g = '%s.g' % output, b = '%s.b' % output, output = output) grass.run_command('r.support', map = output, history="", title = "Color blend of %s and %s" % (first, second), description = "generated by r.blend") grass.run_command('r.support', map = output, history = " %d%% of %s, %d%% of %s" % (percent, first, perc_inv, second)) grass.run_command('r.support', map = output, history = "") grass.run_command('r.support', map = output, history = os.environ['CMDLINE']) else: grass.message(_("Done. Use the following command to visualize the result:")) grass.message(_("d.rgb r=%s.r g=%s.g b=%s.b") % (output, output, output))
def estimate_lst(outname, t10, t11, avg_lse_map, delta_lse_map, cwv_map, lst_expression): """ Produce a Land Surface Temperature map based on a mapcalc expression returned from a SplitWindowLST object. Inputs are: - brightness temperature maps t10, t11 - column water vapor map - a temporary filename - a valid mapcalc expression """ msg = '\n|i Estimating land surface temperature ' if info: msg += "| Expression:\n" g.message(msg) if info: msg = lst_expression msg += '\n' print msg # replace the "dummy" string... if landcover_map: split_window_expression = replace_dummies(lst_expression, in_avg_lse=DUMMY_MAPCALC_STRING_AVG_LSE, out_avg_lse=avg_lse_map, in_delta_lse=DUMMY_MAPCALC_STRING_DELTA_LSE, out_delta_lse=delta_lse_map, in_cwv=DUMMY_MAPCALC_STRING_CWV, out_cwv=cwv_map, in_ti=DUMMY_MAPCALC_STRING_T10, out_ti=t10, in_tj=DUMMY_MAPCALC_STRING_T11, out_tj=t11) elif emissivity_class: split_window_expression = replace_dummies(lst_expression, in_cwv=DUMMY_MAPCALC_STRING_CWV, out_cwv=cwv_map, in_ti=DUMMY_MAPCALC_STRING_T10, out_ti=t10, in_tj=DUMMY_MAPCALC_STRING_T11, out_tj=t11) # Convert to Celsius? if celsius: split_window_expression = '({swe}) - 273.15'.format(swe=split_window_expression) split_window_equation = equation.format(result=outname, expression=split_window_expression) else: split_window_equation = equation.format(result=outname, expression=split_window_expression) grass.mapcalc(split_window_equation, overwrite=True) if info: run('r.info', map=outname, flags='r') del(split_window_expression) del(split_window_equation)
def main(): # User inputs dem = options['input'] # Elevation map out = options['friction'] # Output friction surface slope = options['slope'] # Optional output slope formula = options['formula'] # Formula # Error if no friction surface is given if not grass.find_file(dem)['name']: grass.message(_("Input raster <%s> not found") % dem) sys.exit() # If output raster 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() # Check if slope output name is specified and give error message if it needs to be overwritten but overwrite option isn't selected if not slope: slope = "tmp_slope_%d_" %os.getpid() else: if not grass.overwrite(): if grass.find_file(slope)['name']: grass.message(_("Output raster map <%s> already exists") % slope) sys.exit() # Generate slope (in percent) grass.run_command('r.slope.aspect', elevation=dem, slope=slope, format='percent') # Choose formula if formula == 'Hiker': # So-called "Hiker's formula" # Tobler W (1993) Three Presentations on Geographical Analysis and Modeling. Technical Report 93-1. California # Gorenflo LJ and Gale N (1990) Mapping Regional Settlement in information Space. Journal of Antropological Archaeology (9): 240 - 274 expression = "$outmap = 1.0 / (( 6.0 * exp(-3.5 * abs(( $slope / 100) + 0.05 ))) * 1000)" elif formula == 'Minetti': # This formula is presentedy by I. Herzog who based the formula on the physiological data by Minetti. # Herzog, I. In press. "Theory and Practice of Cost Functions." In Fusion of Cultures. Proceedings of the # XXXVIII Conference on Computer Applications and Quantitative Methods in Archaeology, CAA 2010. expression = "$outmap = 1337.8 * ($slope / 100)^6 + 278.19 * ($slope / 100)^5 - 517.39 * ($slope / 100)^4 - 78.199 * ($slope / 100)^3 + 93.419 * ($slope / 100)^2 + 19.825 * ($slope / 100) + 1.64" else: grass.message("No valid formula chosen") sys.exit() # Create friction surface try: grass.mapcalc(expression, outmap = out, slope = slope) grass.message("Friction raster <" + out + "> complete") except: grass.run_command('g.remove', rast = slope) grass.message("Unable to finish operation. Temporary slope raster deleted.") sys.exit() # Delete temporary slope map if necessary if not options['slope']: grass.run_command('g.remove', rast = slope) grass.message("All done")
def create_bins(mapa_temp): vegetacao = "vegetacao_natural_cli_rast_30m_tif" expressao1 = "veg_temp=if(" + mapa_temp + ">0," + vegetacao + ",null())" grass.mapcalc(expressao1, overwrite=True, quiet=True) grass.run_command("r.series", inpu="veg_temp," + mapa_temp, out="mapa_soma", method="sum", overwrite=True) expressao2 = "mapa_soma_int=int(mapa_soma)" grass.mapcalc(expressao2, overwrite=True, quiet=True) return "mapa_soma_int"
def create_bins(mapa_temp): vegetacao="vegetacao_natural_cli_rast_30m_tif" expressao1='veg_temp=if('+mapa_temp+'>0,'+vegetacao+',null())' grass.mapcalc(expressao1, overwrite = True, quiet = True) grass.run_command('r.series',inpu='veg_temp,'+mapa_temp,out='mapa_soma',method='sum',overwrite=True) expressao2='mapa_soma_int=int(mapa_soma)' grass.mapcalc(expressao2, overwrite = True, quiet = True) return 'mapa_soma_int'
def CreateMask(code, crop): calc = "MASK=if((USA@PERMANENT==%d),1, null())" % (code) grass.mapcalc(calc, overwrite=True, quiet=True) SetRegion("MASK") calc = "test=if(%s@PERMANENT)" % (crop) grass.mapcalc(calc, overwrite=True, quiet=True) grass.run_command("g.remove", rast="MASK", quiet=True) grass.run_command("g.rename", rast="test,MASK", quiet=True)
def calc1bands6(out, bands, k1, k2, k3, k4, k5, k6, k0=0): """ Tasseled cap transformation equation for Landsat bands """ equation = ('$out = $k1 * $in1band + $k2 * $in2band + $k3 * $in3band + ' '$k4 * $in4band + $k5 * $in5band + $k6 * $in6band + $k0') grass.mapcalc(equation, out=out, k1=k1, k2=k2, k3=k3, k4=k4, k5=k5, k6=k6, k0=k0, **bands)
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 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."))
def createAbsoluteInterval(): grass.run_command('g.region', s=0, n=80, w=0, e=120, b=0, t=50, res=10, res3=10, flags='p3', quiet=True) grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) grass.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = grass.read_command("g.tempfile", pid=1, flags='d').strip() fd = open(n1, 'w') fd.write("prec_1|2001-01-01|2001-02-01\n" "prec_2|2001-04-01|2001-05-01\n" "prec_3|2001-05-01|2001-09-01\n" "prec_4|2001-09-01|2002-01-01\n" "prec_5|2002-01-01|2002-05-01\n" "prec_6|2002-05-01|2002-07-01\n") fd.close() n2 = grass.read_command("g.tempfile", pid=2, flags='d').strip() fd = open(n2, 'w') fd.write("temp_1|2000-10-01|2001-01-01\n" "temp_2|2001-04-01|2001-05-01\n" "temp_3|2001-05-01|2001-09-01\n" "temp_4|2001-09-01|2002-01-01\n" "temp_5|2002-01-01|2002-05-01\n" "temp_6|2002-05-01|2002-07-01\n") fd.close() name1 = 'absinterval1' name2 = 'absinterval2' grass.run_command('t.unregister', type='raster', maps='prec_1,prec_2,prec_3,prec_4,prec_5,prec_6,' 'temp_1,temp_2,temp_3,temp_4,temp_5,temp_6') for name, fname in zip((name1, name2), (n1, n2)): grass.run_command('t.create', overwrite=True, type='strds', temporaltype='absolute', output=name, title="A test with input files", descr="A test with input files") grass.run_command('t.register', flags='i', input=name, file=fname, overwrite=True) return name1, name2
def main(options, flags): gisbase = os.getenv('GISBASE') if not gisbase: gs.fatal(_('$GISBASE not defined')) return 0 # Reference / sample area or points ref_rast = options['ref_rast'] ref_vect = options['ref_vect'] if ref_rast: reftype = gs.raster_info(ref_rast) if reftype['datatype'] != "CELL": gs.fatal(_("The ref_rast map must have type CELL (integer)")) if ((reftype['min'] != 0 and reftype['min'] != 1) or reftype['max'] != 1): gs.fatal(_("The ref_rast map must be a binary raster," " i.e. it should contain only values 0 and 1 or 1 only" " (now the minimum is {} and maximum is {})". format(reftype['min'], reftype['max']))) # old environmental layers & variable names REF = options['env'] REF = REF.split(',') raster_exists(REF) ipn = [z.split('@')[0] for z in REF] ipn = [x.lower() for x in ipn] # new environmental variables PROJ = options['env_proj'] if not PROJ: RP = False PROJ = REF else: RP = True PROJ = PROJ.split(',') raster_exists(PROJ) if len(PROJ) != len(REF) and len(PROJ) != 0: gs.fatal(_("The number of reference and predictor variables" " should be the same. You provided {} reference and {}" " projection variables".format(len(REF), len(PROJ)))) # output layers opl = options['output'] opc = opl + '_MES' ipi = [opl + '_' + i for i in ipn] # flags flm = flags['m'] flk = flags['k'] fln = flags['n'] fli = flags['i'] flc = flags['c'] # digits / precision digits = int(options['digits']) digits2 = pow(10, digits) # get current region settings, to compare to new ones later region_1 = gs.parse_command("g.region", flags="g") # Text for history in metadata opt2 = dict((k, v) for k, v in options.iteritems() if v) hist = ' '.join("{!s}={!r}".format(k, v) for (k, v) in opt2.iteritems()) hist = "r.mess {}".format(hist) unused, tmphist = tempfile.mkstemp() with open(tmphist, "w") as text_file: text_file.write(hist) # Create reference layer if not defined if not ref_rast and not ref_vect: ref_rast = tmpname("tmp0") gs.mapcalc("$i = if(isnull($r),null(),1)", i=ref_rast, r=REF[0], quiet=True) # Create the recode table - Reference distribution is raster citiam = gs.find_file(name='MASK', element='cell', mapset=gs.gisenv()['MAPSET']) if citiam['fullname']: rname = tmpname('tmp3') gs.mapcalc('$rname = MASK', rname=rname, quiet=True) if ref_rast: vtl = ref_rast # Create temporary layer based on reference layer tmpf0 = tmpname('tmp2') gs.mapcalc("$tmpf0 = int($vtl * 1)", vtl=vtl, tmpf0=tmpf0, quiet=True) gs.run_command("r.null", map=tmpf0, setnull=0, quiet=True) if citiam['fullname']: gs.run_command("r.mask", flags="r", quiet=True) for i in xrange(len(REF)): # Create mask based on combined MASK/reference layer gs.run_command("r.mask", raster=tmpf0, quiet=True) # Calculate the frequency distribution tmpf1 = tmpname('tmp4') gs.mapcalc("$tmpf1 = int($dignum * $inplay)", tmpf1=tmpf1, inplay=REF[i], dignum=digits2, quiet=True) p = gs.pipe_command('r.stats', quiet=True, flags='cn', input=tmpf1, sort='asc', sep=';') stval = {} for line in p.stdout: [val, count] = line.strip(os.linesep).split(';') stval[float(val)] = float(count) p.wait() sstval = sorted(stval.items(), key=operator.itemgetter(0)) sstval = np.matrix(sstval) a = np.cumsum(np.array(sstval), axis=0) b = np.sum(np.array(sstval), axis=0) c = a[:, 1] / b[1] * 100 # Remove tmp mask and set region to env_proj if needed gs.run_command("r.mask", quiet=True, flags="r") if RP: gs.use_temp_region() gs.run_command("g.region", quiet=True, raster=PROJ[0]) # get new region settings, to compare to original ones later region_2 = gs.parse_command("g.region", flags="g") # Get min and max values for recode table (based on full map) tmpf2 = tmpname('tmp5') gs.mapcalc("$tmpf2 = int($dignum * $inplay)", tmpf2=tmpf2, inplay=PROJ[i], dignum=digits2, quiet=True) d = gs.parse_command("r.univar", flags="g", map=tmpf2, quiet=True) # Create recode rules Dmin = int(d['min']) Dmax = int(d['max']) envmin = np.min(np.array(sstval), axis=0)[0] envmax = np.max(np.array(sstval), axis=0)[0] if Dmin < envmin: e1 = Dmin - 1 else: e1 = envmin - 1 if Dmax > envmax: e2 = Dmax + 1 else: e2 = envmax + 1 a1 = np.hstack([(e1), np.array(sstval.T[0])[0, :]]) a2 = np.hstack([np.array(sstval.T[0])[0, :] - 1, (e2)]) b1 = np.hstack([(0), c]) fd2, tmprule = tempfile.mkstemp(suffix=ipn[i]) with open(tmprule, "w") as text_file: for k in np.arange(0, len(b1.T)): text_file.write("%s:%s:%s\n" % (str(int(a1[k])), str(int(a2[k])), str(b1[k]))) # Create the recode layer and calculate the IES compute_ies(tmprule, ipi[i], tmpf2, envmin, envmax) gs.run_command("r.support", map=ipi[i], title="IES {}".format(REF[i]), units="0-100 (relative score", description="Environmental similarity {}" .format(REF[i]), loadhistory=tmphist) # Clean up os.close(fd2) os.remove(tmprule) # Change region back to original gs.del_temp_region() # Create the recode table - Reference distribution is vector else: vtl = ref_vect # Copy point layer and add columns for variables tmpf0 = tmpname('tmp7') gs.run_command("v.extract", quiet=True, flags="t", input=vtl, type="point", output=tmpf0) gs.run_command("v.db.addtable", quiet=True, map=tmpf0) # TODO: see if there is a more efficient way to handle the mask if citiam['fullname']: gs.run_command("r.mask", quiet=True, flags="r") # Upload raster values and get value in python as frequency table sql1 = "SELECT cat FROM {}".format(str(tmpf0)) cn = len(np.hstack(db.db_select(sql=sql1))) for m in xrange(len(REF)): # Set mask back (this means that points outside the mask will # be ignored in the computation of the frequency distribution # of the reference variabele env(m)) if citiam['fullname']: gs.run_command("g.copy", raster=[rname, 'MASK'], quiet=True) # Compute frequency distribution of variable(m) mid = str(m) laytype = gs.raster_info(REF[m])['datatype'] if laytype == 'CELL': columns = "envvar_{} integer".format(str(mid)) else: columns = "envvar_%s double precision" % mid gs.run_command("v.db.addcolumn", map=tmpf0, columns=columns, quiet=True) sql2 = "UPDATE {} SET envvar_{} = NULL".format(str(tmpf0), str(mid)) gs.run_command("db.execute", sql=sql2, quiet=True) coln = "envvar_%s" % mid gs.run_command("v.what.rast", quiet=True, map=tmpf0, layer=1, raster=REF[m], column=coln) sql3 = ("SELECT {0}, count({0}) from {1} WHERE {0} IS NOT NULL " "GROUP BY {0} ORDER BY {0}").format(coln, tmpf0) volval = np.vstack(db.db_select(sql=sql3)) volval = volval.astype(np.float, copy=False) a = np.cumsum(volval[:, 1], axis=0) b = np.sum(volval[:, 1], axis=0) c = a / b * 100 # Check for point without values if b < cn: gs.info(_("Please note that there were {} points without " "value. This is probably because they are outside " "the computational region or mask".format((cn - b)))) # Set region to env_proj layers (if different from env) and remove # mask (if set above) if citiam['fullname']: gs.run_command("r.mask", quiet=True, flags="r") if RP: gs.use_temp_region() gs.run_command("g.region", quiet=True, raster=PROJ[0]) region_2 = gs.parse_command("g.region", flags="g") # Multiply env_proj layer with dignum tmpf2 = tmpname('tmp8') gs.mapcalc("$tmpf2 = int($dignum * $inplay)", tmpf2=tmpf2, inplay=PROJ[m], dignum=digits2, quiet=True) # Calculate min and max values of sample points and raster layer envmin = int(min(volval[:, 0]) * digits2) envmax = int(max(volval[:, 0]) * digits2) Drange = gs.read_command("r.info", flags="r", map=tmpf2) Drange = str.splitlines(Drange) Drange = np.hstack([i.split('=') for i in Drange]) Dmin = int(Drange[1]) Dmax = int(Drange[3]) if Dmin < envmin: e1 = Dmin - 1 else: e1 = envmin - 1 if Dmax > envmax: e2 = Dmax + 1 else: e2 = envmax + 1 a0 = volval[:, 0] * digits2 a0 = a0.astype(np.int, copy=False) a1 = np.hstack([(e1), a0]) a2 = np.hstack([a0 - 1, (e2)]) b1 = np.hstack([(0), c]) fd3, tmprule = tempfile.mkstemp(suffix=ipn[m]) with open(tmprule, "w") as text_file: for k in np.arange(0, len(b1)): rtmp = "{}:{}:{}\n".format(str(int(a1[k])), str(int(a2[k])), str(b1[k])) text_file.write(rtmp) # Create the recode layer and calculate the IES compute_ies(tmprule, ipi[m], tmpf2, envmin, envmax) gs.run_command("r.support", map=ipi[m], title="IES {}".format(REF[m]), units="0-100 (relative score", description="Environmental similarity {}" .format(REF[m]), loadhistory=tmphist) # Clean up os.close(fd3) os.remove(tmprule) # Change region back to original gs.del_temp_region() # Calculate MESS statistics # Set region to env_proj layers (if different from env) # Note: this changes the region, to ensure the newly created layers # are actually visible to the user. This goes against normal practise # There will be a warning. if RP: gs.run_command("g.region", quiet=True, raster=PROJ[0]) # MES gs.run_command("r.series", quiet=True, output=opc, input=ipi, method="minimum") gs.write_command("r.colors", map=opc, rules='-', stdin=COLORS_MES, quiet=True) # Write layer metadata gs.run_command("r.support", map=opc, title="Areas with novel conditions", units="0-100 (relative score", description="The multivariate environmental similarity" "(MES)", loadhistory=tmphist) # Area with negative MES if fln: mod1 = "{}_novel".format(opl) gs.mapcalc("$mod1 = int(if( $opc < 0, 1, 0))", mod1=mod1, opc=opc, quiet=True) # Write category labels gs.write_command("r.category", map=mod1, rules='-', stdin=RECL_MESNEG, quiet=True) # Write layer metadata gs.run_command("r.support", map=mod1, title="Areas with novel conditions", units="-", source1="Based on {}".format(opc), description="1 = novel conditions, 0 = within range", loadhistory=tmphist) # Most dissimilar variable (MoD) if flm: tmpf4 = tmpname('tmp9') mod2 = "{}_MoD".format(opl) gs.run_command("r.series", quiet=True, output=tmpf4, input=ipi, method="min_raster") gs.mapcalc("$mod2 = int($tmpf4)", mod2=mod2, tmpf4=tmpf4, quiet=True) fd4, tmpcat = tempfile.mkstemp() with open(tmpcat, "w") as text_file: for cats in xrange(len(ipi)): text_file.write("{}:{}\n".format(str(cats), REF[cats])) gs.run_command("r.category", quiet=True, map=mod2, rules=tmpcat, separator=":") os.close(fd4) os.remove(tmpcat) # Write layer metadata gs.run_command("r.support", map=mod2, title="Most dissimilar variable (MoD)", units="-", source1="Based on {}".format(opc), description="Name of most dissimilar variable", loadhistory=tmphist) # sum(IES), where IES < 0 if flk: mod3 = "{}_SumNeg".format(opl) c0 = -0.01/digits2 gs.run_command("r.series", quiet=True, input=ipi, method="sum", range=('-inf', c0), output=mod3) gs.write_command("r.colors", map=mod3, rules='-', stdin=COLORS_MES, quiet=True) # Write layer metadata gs.run_command("r.support", map=mod3, title="Sum of negative IES values", units="-", source1="Based on {}".format(opc), description="Sum of negative IES values", loadhistory=tmphist) # Number of layers with negative values if flc: tmpf5 = tmpname('tmp10') mod4 = "{}_CountNeg".format(opl) MinMes = gs.read_command("r.info", quiet=True, flags="r", map=opc) MinMes = str.splitlines(MinMes) MinMes = float(np.hstack([i.split('=') for i in MinMes])[1]) c0 = -0.0001/digits2 gs.run_command("r.series", quiet=True, input=ipi, output=tmpf5, method="count", range=(MinMes, c0)) gs.mapcalc("$mod4 = int($tmpf5)", mod4=mod4, tmpf5=tmpf5, quiet=True) # Write layer metadata gs.run_command("r.support", map=mod4, title="Number of layers with negative values", units="-", source1="Based on {}".format(opc), description="Number of layers with negative values", loadhistory=tmphist) # Remove IES layers if fli: gs.run_command("g.remove", quiet=True, flags="f", type="raster", name=ipi) # Clean up tmp file os.remove(tmphist) gs.message(_("Finished ...\n")) if region_1 != region_2: gs.message(_("\nPlease note that the region has been changes to match" " the set of projection (env_proj) variables.\n"))
def createRelativeInterval(): grass.run_command('g.region', s=0, n=80, w=0, e=120, b=0, t=50, res=10, res3=10, flags='p3', quiet=True) grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) grass.mapcalc(exp="temp_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="temp_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="temp_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="temp_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="temp_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="temp_6 = rand(0, 650)", overwrite=True) n1 = grass.read_command("g.tempfile", pid=1, flags='d').strip() fd = open(n1, 'w') fd.write("prec_1|1|4\n" "prec_2|6|7\n" "prec_3|7|10\n" "prec_4|10|11\n" "prec_5|11|14\n" "prec_6|14|17\n") fd.close() n2 = grass.read_command("g.tempfile", pid=2, flags='d').strip() fd = open(n2, 'w') fd.write("temp_1|5|6\n" "temp_2|6|7\n" "temp_3|7|10\n" "temp_4|10|11\n" "temp_5|11|18\n" "temp_6|19|22\n") fd.close() name1 = 'relinterval1' name2 = 'relinterval2' grass.run_command('t.unregister', type='raster', maps='prec_1,prec_2,prec_3,prec_4,prec_5,prec_6,' 'temp_1,temp_2,temp_3,temp_4,temp_5,temp_6') for name, fname in zip((name1, name2), (n1, n2)): grass.run_command('t.create', overwrite=True, type='strds', temporaltype='relative', output=name, title="A test with input files", descr="A test with input files") grass.run_command('t.register', flags='i', input=name, file=fname, unit="years", overwrite=True) return name1, name2
def main(): color = options["color"] column = options["column"] layer = options["layer"] map = options["map"] range = options["range"] raster = options["raster"] rgb_column = options["rgb_column"] rules = options["rules"] flip = flags["n"] global tmp, tmp_colr, tmp_vcol pid = os.getpid() tmp = tmp_colr = tmp_vcol = None mapset = grass.gisenv()["MAPSET"] gisbase = os.getenv("GISBASE") # does map exist in CURRENT mapset? kv = grass.find_file(map, element="vector", mapset=mapset) if not kv["file"]: grass.fatal(_("Vector map <%s> not found in current mapset") % map) vector = map.split("@", 1) # sanity check mutually exclusive color options if not options["color"] and not options["raster"] and not options["rules"]: grass.fatal(_("Pick one of color, rules, or raster options")) if color: #### check the color rule is valid color_opts = os.listdir(os.path.join(gisbase, "etc", "colors")) color_opts += ["random", "grey.eq", "grey.log", "rules"] if color not in color_opts: grass.fatal( _("Invalid color rule <%s>\n") % color + _("Valid options are: %s") % " ".join(color_opts)) elif raster: if not grass.find_file(raster)["name"]: grass.fatal(_("Raster raster map <%s> not found") % raster) elif rules: if not os.access(rules, os.R_OK): grass.fatal(_("Unable to read color rules file <%s>") % rules) # column checks # check input data column cols = grass.vector_columns(map, layer=layer) if column not in cols: grass.fatal(_("Column <%s> not found") % column) ncolumn_type = cols[column]["type"] if ncolumn_type not in ["INTEGER", "DOUBLE PRECISION"]: grass.fatal( _("Column <%s> is not numeric but %s") % (column, ncolumn_type)) # check if GRASSRGB column exists, make it if it doesn't table = grass.vector_db(map)[int(layer)]["table"] if rgb_column not in cols: # RGB Column not found, create it grass.message(_("Creating column <%s>...") % rgb_column) try: grass.run_command( "v.db.addcolumn", map=map, layer=layer, column="%s varchar(11)" % rgb_column, ) except CalledModuleError: grass.fatal(_("Creating color column")) else: column_type = cols[rgb_column]["type"] if column_type not in ["CHARACTER", "TEXT"]: grass.fatal( _("Column <%s> is not of compatible type (found %s)") % (rgb_column, column_type)) else: num_chars = dict([ (v[0], int(v[2])) for v in grass.db_describe(table)["cols"] ])[rgb_column] if num_chars < 11: grass.fatal( _("Color column <%s> is not wide enough (needs 11 characters)" ), rgb_column, ) cvals = grass.vector_db_select(map, layer=int(layer), columns=column)["values"].values() # find data range if range: # order doesn't matter vals = range.split(",") else: grass.message(_("Scanning values...")) vals = [float(x[0]) for x in cvals] minval = min(vals) maxval = max(vals) grass.verbose(_("Range: [%s, %s]") % (minval, maxval)) if minval is None or maxval is None: grass.fatal(_("Scanning data range")) # setup internal region grass.use_temp_region() grass.run_command("g.region", rows=2, cols=2) tmp_colr = "tmp_colr_%d" % pid # create dummy raster map if ncolumn_type == "INTEGER": grass.mapcalc( "$tmp_colr = int(if(row() == 1, $minval, $maxval))", tmp_colr=tmp_colr, minval=minval, maxval=maxval, ) else: grass.mapcalc( "$tmp_colr = double(if(row() == 1, $minval, $maxval))", tmp_colr=tmp_colr, minval=minval, maxval=maxval, ) if color: color_cmd = {"color": color} elif raster: color_cmd = {"raster": raster} elif rules: color_cmd = {"rules": rules} if flip: flip_flag = "n" else: flip_flag = "" grass.run_command("r.colors", map=tmp_colr, flags=flip_flag, quiet=True, **color_cmd) tmp = grass.tempfile() # calculate colors and write SQL command file grass.message(_("Looking up colors...")) f = open(tmp, "w") p = grass.feed_command("r.what.color", flags="i", input=tmp_colr, stdout=f) lastval = None for v in sorted(vals): if v == lastval: continue p.stdin.write("%f\n" % v) p.stdin.close() p.wait() f.close() tmp_vcol = "%s_vcol.sql" % tmp fi = open(tmp, "r") fo = open(tmp_vcol, "w") t = string.Template( "UPDATE $table SET $rgb_column = '$colr' WHERE $column = $value;\n") found = 0 for line in fi: [value, colr] = line.split(": ") colr = colr.strip() if len(colr.split(":")) != 3: continue fo.write( t.substitute( table=table, rgb_column=rgb_column, colr=colr, column=column, value=value, )) found += 1 fi.close() fo.close() if not found: grass.fatal(_("No values found in color range")) # apply SQL commands to update the table with values grass.message(_("Writing %s colors...") % found) try: grass.run_command("db.execute", input=tmp_vcol) except CalledModuleError: grass.fatal(_("Processing SQL transaction")) if flags["s"]: vcolors = "vcolors_%d" % pid grass.run_command("g.rename", raster=(tmp_colr, vcolors), quiet=True) grass.message( _("Raster map containing color rules saved to <%s>") % vcolors) # TODO save full v.colors command line history grass.run_command( "r.support", map=vcolors, history="", source1="vector map = %s" % map, source2="column = %s" % column, title=_("Dummy raster to use as thematic vector legend"), description="generated by v.colors using r.mapcalc", ) grass.run_command( "r.support", map=vcolors, history=_("RGB saved into <%s> using <%s%s%s>") % (rgb_column, color, raster, rules), )
def main(): # lazy imports import grass.temporal as tgis # Get the options input = options["input"] elevation = options["elevation"] expdir = options["directory"] where = options["where"] null = options["null"] use_pdata = flags["p"] coorcorr = flags["c"] use_granularity = flags["g"] # Make sure the temporal database exists tgis.init() if not os.path.exists(expdir): grass.fatal(_("Export directory <%s> not found.") % expdir) os.chdir(expdir) sp = tgis.open_old_stds(input, "strds") if use_granularity: # Attention: A list of lists of maps will be returned maps = sp.get_registered_maps_as_objects_by_granularity() # Create a NULL map in case of granularity support null_map = "temporary_null_map_%i" % os.getpid() grass.mapcalc("%s = null()" % (null_map)) else: maps = sp.get_registered_maps_as_objects(where, "start_time", None) # To have scalar values with the same name, we need to copy the # raster maps using a single name map_name = "%s_%i" % (sp.base.get_name(), os.getpid()) count = 0 if maps is not None: for map in maps: if use_granularity: if map and len(map) > 0: id = map[0].get_map_id() else: id = map.get_map_id() # None ids will be replaced by NULL maps if id is None: id = null_map grass.run_command("g.copy", raster="%s,%s" % (id, map_name), overwrite=True) out_name = "%6.6i_%s.vtk" % (count, sp.base.get_name()) mflags = "" if use_pdata: mflags += "p" if coorcorr: mflags += "c" # Export the raster map with r.out.vtk try: if elevation: grass.run_command("r.out.vtk", flags=mflags, null=null, input=map_name, elevation=elevation, output=out_name, overwrite=grass.overwrite()) else: grass.run_command("r.out.vtk", flags=mflags, null=null, input=map_name, output=out_name, overwrite=grass.overwrite()) except CalledModuleError: grass.fatal(_("Unable to export raster map <%s>" % map_name)) count += 1 if use_granularity: grass.run_command("g.remove", flags='f', type='raster', name=null_map) grass.run_command("g.remove", flags='f', type='raster', name=map_name)
def createAbsolutePoint(): grass.run_command('g.region', s=0, n=80, w=0, e=120, b=0, t=50, res=10, res3=10, flags='p3', quiet=True) grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = grass.read_command("g.tempfile", pid=1, flags='d').strip() fd = open(n1, 'w') fd.write("prec_1|2001-01-01\n" "prec_2|2001-03-01\n" "prec_3|2001-04-01\n" "prec_4|2001-05-01\n" "prec_5|2001-08-01\n" "prec_6|2001-09-01\n") fd.close() name = 'abspoint' grass.run_command('t.create', overwrite=True, type='strds', temporaltype='absolute', output=name, title="A test with input files", descr="A test with input files") grass.run_command('t.register', flags='i', input=name, file=n1, overwrite=True) return name
def BuildFileISF(attributes, preferences, decision, outputMap, outputTxt): outputTxt = outputTxt + ".isf" outf = file(outputTxt, "w") outf.write("**ATTRIBUTES\n") for i in range(len(attributes)): outf.write("+ %s: (continuous)\n" % attributes[i]) outf.write("+ %s: [" % decision) value = [] value = grass.read_command("r.describe", flags="1n", map=decision) v = value.split() for i in range(len(v) - 1): outf.write("%s, " % str(v[i])) outf.write("%s]\n" % str(v[len(v) - 1])) outf.write("decision: %s\n" % decision) outf.write("\n**PREFERENCES\n") for i in range(len(attributes)): if (preferences[i] == ""): preferences[i] = "none" outf.write("%s: %s\n" % (attributes[i], preferences[i])) outf.write("%s: gain\n" % decision) if flags['n']: for i in range(len(attributes)): print "%s - convert null to 0" % str(attributes[i]) grass.run_command("r.null", map=attributes[i], null=0) outf.write("\n**EXAMPLES\n") examples = [] MATRIX = [] for i in range(len(attributes)): grass.mapcalc("rast=if(isnull(${decision})==0,${attribute},null())", rast="rast", decision=decision, attribute=attributes[i]) tmp = grass.read_command("r.stats", flags="1n", nv="?", input="rast") example = tmp.split() examples.append(example) tmp = grass.read_command("r.stats", flags="1n", nv="?", input=decision) example = tmp.split() examples.append(example) MATRIX = map(list, zip(*examples)) MATRIX = [r for r in MATRIX if not '?' in r] #remove all rows with almost one "?" MATRIX = [list(i) for i in set(tuple(j) for j in MATRIX)] #remove duplicate example for r in range(len(MATRIX)): for c in range(len(MATRIX[0])): outf.write("%s " % (MATRIX[r][c])) # outf.write("%s " % round(float(MATRIX[r][c]), 2)) outf.write("\n") outf.write("**END") outf.close() return outputTxt
def main(): ############################################### leggo variabili################################### r_elevation = options["dem"].split("@")[0] imme = options["imme"] incl = options["incl"] f4 = options["f4"] if f4 == "Natural Slope +15": f4 = 15 elif f4 == "Pre-splitting +10": f4 = 10 elif f4 == "Smooth blasting +8": f4 = 8 elif f4 == "Normal blasting or mechanical excavation 0": f4 = 0 elif f4 == "Poor blasting -8": f4 = -8 RMR = options["rmr"] prefix = options["prefix"] # SMRrib = options['SMRtoppling'] grass.message("Starting to calculate SMR index") grass.message("Waiting...") # calcolo slope ed aspect grass.run_command( "r.slope.aspect", elevation=r_elevation, slope="slopes_", format="degrees", # precision = 'float' , aspect="aspects_", zfactor="1.0", min_slope="0.0", overwrite=True, quiet=True, ) # Correggi aspect per avere: N=0 E=90 S=180 W=270 grass.mapcalc( "aspects_1 = if (aspects_ > 90, 450 - aspects_, 90 - aspects_)", overwrite=True, quiet=True, ) # calcolo A (valore assoluto)che vale SCIVOL=abs(immersdelgiunto-aspect1); RIBAL=abs(immersdelgiunto-aspect1-180) grass.mapcalc( "Asci = abs($imme - aspects_1)", imme=imme, overwrite=True, quiet=True ) grass.mapcalc("Arib = abs(Asci - 180)", overwrite=True, quiet=True) # calcolo F1 # la formula originale e' stata in parte modificata per tener conto dei valori di A compresi tra 270 e 360 sfavorevoli x la stabilita' grass.mapcalc( "F1sci1 = if(Asci > 270, 0.64 - 0.006*atan(0.1*(abs(Asci - 360) - 17)), 0)", overwrite=True, quiet=True, ) grass.mapcalc( "F1sci2 = if(Asci < 270, 0.64 - 0.006*atan(0.1*(Asci - 17)), 0)", overwrite=True, quiet=True, ) grass.mapcalc("F1sci = F1sci1 + F1sci2", overwrite=True, quiet=True) grass.mapcalc( "F1rib1 = if(Arib > 270, 0.64 - 0.006*atan(0.1*(abs(Arib - 360) - 17)), 0)", overwrite=True, quiet=True, ) grass.mapcalc( "F1rib2 = if(Arib < 270, 0.64 - 0.006*atan(0.1*(Arib - 17)), 0)", overwrite=True, quiet=True, ) grass.mapcalc("F1rib = F1rib1 + F1rib2", overwrite=True, quiet=True) # calcolo F2 (per il toppling vale sempre 1) grass.mapcalc( "F2sci = 0.56 + 0.005*(atan(0.17*abs($incl) - 5))", incl=incl, overwrite=True, quiet=True, ) # calcolo F3 grass.mapcalc( "F3sci = -30 + 0.33*atan($incl - slopes_)", incl=incl, overwrite=True, quiet=True, ) grass.mapcalc( "F3rib = -13 - 0.143*atan($incl + slopes_ - 120)", incl=incl, overwrite=True, quiet=True, ) # moltiplica F1xF2XF3 grass.mapcalc("Isciv = F1sci * F2sci * F3sci", overwrite=True, quiet=True) grass.mapcalc("Irib = F1rib * F3rib * 1", overwrite=True, quiet=True) # Calcola l'indice SMR grass.mapcalc( "$SMRsciv = Isciv + $RMR + $F4", SMRsciv=prefix + "_planar", RMR=RMR, F4=f4, quiet=True, ) grass.mapcalc( "$SMRrib = Irib + $RMR + $F4", SMRrib=prefix + "_toppling", RMR=RMR, F4=f4, quiet=True, ) ######################################################## ############################SMR_wedge################### ######################################################## imme2 = options["imme2"] incl2 = options["incl2"] grass.message("SMR index done!") if imme2 != "" and incl2 != "": # calcola trend del cuneo grass.message("Parameter set for SMR_wedge") grass.message("Starting to calculate SMR_wedge index") grass.message("Waiting...") grass.mapcalc( "T = (-tan($incl) * cos($imme)+tan($incl2)*cos($imme2))/(tan($incl)*sin($imme)-tan($incl2)*sin($imme2))", imme=imme, imme2=imme2, incl=incl, incl2=incl2, overwrite=True, quiet=True, ) grass.mapcalc("T1 = atan(T)", overwrite=True, quiet=True) # calcola plunge del cuneo P2 (sarebbe inclinazione) grass.mapcalc( "P=((sin($incl)*sin($imme)*sin($imme2-$imme))/(sin($incl)*cos($imme)*cos($incl2)-sin($incl2)*cos($imme2)*cos($incl)))*sin(T1)", imme=imme, imme2=imme2, incl=incl, incl2=incl2, overwrite=True, quiet=True, ) grass.mapcalc("P1=atan(P)", overwrite=True, quiet=True) grass.mapcalc("P2=abs(P1)", overwrite=True, quiet=True) # calcola trend del cuneo corretto (TB) sarebbe immersione grass.mapcalc("TA=if(P1<0,T1+180,T1)", overwrite=True, quiet=True) grass.mapcalc("TB=if(TA<0,TA+360,TA)", overwrite=True, quiet=True) # calcola slope e aspect # ...calcolo A (valore assoluto)che vale SCIVOL=abs(immersdelgiunto-aspect1); RIBAL=abs(immersdelgiunto-aspect1-180) grass.mapcalc("Asci=abs(TB-aspects_1)", overwrite=True, quiet=True) reclass_rules = "-360 thru 5 = 1\n5.1 thru 10 = 0.085\n10.1 thru 20 = 0.7\n20.1 thru 30 = 0.4\n30.1 thru 320 = 0.15" grass.write_command( "r.reclass", input="Asci", output="F1sci_", rules="-", stdin=reclass_rules, overwrite=True, quiet=True, ) # creo una mappa con valore dell'inclinazione grass.mapcalc("mappa=P2+slopes_*0", overwrite=True, quiet=True) # calcolo di F2 reclass_rules2 = "0 thru 20 = 0.15\n20.1 thru 30 = 0.4\n30.1 thru 35 = 0.7\n35.1 thru 45 = 0.85\n45.1 thru 90 = 1" grass.write_command( "r.reclass", input="mappa", output="F2", rules="-", stdin=reclass_rules2, overwrite=True, quiet=True, ) # Calcolo di F3 # Calcolo C che vale SCIVOL=inclgiunto - slopes; grass.mapcalc("Csci=P2-slopes_", overwrite=True, quiet=True) # Reclass per F3 scivolamento reclass_rules3 = "180 thru 9 = 0\n10 thru 0.1 = -6\n0 = -25\n-0.1 thru -9 = -50\n-10 thru -180 = -60" grass.write_command( "r.reclass", input="Csci", output="F3sci_", rules="-", overwrite=True, stdin=reclass_rules3, ) grass.mapcalc("Isciv_=F1sci_*F3sci_*F2", quiet=True) grass.mapcalc( "$SMRsciv=Isciv_+$RMR+$F4", SMRsciv=prefix + "_wedge", RMR=RMR, F4=f4, overwrite=True, quiet=True, ) grass.run_command( "g.remove", flags="f", type="raster", name=( "Asci", "Arib", "F1sci_", "F3sci_", "F2", "Csci", "P", "P1", "P2", "T", "TA", "T1", "mappa", "Isciv_", ), quiet=True, ) grass.message("SMR_wedge index done!") else: grass.message("No parameter set for SMR_wedge") ##################################################### ############################SSPC##################### ##################################################### TC = options["tc"] if TC != "": # calcolo DELTA=aspect-immersione grass.mapcalc( "delta = aspects_1 - $imme", imme=imme, overwrite=True, quiet=True ) # calcola A=cosenoDELTA grass.mapcalc("A = cos(delta)", overwrite=True, quiet=True) # calcola B=tan(inclinazione) grass.mapcalc("B = tan($incl)", incl=incl, overwrite=True, quiet=True) # calcola C=A*B grass.mapcalc("C = A * B", overwrite=True, quiet=True) # calcola AP grass.mapcalc("AP = atan(C)", overwrite=True, quiet=True) # additional condition per scivolamento (dip del pendio deve essere < di AP+5), AP deve essere < di 85 grass.mapcalc("AP1 = slopes_ - AP - 5", overwrite=True, quiet=True) grass.mapcalc("consci1 = if(AP1 > 0, 0, null())", overwrite=True, quiet=True) grass.mapcalc("consci2 = if(AP < 85, 0, null())", overwrite=True, quiet=True) # additional condition per ribaltamento (AP deve essere> di 85) grass.mapcalc("conrib = if(AP > (-85), 0, null())", overwrite=True, quiet=True) # ANALISI SCIVOLAMENTO PLANARE AP * 0.0113 grass.mapcalc("membro_sci = 0.0113 * AP", overwrite=True, quiet=True) grass.mapcalc("sci = membro_sci - $TC", TC=TC, overwrite=True, quiet=True) # se il risultato ottenuto e' minore di zero non ho cinematismo, maggiore e' il valore piu' alta sara' la propensione al distacco grass.mapcalc( "cinem_sci = if(sci >= 0, 1, null())", TC=TC, overwrite=True, quiet=True ) grass.mapcalc( "$SSPCsciv = cinem_sci * sci + consci1 + consci2", SSPCsciv=prefix + "_SSPC_planar", overwrite=True, quiet=True, ) # ANALISI RIBALTAMENTO 0.0087*(-90-AP+INCLINAZIONE) grass.mapcalc( "membro_RIB = 0.0087 * ((-90) - AP + $incl)", incl=incl, overwrite=True, quiet=True, ) grass.mapcalc("rib = membro_RIB - $TC", TC=TC, overwrite=True, quiet=True) # se il risultato ottenuto e' minore di zero non ho cinematismo, maggiore e' il valore piu' alta sara' la propensione al distacco grass.mapcalc("cinem_rib = if(rib >= 0, 1, null())", overwrite=True, quiet=True) grass.mapcalc( "$SSPCrib = cinem_rib * rib + conrib", SSPCrib=prefix + "_SSPC_toppling", overwrite=True, quiet=True, ) # processo per sostituire i valori di cella nulli con 0 (passaggio importante per trovare poi il minimo grass.run_command( "r.null", map=prefix + "_SSPC_planar", null=0, overwrite=True, quiet=True ) grass.run_command( "r.null", map=prefix + "_SSPC_toppling", null=0, overwrite=True, quiet=True ) # elimino mappe grass.run_command( "g.remove", flags="f", type="raster", name=( "slopes_", "aspects_", "aspects_1", "Asci", "Arib", "F1sci1", "F1sci2", "F1sci", "F1rib1", "F1rib2", "F1rib", "F2sci", "F3sci", "F3rib", "Isciv", "Irib", "delta", "A", "B", "C", "AP", "membro_sci", "membro_RIB", "sci", "rib", "cinem_sci", "consci1", "consci2", "conrib", "AP1", "cinem_rib", ), quiet=True, ) else: grass.run_command( "g.remove", flags="f", type="raster", name=( "slopes_", "aspects_", "aspects_1", "Asci", "Arib", "F1sci1", "F1sci2", "F1sci", "F1rib1", "F1rib2", "F1rib", "F2sci", "F3sci", "F3rib", "Isciv", "Irib", ), quiet=True, ) grass.message("Done!")
def pca(pan, ms1, ms2, ms3, out, pid, sproc): 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] # Histogram matching 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) grass.message(_("Performing inverse PCA ...")) # Get mean value of each channel 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 outr = '%s_red' % out outg = '%s_green' % out outb = '%s_blue' % out cmd1 = "$outb = 1 * round(($panmatch1 * $b1evect1) + ($pca2 * $b1evect2) + ($pca3 * $b1evect3) + $b1mean)" cmd2 = "$outg = 1 * round(($panmatch2 * $b2evect1) + ($pca2 * $b2evect2) + ($pca3 * $b2evect3) + $b2mean)" cmd3 = "$outr = 1 * round(($panmatch3 * $b3evect1) + ($pca2 * $b3evect2) + ($pca3 * $b3evect3) + $b3mean)" cmd = '\n'.join([cmd1, cmd2, cmd3]) grass.mapcalc(cmd, outb=outb, outg=outg, outr=outr, panmatch1=panmatch1, panmatch2=panmatch2, panmatch3=panmatch3, 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 = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)' % (out, panmatch1, b1evect1, pca2, b1evect2, pca3, b1evect3, b1mean), overwrite=True) pg = grass.mapcalc_start( '%s_green = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)' % (out, panmatch2, b2evect1, pca2, b2evect2, pca3, b2evect3, b2mean), overwrite=True) pr = grass.mapcalc_start( '%s_red = 1 * round((%s * %f) + (%s * %f) + (%s * %f) + %f)' % (out, panmatch3, b3evect1, pca2, b3evect2, pca3, b3evect3, b3mean), overwrite=True) pb.wait(), pg.wait(), pr.wait() try: pb.terminate(), pg.terminate(), pr.terminate() except: "" # Cleanup grass.run_command('g.remove', flags='f', quiet=True, type='raster', name='%s,%s,%s' % (panmatch1, panmatch2, panmatch3))
def main(options, flags): gisbase = os.getenv("GISBASE") if not gisbase: gs.fatal(_("$GISBASE not defined")) return 0 # Variables ref = options["reference"] REF = ref.split(",") pro = options["projection"] if pro: PRO = pro.split(",") else: PRO = REF opn = [z.split("@")[0] for z in PRO] out = options["output"] region = options["region"] flag_d = flags["d"] flag_e = flags["e"] flag_p = flags["p"] # get current region settings, to compare to new ones later regbu1 = tmpname("region") gs.parse_command("g.region", save=regbu1) # Check if region, projected layers or mask is given if region: ffile = gs.find_file(region, element="region") if not ffile: gs.fatal(_("the region {} does not exist").format(region)) if not pro and not checkmask() and not region: gs.fatal( _("You need to provide projected layers, a region, or " "a mask has to be set")) if pro and len(REF) != len(PRO): gs.fatal( _("The number of reference and projection layers need to " "be the same. Your provided %d reference and %d" "projection variables") % (len(REF), len(PRO))) # Text for history in metadata opt2 = dict((k, v) for k, v in options.items() if v) hist = " ".join("{!s}={!r}".format(k, v) for (k, v) in opt2.items()) hist = "r.exdet {}".format(hist) unused, tmphist = tempfile.mkstemp() with open(tmphist, "w") as text_file: text_file.write(hist) # Create covariance table VI = CoVar(maps=REF) # Import reference data & compute univar stats per reference layer s = len(REF) dat_ref = stat_mean = stat_min = stat_max = None layer = garray.array() for i, map in enumerate(REF): layer.read(map, null=np.nan) r, c = layer.shape if dat_ref is None: dat_ref = np.empty((s, r, c), dtype=np.double) if stat_mean is None: stat_mean = np.empty((s), dtype=np.double) if stat_min is None: stat_min = np.empty((s), dtype=np.double) if stat_max is None: stat_max = np.empty((s), dtype=np.double) stat_min[i] = np.nanmin(layer) stat_mean[i] = np.nanmean(layer) stat_max[i] = np.nanmax(layer) dat_ref[i, :, :] = layer del layer # Compute mahalanobis over full set of reference layers mahal_ref = mahal(v=dat_ref, m=stat_mean, VI=VI) mahal_ref_max = max(mahal_ref[np.isfinite(mahal_ref)]) if flag_e: mahalref = "{}_mahalref".format(out) mahal_ref.write(mapname=mahalref) gs.info(_("Mahalanobis distance map saved: {}").format(mahalref)) gs.run_command( "r.support", map=mahalref, title="Mahalanobis distance map", units="unitless", description="Mahalanobis distance map in reference " "domain", loadhistory=tmphist, ) del mahal_ref # Remove mask and set new region based on user-defined region or # otherwise based on projection layers if checkmask(): gs.run_command("r.mask", flags="r") if region: gs.run_command("g.region", region=region) gs.info(_("The region has set to the region {}").format(region)) if pro: gs.run_command("g.region", raster=PRO[0]) # TODO: only set region to PRO[0] when different from current region gs.info(_("The region has set to match the proj raster layers")) # Import projected layers in numpy array s = len(PRO) dat_pro = None layer = garray.array() for i, map in enumerate(PRO): layer.read(map, null=np.nan) r, c = layer.shape if dat_pro is None: dat_pro = np.empty((s, r, c), dtype=np.double) dat_pro[i, :, :] = layer del layer # Compute mahalanobis distance mahal_pro = mahal(v=dat_pro, m=stat_mean, VI=VI) if flag_d: mahalpro = "{}_mahalpro".format(out) mahal_pro.write(mapname=mahalpro) gs.info(_("Mahalanobis distance map saved: {}").format(mahalpro)) gs.run_command( "r.support", map=mahalpro, title="Mahalanobis distance map projection domain", units="unitless", loadhistory=tmphist, description="Mahalanobis distance map in projection " "domain estimated using covariance of refence data", ) # Compute NT1 tmplay = tmpname(out) mnames = [None] * len(REF) for i in range(len(REF)): tmpout = tmpname("exdet") # TODO: computations below sometimes result in very small negative # numbers, which are not 'real', but rather due to some differences # in handling digits in grass and python, hence second mapcalc # statement. Need to figure out how to handle this better. gs.mapcalc( "eval(" "tmp = min(($prolay - $refmin), ($refmax - $prolay),0) / " "($refmax - $refmin))\n" "$Dij = if(tmp > -0.00000000001, 0, tmp)", Dij=tmpout, prolay=PRO[i], refmin=stat_min[i], refmax=stat_max[i], quiet=True, ) mnames[i] = tmpout gs.run_command("r.series", quiet=True, input=mnames, output=tmplay, method="sum") # Compute most influential covariate (MIC) metric for NT1 if flag_p: tmpla1 = tmpname(out) gs.run_command("r.series", quiet=True, output=tmpla1, input=mnames, method="min_raster") # Compute NT2 tmpla2 = tmpname(out) nt2map = garray.array() nt2map[...] = mahal_pro / mahal_ref_max nt2map.write(mapname=tmpla2) # Compute most influential covariate (MIC) metric for NT2 if flag_p: tmpla3 = tmpname(out) laylist = [] layer = garray.array() for i, map in enumerate(opn): gs.use_temp_region() gs.run_command("g.region", quiet=True, region=regbu1) REFtmp = [x for num, x in enumerate(REF) if not num == i] stattmp = np.delete(stat_mean, i, axis=0) VItmp = CoVar(maps=REFtmp) gs.del_temp_region() dat_protmp = np.delete(dat_pro, i, axis=0) ymap = mahal(v=dat_protmp, m=stattmp, VI=VItmp) # in Mesgaran et al, the MIC2 is the max icp, but that is the # same as the minimum mahalanobis distance (ymap) # icp = (mahal_pro - ymap) / mahal_pro * 100 layer[:, :] = ymap tmpmahal = tmpname(out) layer.write(tmpmahal) laylist.append(tmpmahal) gs.run_command( "r.series", quiet=True, output=tmpla3, input=laylist, method="min_raster", overwrite=True, ) # Compute nt1, nt2, and nt1and2 novelty maps nt1 = "{}_NT1".format(out) nt2 = "{}_NT2".format(out) nt12 = "{}_NT1NT2".format(out) expr = ";".join([ "$nt12 = if($tmplay < 0, $tmplay, $tmpla2)", "$nt2 = if($tmplay >= 0, $tmpla2, null())", "$nt1 = if($tmplay < 0, $tmplay, null())", ]) gs.mapcalc(expr, nt12=nt12, nt1=nt1, nt2=nt2, tmplay=tmplay, tmpla2=tmpla2, quiet=True) # Write metadata nt1, nt2, nt1and2 maps gs.run_command( "r.support", map=nt1, units="unitless", title="Type 1 similarity", description="Type 1 similarity (NT1)", loadhistory=tmphist, ) gs.run_command( "r.support", map=nt2, units="unitless", title="Type 2 similarity", description="Type 2 similarity (NT2)", loadhistory=tmphist, ) gs.run_command( "r.support", map=nt12, units="unitless", title="Type 1 + 2 novelty / similarity", description="Type 1 + 2 similarity (NT1)", loadhistory=tmphist, ) # Compute MIC maps if flag_p: mic12 = "{}_MICNT1and2".format(out) expr = "$mic12 = if($tmplay < 0, $tmpla1, " "if($tmpla2>1, $tmpla3, -1))" gs.mapcalc( expr, tmplay=tmplay, tmpla1=tmpla1, tmpla2=tmpla2, tmpla3=tmpla3, mic12=mic12, quiet=True, ) # Write category labels to MIC maps tmpcat = tempfile.mkstemp() with open(tmpcat[1], "w") as text_file: text_file.write("-1:None\n") for cats in range(len(opn)): text_file.write("{}:{}\n".format(cats, opn[cats])) gs.run_command("r.category", quiet=True, map=mic12, rules=tmpcat[1], separator=":") os.remove(tmpcat[1]) CATV = Module("r.category", map=mic12, stdout_=PIPE).outputs.stdout Module("r.category", map=mic12, rules="-", stdin_=CATV, quiet=True) gs.run_command( "r.support", map=mic12, units="unitless", title="Most influential covariate", description="Most influential covariate (MIC) for NT1" "and NT2", loadhistory=tmphist, ) # Write color table gs.write_command("r.colors", map=nt12, rules="-", stdin=COLORS_EXDET, quiet=True) # Finalize gs.info(_("Done...."))
def test__mapcalc__if(): core.mapcalc("test_c = if(test_a > 50, 1, 0)", quite=True, overwrite=True)
def Parser_mapcalc(RULES, outputMap): "Parser to build a formula to be included in mapcalc command" i = 1 category = [] maps = [] stringa = [] for R in RULES: formula = "if(" for e in R[:-1]: #build a mapcalc formula formula += "(%s %s %.4f ) && " % (e['label'], e['sign'], e['condition']) formula += "(%s %s %.4f ),%d,null())" % (R[-1]['label'], R[-1]['sign'], R[-1]['condition'], i) mappa = "r%d_%s_%d" % (i, R[0]['type'], R[0]['class'] ) #build map name for mapcalc output category.append({ 'id': i, 'type': R[0]['type'], 'class': R[0]['class'] }) #extract category name maps.append(mappa) #extract maps name grass.mapcalc(mappa + "=" + formula) i += 1 mapstring = ",".join(maps) #make one layer for each label rule labels = ["_".join(m.split('_')[1:]) for m in maps] labels = list(set(labels)) for l in labels: print "mapping %s rule" % str(l) map_synth = [] for m in maps: if l == "_".join(m.split('_')[1:]): map_synth.append(m) if len(map_synth) > 1: grass.run_command("r.patch", overwrite='True', input=(",".join(map_synth)), output=l) else: grass.run_command("g.copy", rast=("".join(map_synth), l)) grass.run_command("r.to.vect", overwrite='True', flags='s', input=l, output=l, feature='area') grass.run_command("v.db.addcol", map=l, columns='rule varchar(25)') grass.run_command("v.db.update", map=l, column='rule', value=l) grass.run_command("v.db.addcol", map=l, columns='label varchar(25)') grass.run_command("v.db.update", map=l, column='label', value=l) mapslabels = ",".join(labels) if len(maps) > 1: grass.run_command("v.patch", overwrite='True', flags='e', input=mapslabels, output=outputMap) else: grass.run_command("g.copy", vect=(mapslabels, outputMap)) if not flags['l']: grass.run_command("g.remove", rast=mapstring) grass.run_command("g.remove", vect=mapstring) return 0
def main(): r_elevation = options["elevation"] mrvbf = options["mrvbf"].split("@")[0] mrrtf = options["mrrtf"].split("@")[0] t_slope = float(options["t_slope"]) t_pctl_v = float(options["t_pctl_v"]) t_pctl_r = float(options["t_pctl_r"]) t_vf = float(options["t_rf"]) t_rf = float(options["t_rf"]) p_slope = float(options["p_slope"]) p_pctl = float(options["p_pctl"]) moving_window_square = flags["s"] min_cells = int(options["min_cells"]) global current_region, TMP_RAST, L TMP_RAST = {} current_region = Region() # some checks if (t_slope <= 0 or t_pctl_v <= 0 or t_pctl_r <= 0 or t_vf <= 0 or t_rf <= 0 or p_slope <= 0 or p_pctl <= 0): gs.fatal("Parameter values cannot be <= 0") if min_cells < 2: gs.fatal( "Minimum number of cells in generalized DEM cannot be less than 2") if min_cells > current_region.cells: gs.fatal( "Minimum number of cells in the generalized DEM cannot exceed the ungeneralized number of cells" ) # calculate the number of levels levels = 2 remaining_cells = current_region.cells while remaining_cells >= min_cells: levels += 1 g.region(nsres=Region().nsres * 3, ewres=Region().ewres * 3) remaining_cells = Region().cells current_region.write() if levels < 3: gs.fatal( 'MRVBF algorithm requires a greater level of generalization. Reduce number of min_cells or use a larger computational region.' ) gs.message('Parameter Settings') gs.message('------------------') gs.message('min_cells = %d will result in %d generalization steps' % (min_cells, levels)) # intermediate outputs Xres_step = list() Yres_step = list() DEM = list() SLOPE = list() F = list() PCTL = list() PVF = list() PVF_RF = list() VF = list() VF_RF = list() MRVBF = list() MRRTF = list() # step 1 at base resolution ------------------------------------------------------- L = 0 TMP_RAST[L] = list() Xres_step.append(current_region.ewres) Yres_step.append(current_region.nsres) DEM.append(r_elevation) radius = 3 step_message(L, Xres_step[L], Yres_step[L], current_region.cells, t_slope) # calculation of slope (S1) and calculation of flatness (F1) (equation 2) SLOPE.append(calc_slope(DEM[L])) F.append(flatness(SLOPE[L], t_slope, p_slope)) # calculation of elevation percentile PCTL for step 1 PCTL.append(elevation_percentile(DEM[L], radius, moving_window_square)) # transform elevation percentile to local lowness for step 1 (equation 3) PVF.append(prelim_flatness_valleys(F[L], PCTL[L], t_pctl_v, p_pctl)) if mrrtf != "": PVF_RF.append(prelim_flatness_ridges(F[L], PCTL[L], t_pctl_r, p_pctl)) # calculation of the valley flatness step 1 VF1 (equation 4) VF.append(valley_flatness(PVF[L], t_vf, p_slope)) MRVBF.append(None) if mrrtf != "": VF_RF.append(valley_flatness(PVF_RF[L], t_rf, p_slope)) MRRTF.append(None) # step 2 at base scale resolution ------------------------------------------------- L = 1 TMP_RAST[L] = list() Xres_step.append(current_region.ewres) Yres_step.append(current_region.nsres) DEM.append(r_elevation) t_slope /= 2.0 radius = 6 step_message(L, Xres_step[L], Yres_step[L], current_region.cells, t_slope) # calculation of flatness for step 2 (equation 5) SLOPE.append(SLOPE[L - 1]) F.append(flatness(SLOPE[L], t_slope, p_slope)) # calculation of elevation percentile PCTL for step 2 (radius of 6 cells) PCTL.append(elevation_percentile(r_elevation, radius, moving_window_square)) # PVF for step 2 (equation 6) PVF.append(prelim_flatness_valleys(F[L], PCTL[L], t_pctl_v, p_pctl)) if mrrtf != "": PVF_RF.append(prelim_flatness_ridges(F[L], PCTL[L], t_pctl_r, p_pctl)) # calculation of the valley flatness VF for step 2 (equation 7) VF.append(valley_flatness(PVF[L], t_vf, p_slope)) if mrrtf != "": VF_RF.append(valley_flatness(PVF_RF[L], t_rf, p_slope)) # calculation of MRVBF for step 2 MRVBF.append(calc_mrvbf(VF1=VF[L - 1], VF2=VF[L], t=t_pctl_v)) if mrrtf != "": MRRTF.append(calc_mrvbf(VF1=VF_RF[L - 1], VF2=VF_RF[L], t=t_pctl_r)) # update flatness for step 2 with combined flatness from F1 and F2 (equation 10) F[L] = combined_flatness(F[L - 1], F[L]) # remaining steps ----------------------------------------------------------------- # for steps >= 2, each step uses the smoothing radius of the current step # but at the dem resolution of the previous step remaining_cells = current_region.cells while remaining_cells >= min_cells: L += 1 TMP_RAST[L] = list() t_slope /= 2.0 Xres_step.append(Xres_step[L - 1] * 3) Yres_step.append(Yres_step[L - 1] * 3) radius = 6 # delete temporary maps from L-2 for tmap in TMP_RAST[L - 2]: if len(gs.find_file(tmap)["fullname"]) > 0: g.remove(type="raster", name=tmap, flags="f", quiet=True) # coarsen resolution to resolution of previous step (step L-1) and smooth DEM if L > 2: g.region(ewres=Xres_step[L - 1], nsres=Yres_step[L - 1]) step_message(L, Xres_step[L], Yres_step[L], remaining_cells, t_slope) DEM.append(smooth_dem(DEM[L - 1])) # calculate slope at coarser resolution SLOPE.append(calc_slope(DEM[L])) # refine slope back to base resolution if L > 2: SLOPE[L] = refine(SLOPE[L], current_region, method="bilinear") # coarsen resolution to current step L and calculate PCTL g.region(ewres=Xres_step[L], nsres=Yres_step[L]) remaining_cells = Region().cells DEM[L] = refine(DEM[L], Region(), method="average") PCTL.append(elevation_percentile(DEM[L], radius, moving_window_square)) # refine PCTL to base resolution PCTL[L] = refine(PCTL[L], current_region, method="bilinear") # calculate flatness F at the base resolution F.append(flatness(SLOPE[L], t_slope, p_slope)) # update flatness with combined flatness CF from the previous step F[L] = combined_flatness(F1=F[L - 1], F2=F[L]) # calculate preliminary valley flatness index PVF at the base resolution PVF.append(prelim_flatness_valleys(F[L], PCTL[L], t_pctl_v, p_pctl)) if mrrtf != "": PVF_RF.append( prelim_flatness_ridges(F[L], PCTL[L], t_pctl_r, p_pctl)) # calculate valley flatness index VF VF.append(valley_flatness(PVF[L], t_vf, p_slope)) if mrrtf != "": VF_RF.append(valley_flatness(PVF_RF[L], t_rf, p_slope)) # calculation of MRVBF MRVBF.append(calc_mrvbf(VF1=MRVBF[L - 1], VF2=VF[L], t=t_pctl_v)) if mrrtf != "": MRRTF.append(calc_mrvbf(VF1=MRRTF[L - 1], VF2=VF_RF[L], t=t_pctl_r)) # output final MRVBF -------------------------------------------------------------- current_region.write() gs.mapcalc("$x = $y", x=mrvbf, y=MRVBF[L]) if mrrtf != "": gs.mapcalc("$x = $y", x=mrrtf, y=MRRTF[L])
def main(): # User specified variables dem = options['elevation'] neighborhood_size = options['size'] OutRaster = options['output'] notparallel = flags['p'] # Internal raster map names SlopeRaster = 'tmpSlope_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) AspectRaster = 'tmpAspect_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) xyRaster = 'tmpxyRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) zRaster = 'tmpzRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) xRaster = 'tmpxRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) yRaster = 'tmpyRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) xSumRaster = 'tmpxSumRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) ySumRaster = 'tmpySumRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) zSumRaster = 'tmpzSumRaster_' + ''.join([random.choice(string.ascii_letters + string.digits) for n in range(8)]) tmp_rast.append(SlopeRaster) tmp_rast.append(AspectRaster) tmp_rast.append(xyRaster) tmp_rast.append(zRaster) tmp_rast.append(xRaster) tmp_rast.append(yRaster) tmp_rast.append(xSumRaster) tmp_rast.append(ySumRaster) tmp_rast.append(zSumRaster) # Create Slope and Aspect rasters grass.message("Calculating slope and aspect...") grass.run_command("r.slope.aspect", elevation = dem, slope = SlopeRaster, aspect = AspectRaster, format = "degrees", precision = "FCELL", zscale = 1.0, min_slope = 0.0, quiet = True) # Calculate x y and z rasters # Note - GRASS sin/cos functions differ from ArcGIS which expects input grid in radians, whereas GRASS functions expect degrees # No need to convert slope and aspect to radians as in the original ArcGIS script if notparallel == False: # parallel version grass.message("Calculating x, y, and z rasters...") # calculate xy and z rasters using two parallel processes mapcalc_list = [] mapcalc = Module("r.mapcalc", run_=False) queue = ParallelModuleQueue(nprocs=2) mapcalc1 = copy.deepcopy(mapcalc) mapcalc_list.append(mapcalc1) m = mapcalc1(expression='{x} = float(sin({a}))'.format(x=xyRaster, a=SlopeRaster)) queue.put(m) mapcalc2 = copy.deepcopy(mapcalc) mapcalc_list.append(mapcalc2) m = mapcalc2(expression='{x} = float(cos({a}))'.format(x=zRaster, a=SlopeRaster)) queue.put(m) queue.wait() # calculate x and y rasters using two parallel processes mapcalc_list = [] mapcalc = Module("r.mapcalc", run_=False) queue = ParallelModuleQueue(nprocs=2) mapcalc1 = copy.deepcopy(mapcalc) mapcalc_list.append(mapcalc1) m = mapcalc1(expression='{x} = float(sin({a}) * {b})'.format(x=xRaster, a=AspectRaster, b=xyRaster)) queue.put(m) mapcalc2 = copy.deepcopy(mapcalc) mapcalc_list.append(mapcalc2) m = mapcalc2(expression='{x} = float(cos({a}) * {b})'.format(x=yRaster, a=AspectRaster, b=xyRaster)) queue.put(m) queue.wait() else: grass.mapcalc('{x} = float(sin({a}))'.format(x=xyRaster, a=SlopeRaster)) grass.mapcalc('{x} = float(cos({a}))'.format(x=zRaster, a=SlopeRaster)) grass.mapcalc('{x} = float(sin({a}) * {b})'.format(x=xRaster, a=AspectRaster, b=xyRaster)) grass.mapcalc('{x} = float(cos({a}) * {b})'.format(x=yRaster, a=AspectRaster, b=xyRaster)) # Calculate sums of x, y, and z rasters for selected neighborhood size if notparallel == False: # parallel version using three parallel processes grass.message("Calculating sums of x, y, and z rasters in selected neighborhood...") n_list = [] neighbors = Module("r.neighbors", overwrite=True, run_=False) queue = ParallelModuleQueue(nprocs=3) n1 = copy.deepcopy(neighbors) n_list.append(n1) n = n1(input = xRaster, output = xSumRaster, method = "average", size = neighborhood_size) queue.put(n1) n2 = copy.deepcopy(neighbors) n_list.append(n2) n = n2(input = yRaster, output = ySumRaster, method = "average", size = neighborhood_size) queue.put(n2) n3 = copy.deepcopy(neighbors) n_list.append(n3) n = n3(input = zRaster, output = zSumRaster, method = "average", size = neighborhood_size) queue.put(n3) queue.wait() else: grass.run_command("r.neighbors", input = xRaster, output = xSumRaster, method = "average", size = neighborhood_size) grass.run_command("r.neighbors", input = yRaster, output = ySumRaster, method = "average", size = neighborhood_size) grass.run_command("r.neighbors", input = zRaster, output = zSumRaster, method = "average", size = neighborhood_size) # Calculate the resultant vector and final ruggedness raster # Modified from the original script to multiple each SumRaster by the n neighborhood cells to get the sum grass.message("Calculating the final ruggedness raster...") maxValue = int(neighborhood_size) * int(neighborhood_size) grass.mapcalc('{x} = float(1-( (sqrt(({a}*{d})^2 + ({b}*{d})^2 + ({c}*{d})^2) / {e})))'.format(x=OutRaster, a=xSumRaster, b=ySumRaster, c=zSumRaster, d=maxValue, e=maxValue)) # Set the default color table grass.run_command("r.colors", flags = 'e', map = OutRaster, color = "ryb") return 0
def main(): #set options elevmap = options['elevation'] # input slope = options['slope'] # input aspect = options['aspect'] # input window = options['window'] # input strength = options['strength'] # output fisher = options['fisher'] # output compass = options['compass'] # temporary colatitude = options['colatitude'] # temporary xcos = options['xcos'] # temporary ycos = options['ycos'] # temporary zcos = options['zcos'] # temporary # check if input files exist grass.message("----") grass.message("Check if input files exist ...") find_elev = grass.find_file(elevmap, element='cell') if find_elev['name'] == "": print "Map %s not found! Aborting." % elevmap sys.exit() find_slope = grass.find_file(slope, element='cell') if find_slope['name'] == "": print "Map %s not found! Aborting." % slope sys.exit() find_aspect = grass.find_file(aspect, element='cell') if find_aspect['name'] == "": print "Map %s not found! Aborting." % aspect sys.exit() ######################################################################################################### #ACERTAR O NOME DOS ARQUIVOS - TIRAR TUDO DESDE O @!!!! ######################################################################################################### # give default names to outputs, in case the user doesn't provide them grass.message("----") grass.message("Define default output names when not defined by user ...") if strength == "": strength = "%s_vector_strength_%sx%s" % (find_elev['name'], window, window) if fisher == "": fisher = "%s_fisher_1K_%sx%s" % (find_elev['name'], window, window) ##################### # calculate compass-oriented aspect and colatitude # (temp rasters) # correct aspect angles from cartesian (GRASS default) to compass angles # if(A==0,0,if(A < 90, 90-A, 360+90-A)) grass.message("----") grass.message("Calculate compass aspect values ...") if compass == "": aspect_compass = '******' # aspect_compass = grass.tempfile() grass.mapcalc( "${out} = if(${rast1}==0,0,if(${rast1} < 90, 90-${rast1}, 360+90-${rast1}))", out=aspect_compass, rast1=aspect) else: grass.message( "Using previous calculated compass aspect values (longitude)") aspect_compass = compass # calculates colatitude (90-slope) grass.message("----") grass.message("Calculate colatitude ...") if colatitude == "": colat_angle = 'colat_angle' # colat_angle = grass.tempfile() grass.mapcalc("${out} = 90 - ${rast1}", out=colat_angle, rast1=slope) else: grass.message("Using previous calculated colatitude values") colat_angle = colatitude ##################### # calculate direction cosines # direction cosines relative to axis oriented north, east and up # direction cosine calculation according to McKean & Roering (2004), Geomorphology, 57:331-351. grass.message("----") grass.message("Calculate direction cosines ...") # X cosine if xcos == "": cosine_x = 'cosine_x' # cosine_x = grass.tempfile() grass.mapcalc("${out} = sin(${rast1}) * cos(${rast2})", out='cosine_x', rast1=aspect_compass, rast2=colat_angle) else: grass.message("Using previous calculated X direction cosine value") cosine_x = xcos # Y cosine if ycos == "": cosine_y = 'cosine_y' # cosine_y = grass.tempfile() grass.mapcalc("${out} = sin(${rast1}) * sin(${rast2})", out='cosine_y', rast1=aspect_compass, rast2=colat_angle) else: grass.message("Using previous calculated Y direction cosine values") cosine_y = ycos # Z cosine if zcos == "": cosine_z = 'cosine_z' # cosine_z = grass.tempfile() grass.mapcalc("${out} = cos(${rast1})", out='cosine_z', rast1=aspect_compass) else: grass.message("Using previous calculated Y direction cosine values") cosine_z = zcos # calculate SUM of direction cosines grass.message("----") grass.message("Calculate sum of direction cosines ...") grass.message("Calculating sum of X direction cosines ...") # sum_Xcosine = grass.tempfile() grass.run_command("r.neighbors", input=cosine_x, output='sum_Xcosine', method='sum', size=window, overwrite=True) grass.message("Calculating sum of Y direction cosines ...") # sum_Ycosine = grass.tempfile() grass.run_command("r.neighbors", input=cosine_y, output='sum_Ycosine', method='sum', size=window, overwrite=True) grass.message("Calculating sum of Z direction cosines ...") # sum_Zcosine = grass.tempfile() grass.run_command("r.neighbors", input=cosine_z, output='sum_Zcosine', method='sum', size=window, overwrite=True) ##################### # calculate vector strength grass.message("----") grass.message("Calculate vector strength ...") # print strength grass.mapcalc( "${out} = sqrt(exp(${rast1},2) + exp(${rast2},2) + exp(${rast3},2))", out=strength, rast1='sum_Xcosine', rast2='sum_Ycosine', rast3='sum_Zcosine') # calculate Inverted Fisher's K parameter # k=1/((N-1)/(N-R)) grass.message("----") grass.message("Calculate inverted Fisher's K parameter ...") w = int(window) grass.mapcalc("${out} = ($w * $w - ${rast1}) / ($w * $w - 1)", out=fisher, rast1=strength, w=int(window)) # calculations done grass.message("----") grass.message("Result maps:") grass.message(strength) grass.message(fisher) grass.message("Calculations done.") grass.message("----")
def brovey(pan, ms1, ms2, ms3, out, pid, sproc): grass.verbose(_("Using Brovey algorithm")) # pan/intensity histogram matching using linear regression grass.message( _("Pan channel/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 * round("$ms3" * "$panmatch3" / k) "$outg" = 1 * round("$ms2" * "$panmatch2" / k) "$outb" = 1 * round("$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 * round((%s * %s) / (%s + %s + %s))' % (out, ms1, panmatch1, ms1, ms2, ms3), overwrite=True) pg = grass.mapcalc_start( '%s_green = 1 * round((%s * %s) / (%s + %s + %s))' % (out, ms2, panmatch2, ms1, ms2, ms3), overwrite=True) pr = grass.mapcalc_start( '%s_red = 1 * round((%s * %s) / (%s + %s + %s))' % (out, ms3, panmatch3, ms1, ms2, ms3), overwrite=True) pb.wait(), pg.wait(), pr.wait() try: pb.terminate(), pg.terminate(), pr.terminate() except: "" # Cleanup try: grass.run_command('g.remove', flags='f', quiet=True, type='raster', name='%s,%s,%s' % (panmatch1, panmatch2, panmatch3)) except: ""
def main(): input_A = options['input_a'] input_B = options['input_b'] output = options['output'] overlap = options['overlap'] smooth_dist = options['smooth_dist'] angle = options['transition_angle'] blend_mask = options['blend_mask'] simple = not flags['s'] # smooth values of closest difference smooth_closest_difference_size = int(options['parallel_smoothing']) if smooth_closest_difference_size % 2 == 0: gscript.fatal(_("Option 'parallel_smoothing' requires odd number")) difference_reach = int(options['difference_reach']) postfix = str(os.getpid()) tmp_absdiff = "tmp_absdiff_" + postfix tmp_absdiff_smooth = "tmp_absdiff_smooth" + postfix tmp_grow = "tmp_grow" + postfix tmp_diff_overlap_1px = "tmp_diff_overlap_1px" + postfix tmp_value = "tmp_value" + postfix tmp_value_smooth = "tmp_value_smooth" + postfix tmp_stretch_dist = "tmp_stretch_dist" + postfix tmp_overlap = "tmp_overlap" + postfix TMP.extend([ tmp_absdiff, tmp_absdiff_smooth, tmp_grow, tmp_diff_overlap_1px, tmp_value, tmp_value_smooth, tmp_stretch_dist, tmp_overlap ]) gscript.run_command('r.grow.distance', flags='n', input=input_A, distance=tmp_grow) if simple and blend_mask: tmp_mask1 = "tmp_mask1" tmp_mask2 = "tmp_mask2" tmp_mask3 = "tmp_mask3" tmp_mask4 = "tmp_mask4" TMP.extend([tmp_mask1, tmp_mask2, tmp_mask3, tmp_mask4]) # derive 1-pixel wide edge of A inside of the provided mask gscript.mapcalc( "{new} = if ({dist} > 0 && {dist} <= 1.5*nsres() && ! isnull({blend_mask}), 1, null())" .format(new=tmp_mask1, dist=tmp_grow, blend_mask=blend_mask)) # create buffer around it gscript.run_command('r.grow', input=tmp_mask1, output=tmp_mask2, flags='m', radius=smooth_dist, old=1, new=1) # patch the buffer and A gscript.mapcalc( "{new} = if(! isnull({mask2}) || ! isnull({A}), 1, null())".format( A=input_A, mask2=tmp_mask2, new=tmp_mask3)) # inner grow gscript.run_command('r.grow.distance', flags='n', input=tmp_mask3, distance=tmp_mask4) # replace the distance inside the buffered area with 0 gscript.mapcalc('{new} = if(! isnull({A}), {m4}, 0)'.format( new=tmp_grow, A=input_A, m4=tmp_mask4), overwrite=True) if simple: gscript.mapcalc( "{out} = if({grow} > {smooth}, {A}, if({grow} == 0, {B}," "if (isnull({B}) && ! isnull({A}), {A}," "(1 - {grow}/{smooth}) * {B} + ({grow}/{smooth} * {A}))))".format( out=output, grow=tmp_grow, smooth=smooth_dist, A=input_A, B=input_B)) return # difference gscript.mapcalc("{new} = abs({A} - {B})".format(new=tmp_absdiff, A=input_A, B=input_B)) # take maximum difference from near cells difference_reach = (difference_reach - 1) * 2 + 1 gscript.run_command('r.neighbors', flags='c', input=tmp_absdiff, output=tmp_absdiff_smooth, method='maximum', size=difference_reach) # closest value of difference if blend_mask: # set the edge pixels to almost 0 where the mask is, results in no blending gscript.mapcalc( "{new} = if ({dist} > 0 && {dist} <= 1.5*nsres(), if(isnull({blend_mask}), {diff}, 0.00001), null())" .format(new=tmp_diff_overlap_1px, dist=tmp_grow, diff=tmp_absdiff_smooth, blend_mask=blend_mask)) else: gscript.mapcalc( "{new} = if ({dist} > 0 && {dist} <= 1.5*nsres(), {diff}, null())". format(new=tmp_diff_overlap_1px, dist=tmp_grow, diff=tmp_absdiff_smooth)) # closest value of difference gscript.run_command('r.grow.distance', input=tmp_diff_overlap_1px, value=tmp_value) # smooth closest value gscript.run_command('r.neighbors', flags='c', input=tmp_value, output=tmp_value_smooth, method='average', size=smooth_closest_difference_size) # stretch 10cm height difference per 5 meters gscript.mapcalc("{stretch} = {value}/tan({alpha})".format( stretch=tmp_stretch_dist, value=tmp_value_smooth, alpha=angle)) # spatially variable overlap width s gscript.mapcalc( "{s} = if (isnull({B}) && ! isnull({A}), 1, {dist} / {stretch})". format(s=tmp_overlap, B=input_B, A=input_A, dist=tmp_grow, stretch=tmp_stretch_dist)) # fusion gscript.mapcalc( "{fused} = if({s} >= 1, {A} , if({s} == 0, {B}, (1 - {s}) * {B} + {A} * {s}))" .format(fused=output, s=tmp_overlap, B=input_B, A=input_A)) # visualize overlap if overlap: gscript.mapcalc( "{s_trim} = if ({s}>=1, null(), if({s}<=0, null(), {s}))".format( s_trim=overlap, s=tmp_overlap))
def run_felt(scanned_elev, scanned_color, pops, eventHandler, env, **kwargs): ############################## color_threshold = 60 ############################### size_threshold = 10 superpixels = 'superpixels' superpixels_filled = 'superpixels_filled' mean_color = 'mean_color' treatments = 'treatments' treatments_old = 'treatments_old' treatments_masked = 'treatments_masked' cross_test = 'cross_test' env = get_environment(raster=scanned_elev, n='n-200') gscript.run_command('i.superpixels.slic', input=scanned_color, output=superpixels, step=8, perturb=10, compactness=1, minsize=10, memory=1000, env=env) gscript.run_command('r.fill.stats', flags='k', input=superpixels, output=superpixels_filled, distance=3, mode='mode', cells=6, env=env) gscript.mapcalc('{c} = ({r} + {g} + {b}) / 3.'.format(c=mean_color, r=scanned_color + '_r', g=scanned_color + '_g', b=scanned_color + '_b'), env=env) data = gscript.read_command('r.univar', flags='egt', separator='comma', map=mean_color, zones=superpixels_filled, env=env).strip().splitlines() data = np.genfromtxt(data, delimiter=',', skip_header=1) #zones = list(data[(data[:, 7] < color_threshold) & (data[:, 2] > size_threshold)][:, 0]) zones = list(data[(data[:, 15] < color_threshold) & (data[:, 2] > size_threshold)][:, 0]) #print "detected zones:", zones if not zones: gscript.mapcalc('{t} = null()'.format(t=treatments), env=env) condition = " || ".join(['{c} == {n}'.format(c=superpixels_filled, n=int(z)) for z in zones]) if not condition: event = updateDisplay(area=0) eventHandler.postEvent(receiver=eventHandler.pops_panel, event=event) return #gscript.mapcalc("{n} = if (({lide} > 0 || {inf} > 0) && ({c}), 1, null()) ".format(lide=lide, inf=inf, n=treatments, c=condition), env=env) gscript.mapcalc("{n} = if ({c}, 1, null()) ".format(n=treatments, c=condition), env=env) try: # is treatments_old doesn't exist, ignore this gscript.run_command('r.cross', input=[treatments, treatments_old], output=cross_test, env=env) stats = gscript.read_command('r.stats', flags='cn', input=cross_test, env=env).strip().splitlines() changed_cells = total_cells = 0 for line in stats: cat, ncells = line.split(' ') if cat in ('0', '1'): changed_cells += int(ncells) else: total_cells = int(ncells) if total_cells > 0: changed_ratio = changed_cells / float(total_cells) #print changed_ratio if changed_ratio < 0.2: return except CalledModuleError: gscript.mapcalc('{t} = null()'.format(t=treatments), env=env) gscript.mapcalc('{t} = null()'.format(t=treatments_old), env=env) event = updateDisplay(area=0) eventHandler.postEvent(receiver=eventHandler.pops_panel, event=event) # print 'changed cells:' + str(changed_cells) # print 'total cells:' + str(total_cells) gscript.run_command('g.copy', raster=[treatments, treatments_old], env=env) # price gscript.mapcalc("{n} = if ({host} > 0, {t}, null())".format(host=pops['model']['host'], t=treatments, n=treatments + '_exclude_host_tmp'), env=env) univar = gscript.parse_command('r.univar', map=treatments + '_exclude_host_tmp', flags='g', env=env) if univar and 'n' in univar: ncells = int(univar['n']) info = gscript.raster_info(treatments) res = (info['nsres'] + info['ewres'] ) / 2. area = ncells * res * res else: area = 0 event = updateDisplay(area=area) eventHandler.postEvent(receiver=eventHandler.pops_panel, event=event)
def createRelativePoint(): grass.run_command('g.region', s=0, n=80, w=0, e=120, b=0, t=50, res=10, res3=10, flags='p3', quiet=True) grass.mapcalc(exp="prec_1 = rand(0, 550)", overwrite=True) grass.mapcalc(exp="prec_2 = rand(0, 450)", overwrite=True) grass.mapcalc(exp="prec_3 = rand(0, 320)", overwrite=True) grass.mapcalc(exp="prec_4 = rand(0, 510)", overwrite=True) grass.mapcalc(exp="prec_5 = rand(0, 300)", overwrite=True) grass.mapcalc(exp="prec_6 = rand(0, 650)", overwrite=True) n1 = grass.read_command("g.tempfile", pid=1, flags='d').strip() fd = open(n1, 'w') fd.write("prec_1|1\n" "prec_2|3\n" "prec_3|5\n" "prec_4|7\n" "prec_5|11\n" "prec_6|13\n") fd.close() name = 'relpoint' grass.run_command('t.create', overwrite=True, type='strds', temporaltype='relative', output=name, title="A test with input files", descr="A test with input files") grass.run_command('t.register', unit="day", input=name, file=n1, overwrite=True) return name
def main(): tavg = options['tavg'] tmin = options['tmin'] tmax = options['tmax'] prec = options['precipitation'] outpre = options['output'] tinscale = options['tinscale'] toutscale = options['toutscale'] workers = int(options['workers']) quartals = int(options['quartals']) qstep = 12 / quartals mapset = grass.gisenv()['MAPSET'] # count input maps if len(tmin.split(',')) != 12: grass.fatal(_("12 maps with minimum temperatures are required")) if len(tmax.split(',')) != 12: grass.fatal(_("12 maps with maximum temperatures are required")) if tavg and len(tavg.split(',')) != 12: grass.fatal(_("12 maps with average temperatures are required")) if prec: if len(prec.split(',')) != 12: grass.fatal(_("12 maps with precipitation are required")) tinscale = int(tinscale) if tinscale <= 0: grass.fatal(_("Input temperature scale must be positive")) toutscale = int(toutscale) if toutscale <= 0: grass.fatal(_("Output temperature scale must be positive")) pid = os.getpid() # all temporary raster maps must follow this naming pattern tmp_pattern = "%s.*.%d" % (outpre, pid) tminl = tmin.split(',') tmaxl = tmax.split(',') ps = {} if not tavg: # calculate monthly averages from min and max grass.message(_("Calculating monthly averages from min and max")) e = "$ta = ($tmax + $tmin) / 2.0" if workers > 1: for i in range(0, 12, workers): jend = 12 - i if jend > workers: jend = workers for j in range(jend): ta = "%s.tavg%02d.%d" % (outpre, (i + j + 1), pid) ps[j] = grass.mapcalc_start(e, ta=ta, tmax=tmaxl[i + j], tmin=tminl[i + j]) for j in range(jend): ps[j].wait() else: for i in range(12): ta = "%s.tavg%02d.%d" % (outpre, (i + 1), pid) grass.mapcalc(e, ta=ta, tmax=tmaxl[i], tmin=tminl[i]) tavg = grass.read_command("g.list", quiet=True, type='raster', pattern='%s.tavg??.%d' % (outpre, pid), separator=',', mapset='.') tavg = tavg.strip('\n') tavgl = tavg.split(',') # BIO1 = Annual Mean Temperature grass.message(_("BIO1 = Annual Mean Temperature ...")) output = outpre + 'bio01.' + str(pid) grass.run_command('r.series', input=tavg, output=output, method='average') grass.mapcalc("$bio = round(double($oscale) * $input / $iscale)", bio=outpre + 'bio01', oscale=toutscale, input=output, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio01', description='BIOCLIM01: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio01', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name=output, quiet=True) # BIO2 = Mean Diurnal Range (Mean of monthly (max temp - min temp)) grass.message(_("BIO2 = Mean Diurnal Range ...")) e = "$tr = $tmax - $tmin" if workers > 1: for i in range(0, 12, workers): jend = 12 - i if jend > workers: jend = workers for j in range(jend): tr = "%s.tr%02d.%d" % (outpre, (i + j + 1), pid) ps[j] = grass.mapcalc_start(e, tr=tr, tmax=tmaxl[i + j], tmin=tminl[i + j]) for j in range(jend): ps[j].wait() else: for i in range(12): tr = "%s.tr%02d.%d" % (outpre, (i + 1), pid) grass.mapcalc(e, tr=tr, tmax=tmaxl[i], tmin=tminl[i]) tr = grass.read_command("g.list", quiet=True, type='raster', pattern='%s.tr??.%d' % (outpre, pid), separator=',', mapset='.') tr = tr.strip('\n') output = outpre + 'bio02.' + str(pid) grass.run_command('r.series', input=tr, output=output, method='average') grass.mapcalc("$bio = round(double($oscale) * $input / $iscale)", bio=outpre + 'bio02', oscale=toutscale, input=output, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio02', description='BIOCLIM02: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio02', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name=output, quiet=True) grass.run_command('g.remove', flags='f', type='raster', pattern='%s.tr??.%d' % (outpre, pid), quiet=True) # BIO4 = Temperature Seasonality (standard deviation * 100) grass.message(_("BIO4 = Temperature Seasonality ...")) output = outpre + 'bio04.' + str(pid) grass.run_command('r.series', input=tavg, output=output, method='stddev') grass.mapcalc("$bio = round(100.0 * $biotmp / $iscale * $oscale)", bio=outpre + 'bio04', biotmp=output, iscale=tinscale, oscale=toutscale) grass.run_command('r.support', map=outpre + 'bio04', description='BIOCLIM04: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio04', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name=output, quiet=True) # BIO5 = Max Temperature of Warmest Month grass.message(_("BIO5 = Max Temperature of Warmest Month ...")) output = outpre + 'bio05.' + str(pid) grass.run_command('r.series', input=tmax, output=output, method='maximum') grass.mapcalc("$bio = round(double($oscale) * $biotmp / $iscale)", bio=outpre + 'bio05', oscale=toutscale, iscale=tinscale, biotmp=output) grass.run_command('r.support', map=outpre + 'bio05', description='BIOCLIM05: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio05', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name=output, quiet=True) # BIO6 = Min Temperature of Coldest Month grass.message(_("BIO6 = Min Temperature of Coldest Month ...")) output = outpre + 'bio06.' + str(pid) grass.run_command('r.series', input=tmin, output=output, method='minimum') grass.mapcalc("$bio = round(double($oscale) * $biotmp / $iscale)", bio=outpre + 'bio06', oscale=toutscale, biotmp=output, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio06', description='BIOCLIM06: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio06', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name=output, quiet=True) # BIO7 = Temperature Annual Range (BIO5-BIO6) grass.message(_("BIO7 = Temperature Annual Range ...")) grass.mapcalc("$bio = $bio5 - $bio6", bio=outpre + 'bio07', bio5=outpre + 'bio05', bio6=outpre + 'bio06') grass.run_command('r.support', map=outpre + 'bio07', description='BIOCLIM07: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio07', history=os.environ['CMDLINE']) # BIO3 = Isothermality (BIO2/BIO7) (* 100) grass.message(_("BIO3 = Isothermality (BIO2/BIO7) ...")) grass.mapcalc("$bio = round(100.0 * $bio2 / $bio7)", bio=outpre + 'bio03', bio2=outpre + 'bio02', bio7=outpre + 'bio07') grass.run_command('r.support', map=outpre + 'bio03', description='BIOCLIM03: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio03', history=os.environ['CMDLINE']) # mean of mean for each quarter year grass.message(_("Mean temperature for each quarter year ...")) for i in range(quartals): tavgq = "%s.tavgq.%02d.%d" % (outpre, i, pid) m1 = i * qstep m2 = m1 + 1 if m2 > 11: m2 = m2 - 12 m3 = m1 + 2 if m3 > 11: m3 = m3 - 12 grass.run_command('r.series', input="%s,%s,%s" % (tavgl[m1], tavgl[m2], tavgl[m3]), output=tavgq, method='average') # BIO10 = Mean Temperature of Warmest Quarter # BIO11 = Mean Temperature of Coldest Quarter grass.message(_("BIO10 = Mean Temperature of Warmest Quarter,")) grass.message(_("BIO11 = Mean Temperature of Coldest Quarter ...")) tavgq = grass.read_command("g.list", quiet=True, type='raster', pattern='%s.tavgq.??.%d' % (outpre, pid), separator=',', mapset='.') tavgq = tavgq.strip("\n") bio10 = outpre + 'bio10.' + str(pid) bio11 = outpre + 'bio11.' + str(pid) grass.run_command('r.series', input=tavgq, output="%s,%s" % (bio10, bio11), method='maximum,minimum') grass.mapcalc("$bio = round(double($oscale) * $biotmp / $iscale)", bio=outpre + 'bio10', oscale=toutscale, biotmp=bio10, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio10', description='BIOCLIM10: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio10', history=os.environ['CMDLINE']) grass.mapcalc("$bio = round(double($oscale) * $biotmp / $iscale)", bio=outpre + 'bio11', oscale=toutscale, biotmp=bio11, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio11', description='BIOCLIM11: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio11', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', name="%s,%s" % (bio10, bio11), quiet=True) if not prec: grass.run_command('g.remove', flags='f', type='raster', pattern=tmp_pattern, quiet=True) sys.exit(1) precl = prec.split(',') # sum for each quarter year grass.message(_("Precipitation for each quarter year ...")) for i in range(quartals): precq = "%s.precq.%02d.%d" % (outpre, i + 1, pid) m1 = i * qstep m2 = m1 + 1 if m2 > 11: m2 = m2 - 12 m3 = m1 + 2 if m3 > 11: m3 = m3 - 12 grass.run_command('r.series', input="%s,%s,%s" % (precl[m1], precl[m2], precl[m3]), output=precq, method='sum') precq = grass.read_command("g.list", quiet=True, type='raster', pattern='%s.precq.??.%d' % (outpre, pid), separator=',', mapset='.') precq = precq.strip("\n") # warmest and coldest quarter warmestq = "%s.warmestq.%d" % (outpre, pid) coldestq = "%s.coldestq.%d" % (outpre, pid) grass.run_command('r.series', input=tavgq, output="%s,%s" % (warmestq, coldestq), method='max_raster,min_raster') tavgql = tavgq.split(',') # wettest and driest quarter wettestq = "%s.wettestq.%d" % (outpre, pid) driestq = "%s.driestq.%d" % (outpre, pid) grass.run_command('r.series', input=precq, output="%s,%s" % (wettestq, driestq), method='max_raster,min_raster') # BIO8 = Mean Temperature of Wettest Quarter grass.message(_("BIO8 = Mean Temperature of Wettest Quarter ...")) if quartals == 4: grass.mapcalc("$bio = round(if($wettestq == 0, $tavgq0, \ if($wettestq == 1, $tavgq1, \ if($wettestq == 2, $tavgq2, \ if($wettestq == 3, $tavgq3, null())))) \ * $oscale / $iscale)", bio=outpre + 'bio08', wettestq=wettestq, tavgq0=tavgql[0], tavgq1=tavgql[1], tavgq2=tavgql[2], tavgq3=tavgql[3], oscale=toutscale, iscale=tinscale) else: # quartals == 12 grass.mapcalc("$bio = round(if($wettestq == 0, $tavgq0, \ if($wettestq == 1, $tavgq1, \ if($wettestq == 2, $tavgq2, \ if($wettestq == 3, $tavgq3, \ if($wettestq == 4, $tavgq4, \ if($wettestq == 5, $tavgq5, \ if($wettestq == 6, $tavgq6, \ if($wettestq == 7, $tavgq7, \ if($wettestq == 8, $tavgq8, \ if($wettestq == 9, $tavgq9, \ if($wettestq == 10, $tavgq10, \ if($wettestq == 11, $tavgq11, null())))))))))))) \ * $oscale / $iscale)", bio=outpre + 'bio08', wettestq=wettestq, tavgq0=tavgql[0], tavgq1=tavgql[1], tavgq2=tavgql[2], tavgq3=tavgql[3], tavgq4=tavgql[4], tavgq5=tavgql[5], tavgq6=tavgql[6], tavgq7=tavgql[7], tavgq8=tavgql[8], tavgq9=tavgql[9], tavgq10=tavgql[10], tavgq11=tavgql[11], oscale=toutscale, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio08', description='BIOCLIM08: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio08', history=os.environ['CMDLINE']) # BIO9 = Mean Temperature of Driest Quarter grass.message(_("BIO9 = Mean Temperature of Driest Quarter ...")) if quartals == 4: grass.mapcalc("$bio = round(if($driestq == 0, $tavgq0, \ if($driestq == 1, $tavgq1, \ if($driestq == 2, $tavgq2, \ if($driestq == 3, $tavgq3, null())))) \ * $oscale / $iscale)", bio=outpre + 'bio09', driestq=driestq, tavgq0=tavgql[0], tavgq1=tavgql[1], tavgq2=tavgql[2], tavgq3=tavgql[3], oscale=toutscale, iscale=tinscale) else: # quartals == 12 grass.mapcalc("$bio = round(if($driestq == 0, $tavgq0, \ if($driestq == 1, $tavgq1, \ if($driestq == 2, $tavgq2, \ if($driestq == 3, $tavgq3, \ if($driestq == 4, $tavgq4, \ if($driestq == 5, $tavgq5, \ if($driestq == 6, $tavgq6, \ if($driestq == 7, $tavgq7, \ if($driestq == 8, $tavgq8, \ if($driestq == 9, $tavgq9, \ if($driestq == 10, $tavgq10, \ if($driestq == 11, $tavgq11, null())))))))))))) \ * $oscale / $iscale)", bio=outpre + 'bio09', driestq=driestq, tavgq0=tavgql[0], tavgq1=tavgql[1], tavgq2=tavgql[2], tavgq3=tavgql[3], tavgq4=tavgql[4], tavgq5=tavgql[5], tavgq6=tavgql[6], tavgq7=tavgql[7], tavgq8=tavgql[8], tavgq9=tavgql[9], tavgq10=tavgql[10], tavgq11=tavgql[11], oscale=toutscale, iscale=tinscale) grass.run_command('r.support', map=outpre + 'bio09', description='BIOCLIM09: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio09', history=os.environ['CMDLINE']) # BIO12 = Annual Precipitation grass.message(_("BIO12 = Annual Precipitation ...")) output = outpre + 'bio12' grass.run_command('r.series', input=prec, output=output, method='sum') grass.run_command('r.support', map=outpre + 'bio12', description='BIOCLIM12: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio12', history=os.environ['CMDLINE']) # BIO13 = Precipitation of Wettest Month # BIO14 = Precipitation of Driest Month grass.message(_("BIO13 = Precipitation of Wettest Month,")) grass.message(_("BIO14 = Precipitation of Driest Month ...")) bio13 = outpre + 'bio13' bio14 = outpre + 'bio14' grass.run_command('r.series', input=prec, output="%s,%s" % (bio13, bio14), method='maximum,minimum') grass.run_command('r.support', map=outpre + 'bio13', description='BIOCLIM13: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio13', history=os.environ['CMDLINE']) grass.run_command('r.support', map=outpre + 'bio14', description='BIOCLIM14: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio14', history=os.environ['CMDLINE']) # BIO15 = Precipitation Seasonality (Coefficient of Variation) grass.message(_("BIO15 = Precipitation Seasonality ...")) precavg = "%s.precavg.%d" % (outpre, pid) precstddev = "%s.precstddev.%d" % (outpre, pid) grass.run_command('r.series', input=prec, output="%s,%s" % (precavg, precstddev), method='average,stddev') grass.mapcalc( "$bio = if($precavg == 0, 0, round(100.0 * $precstddev / $precavg))", bio=outpre + 'bio15', precstddev=precstddev, precavg=precavg) grass.run_command('r.support', map=outpre + 'bio15', description='BIOCLIM15: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio15', history=os.environ['CMDLINE']) # BIO16 = Precipitation of Wettest Quarter # BIO17 = Precipitation of Driest Quarter grass.message(_("BIO16 = Precipitation of Wettest Quarter,")) grass.message(_("BIO17 = Precipitation of Driest Quarter ...")) bio16 = outpre + 'bio16' bio17 = outpre + 'bio17' grass.run_command('r.series', input=precq, output="%s,%s" % (bio16, bio17), method='maximum,minimum') grass.run_command('r.support', map=outpre + 'bio16', description='BIOCLIM16: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio16', history=os.environ['CMDLINE']) grass.run_command('r.support', map=outpre + 'bio17', description='BIOCLIM17: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio17', history=os.environ['CMDLINE']) precql = precq.split(',') # BIO18 = Precipitation of Warmest Quarter grass.message(_("BIO18 = Precipitation of Warmest Quarter ...")) if quartals == 4: grass.mapcalc("$bio = round(if($warmestq == 0, $precq0, \ if($warmestq == 1, $precq1, \ if($warmestq == 2, $precq2, \ if($warmestq == 3, $precq3, null())))))", bio=outpre + 'bio18', warmestq=warmestq, precq0=precql[0], precq1=precql[1], precq2=precql[2], precq3=precql[3]) else: # quartals == 12 grass.mapcalc("$bio = round(if($warmestq == 0, $precq0, \ if($warmestq == 1, $precq1, \ if($warmestq == 2, $precq2, \ if($warmestq == 3, $precq3, \ if($warmestq == 4, $precq4, \ if($warmestq == 5, $precq5, \ if($warmestq == 6, $precq6, \ if($warmestq == 7, $precq7, \ if($warmestq == 8, $precq8, \ if($warmestq == 9, $precq9, \ if($warmestq == 10, $precq10, \ if($warmestq == 11, $precq11, null())))))))))))))", bio=outpre + 'bio18', warmestq=warmestq, precq0=precql[0], precq1=precql[1], precq2=precql[2], precq3=precql[3], precq4=precql[4], precq5=precql[5], precq6=precql[6], precq7=precql[7], precq8=precql[8], precq9=precql[9], precq10=precql[10], precq11=precql[11]) grass.run_command('r.support', map=outpre + 'bio18', description='BIOCLIM18: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio18', history=os.environ['CMDLINE']) # BIO19 = Precipitation of Coldest Quarter grass.message(_("BIO19 = Precipitation of Coldest Quarter ...")) if quartals == 4: grass.mapcalc("$bio = round(if($coldestq == 0, $precq0, \ if($coldestq == 1, $precq1, \ if($coldestq == 2, $precq2, \ if($coldestq == 3, $precq3, null())))))", bio=outpre + 'bio19', coldestq=coldestq, precq0=precql[0], precq1=precql[1], precq2=precql[2], precq3=precql[3]) else: # quartals == 12 grass.mapcalc("$bio = round(if($coldestq == 0, $precq0, \ if($coldestq == 1, $precq1, \ if($coldestq == 2, $precq2, \ if($coldestq == 3, $precq3, \ if($coldestq == 4, $precq4, \ if($coldestq == 5, $precq5, \ if($coldestq == 6, $precq6, \ if($coldestq == 7, $precq7, \ if($coldestq == 8, $precq8, \ if($coldestq == 9, $precq9, \ if($coldestq == 10, $precq10, \ if($coldestq == 11, $precq11, null())))))))))))))", bio=outpre + 'bio19', coldestq=coldestq, precq0=precql[0], precq1=precql[1], precq2=precql[2], precq3=precql[3], precq4=precql[4], precq5=precql[5], precq6=precql[6], precq7=precql[7], precq8=precql[8], precq9=precql[9], precq10=precql[10], precq11=precql[11]) grass.run_command('r.support', map=outpre + 'bio19', description='BIOCLIM19: Generated by r.bioclim') grass.run_command('r.support', map=outpre + 'bio19', history=os.environ['CMDLINE']) grass.run_command('g.remove', flags='f', type='raster', pattern=tmp_pattern, quiet=True)
def main(m, o, p, q, r): # Get variables from user input years = os.getenv("GIS_OPT_number") initbdrk = os.getenv("GIS_OPT_initbdrk") outdem = os.getenv("GIS_OPT_outdem") outsoil = os.getenv("GIS_OPT_outsoil") R = os.getenv("GIS_OPT_R") K = os.getenv("GIS_OPT_K") sdensity = os.getenv("GIS_OPT_sdensity") C = os.getenv("GIS_OPT_C") kappa = os.getenv("GIS_OPT_kappa") cutoff1 = os.getenv("GIS_OPT_cutoff1") cutoff2 = os.getenv("GIS_OPT_cutoff2") cutoff3 = os.getenv("GIS_OPT_cutoff3") rain = os.getenv("GIS_OPT_rain") storms = os.getenv("GIS_OPT_storms") stormlengthsecs = float(os.getenv( "GIS_OPT_stormlength")) * 3600.00 # number of seconds in the storm stormtimet = stormlengthsecs / ( float(os.getenv("GIS_OPT_speed")) * float(r) ) # number of hydrologic instants in the storm timet = stormlengthsecs / stormtimet # length of a single hydrologic instant in seconds Kt = os.getenv("GIS_OPT_Kt") loadexp = os.getenv("GIS_OPT_loadexp") # Make some variables for temporary map names aspect = '%saspect%04d' % (p, o) flowacc = '%sflowacc%04d' % (p, o) flacclargenums = flowacc + '_largenums' flowdir = '%sflowdir%04d' % (p, o) pc = '%spc%04d' % (p, o) tc = '%stc%04d' % (p, o) meancurv = '%smeancurv%04d' % (p, o) rate = '%srate%04d' % (p, o) # Make color rules for netchange maps nccolors = tempfile.NamedTemporaryFile() nccolors.write( '100% 0 0 100\n1 blue\n0.5 indigo\n0.01 green\n0 white\n-0.01 yellow\n-0.5 orange\n-1 red\n0% 150 0 50' ) nccolors.flush() # Make color rules for soil depth maps sdcolors = tempfile.NamedTemporaryFile() sdcolors.write( '100% 0:249:47\n20% 78:151:211\n6% 194:84:171\n0% 227:174:217') sdcolors.flush() # If first iteration, use input maps. Otherwise, use maps generated from previous iterations if (o == 1): old_dem = '%s' % os.getenv("GIS_OPT_elev") old_bdrk = '%s' % os.getenv("GIS_OPT_initbdrk") old_soil = "%s%s_init" % (prefx, os.getenv("GIS_OPT_outsoil")) grass.mapcalc('${old_soil}=${old_dem}-${old_bdrk}', old_soil=old_soil, old_dem=old_dem, old_bdrk=old_bdrk) else: old_dem = '%s%s%04d' % (p, os.getenv("GIS_OPT_outdem"), m) old_bdrk = '%s%s%04d' % (p, os.getenv("GIS_OPT_outbdrk"), m) old_soil = '%s%s%04d' % (p, os.getenv("GIS_OPT_outsoil"), m) #Checking for special condition of there being only one run, and setting variables accordingly (one year runs have no numbers suffixed to the output map names) if (years == '1'): slope = '%sslope' % p qs = '%sQs' % (p) netchange = '%sED_rate' % p new_dem = '%s%s' % (p, outdem) new_soil = '%s%s' % (p, outsoil) else: slope = '%sslope%04d' % (p, o) netchange = '%sED_rate%04d' % (p, o) new_dem = '%s%s%04d' % (p, outdem, o) new_soil = '%s%s%04d' % (p, outsoil, o) if (os.getenv("GIS_FLAG_p") == "1"): grass.message('1) Calculating slope and curvatures') grass.run_command('r.slope.aspect', quiet=True, elevation=old_dem, slope=slope, pcurv=pc, tcurv=tc) else: grass.message( '\n##################################################\n\n*************************\n Year %s -- ' % o + 'step 1: calculating slope\n*************************\n') grass.run_command('r.slope.aspect', quiet=True, elevation=old_dem, aspect=aspect, slope=slope) if (os.getenv("GIS_FLAG_p") == "1"): grass.message('2) Calculating map of rainfall excess') else: grass.message( '\n*************************\n Year %s -- ' % o + 'step 2: calculating accumulated flow depths\n*************************\n' ) grass.message( 'Calculating runoff excess rates (scaled uplsope accumulated cells)' ) rainexcess = "%s_rainfall_excess_map_%04d" % (p, o) #to calculate rainfall excess, we are making a linear regression of C factor and the percentage of water that will leave the cell. A c-factor of 0.005 (mature woodland) will only allow 10% of the water to exit the cell, whereas a c-factor of 0.1 (bareland) will allow 98% of the water to leave the cell. Note that we multiply this by 100 because r.watershed will only allow integer amounts as input in it's 'flow' variable, and we want to maintain the accuracy. The large number flow accumulation will be divided by 100 after it is made, which brings the values back down to what they should be. grass.mapcalc('${rainexcess}=int(100 * ((9.26316 * ${C}) + 0.05368))', rainexcess=rainexcess, C=C) if (os.getenv("GIS_FLAG_p") == "1"): grass.message( '3) Calculating accumulated flow (in numbers of upslope cells, scaled by runoff contribution' ) grass.message( 'Calculating overland flow accumulation per cell (total vertical depth of water that passes over each cell in one storm)' ) try: grass.run_command('r.watershed', quiet=True, flags='fa', elevation=old_dem, flow=rainexcess, accumulation=flacclargenums, drainage=flowdir, convergence='5') except: grass.run_command('r.watershed', quiet=True, flags='a', elevation=old_dem, flow=rainexcess, accumulation=flacclargenums, drainage=flowdir, convergence='5') grass.mapcalc('${flowacc}=${flacclargenums}/100', flowacc=flowacc, flacclargenums=flacclargenums) if (os.getenv("GIS_FLAG_k") == "1"): pass else: grass.run_command('g.remove', quiet=True, rast=rainexcess + "," + flacclargenums) if (os.getenv("GIS_FLAG_p") == "1"): grass.message( '4) Determining number of sampling points using formula: "ln(#cells_in_input_map)*100"' ) flaccstats = grass.parse_command('r.univar', flags='g', map=flowacc) numpts = int(math.log(int(flaccstats['n'])) * 100) grass.message( '5) Creating random points and sampling values of flow accumulation, curvatures, and slope.' ) vout = '%s%s_randomly_sampled_points' % (p, numpts) grass.run_command('r.random', quiet=True, input=flowacc, cover=pc, n=numpts, vector_output=vout) grass.run_command('v.db.renamecol', quiet=True, map=vout, column='value,Flow_acc') grass.run_command('v.db.renamecol', quiet=True, map=vout, column='covervalue,Princ_curv') grass.run_command( 'v.db.addcol', quiet=True, map=vout, columns='Tang_curv double precision, Slope double precision') grass.run_command('v.what.rast', quiet=True, vector=vout, raster=tc, column="Tang_curv") grass.run_command('v.what.rast', quiet=True, vector=vout, raster=slope, column="Slope") if (os.getenv("GIS_FLAG_k") == "1"): grass.message( '--Keeping the created maps (Flow Accumulation, Slope, Principle Curvature, Tangential Curvature)' ) else: grass.message('6) Cleaning up...') grass.run_command('g.remove', quiet=True, rast=slope + "," + pc + "," + tc + "," + flowacc) grass.message( 'FINISHED. \nRandom sample points map "%s" created successfully.\n' % vout) sys.exit(0) grass.message( '\n*************************\n Year %s -- ' % o + 'step 3: calculating sediment transport rates (units variable depending upon process) \n*************************\n' ) # This step calculates the force of the flowing water at every cell on the landscape using the proper transport process law for the specific point in the flow regime. For upper hillslopes (below cutoff point 1) this done by multiplying the diffusion coeficient by the accumulated flow/cell res width. For midslopes (between cutoff 1 and 2) this is done by multiplying slope by accumulated flow with the m and n exponents set to 1. For channel catchment heads (between cutoff 2 and 3), this is done by multiplying slope by accumulated flow with the m and n exponents set to 1.6 and 1.3 respectively. For Channelized flow in streams (above cutoff 3), this is done by calculating the reach average shear stress (hydraulic radius [here estimated for a cellular landscape simply as the depth of flow] times slope times accumulated flow [cells] times gravitatiopnal acceleration of water [9806.65 newtons], all raised to the appropriate exponant for the type of transport (bedload or suspended load), and then divided by the resolution. Depth of flow is calculated as a mean "instantaneous depth" during any given rain event, here estimated by the maximum depth of an idealized unit hydrograph with base equal to the duration of the storm, and area equal to the total accumulated excess rainfall during the storm. Then finally calculates the stream power or sediment carrying capacity (qs) of the water flowing at each part of the map by multiplying the reach average shear stress (channelized flow in streams) or the estimated flow force (overland flow) by the transport coeficient (estimated by R*K*C for hillslopes or kt for streams). This is a "Transport Limited" equation, however, we add some constraints on detachment by checking to see if the sediment supply has been exhausted: if the current soil depth is 0 or negative (checking for a negative value is kind of an error trap) then we make the transport coefficient small (0.000001) to simulate erosion on bedrock. Because diffusion and USPED require 2D divergence later on, we calculate these as vectors in the X and Y directions. Stream flow only needs 1D difference, so it's calulated in the direction of flow. qsx4 = '%sQsx_diffusion%04d' % (p, o) qsy4 = '%sQsy_diffusion%04d' % (p, o) grass.mapcalc('${qsx4}=(${kappa} * sin(${slope}) * cos(${aspect}))', qsx4=qsx4, kappa=kappa, slope=slope, aspect=aspect) grass.mapcalc('${qsy4}=(${kappa} * sin(${slope}) * sin(${aspect}))', qsy4=qsy4, kappa=kappa, slope=slope, aspect=aspect) if cutoff1 == cutoff2: qsx3 = qsx4 qsy3 = qsy4 else: qsx3 = '%sQsx_sheetwash%04d' % (p, o) qsy3 = '%sQsy_sheetwash%04d' % (p, o) grass.mapcalc( '${qsx3}=( (${R}*${K}*${C}*${flowacc}*${res}*sin(${slope})) * cos(${aspect}) )', qsx3=qsx3, R=R, K=K, C=C, slope=slope, res=r, flowacc=flowacc, aspect=aspect, sdensity=sdensity) grass.mapcalc( '${qsy3}=( (${R}*${K}*${C}*${flowacc}*${res}*sin(${slope})) * sin(${aspect}) )', qsy3=qsy3, R=R, K=K, C=C, slope=slope, res=r, flowacc=flowacc, aspect=aspect, sdensity=sdensity) if cutoff2 == cutoff3: qsx2 = qsx3 qsy2 = qsy3 else: qsx2 = '%sQsx_rills%04d' % (p, o) qsy2 = '%sQsy_rills%04d' % (p, o) grass.mapcalc( '${qsx2}=( (${R}*${K}*${C}*exp((${flowacc}*${res}),1.6000000)*exp(sin(${slope}),1.3000000)) * cos(${aspect}))', qsx2=qsx2, R=R, K=K, C=C, slope=slope, res=r, flowacc=flowacc, aspect=aspect, sdensity=sdensity) grass.mapcalc( '${qsy2}=( (${R}*${K}*${C}*exp((${flowacc}*${res}),1.6000000)*exp(sin(${slope}),1.3000000)) * sin(${aspect}))', qsy2=qsy2, R=R, K=K, C=C, slope=slope, res=r, flowacc=flowacc, aspect=aspect, sdensity=sdensity) if (os.getenv("GIS_FLAG_1") == "1"): #This is the 1D version qs1 = '%sQs_1D_streams%04d' % (p, o) grass.mapcalc( '${qs1}=(${Kt} * exp(9806.65*(((${rain}/1000)*${flowacc})/(0.595*${stormtimet}))*sin(${slope}), ${loadexp}) )', qs1=qs1, flowacc=flowacc, stormtimet=stormtimet, slope=slope, loadexp=loadexp, Kt=Kt, sdensity=sdensity) else: #This is the 2D version qsx1 = '%sQsx_streams%04d' % (p, o) qsy1 = '%sQsy_streams%04d' % (p, o) grass.mapcalc( '${qsx1}=(${Kt} * exp(9806.65*(((${rain}/1000)*${flowacc})/(0.595*${stormtimet}))*sin(${slope}), ${loadexp}) ) * cos(${aspect})', qsx1=qsx1, rain=rain, flowacc=flowacc, stormtimet=stormtimet, slope=slope, loadexp=loadexp, Kt=Kt, sdensity=sdensity, aspect=aspect) grass.mapcalc( '${qsy1}=(${Kt} * exp(9806.65*(((${rain}/1000)*${flowacc})/(0.595*${stormtimet}))*sin(${slope}), ${loadexp}) ) * sin(${aspect})', qsy1=qsy1, rain=rain, flowacc=flowacc, stormtimet=stormtimet, slope=slope, loadexp=loadexp, Kt=Kt, sdensity=sdensity, aspect=aspect) grass.message( '\n*************************\n Year %s -- ' % o + 'step 4: calculating divergence/difference of sediment transport for each process and the actual amount of erosion or deposition in vertical meters/cell/year\n*************************\n\n' ) #Here is where we figure out the change in transport capacity, and thus the actual amount of erosion an deposition that would occur. There are two ways of doing this. On planar and convex surfaces (i.e., ridgetops, flats, hillslopes), it is better to take the 2D divergence of sediment flux (we use r.slope.aspect to calculate this), but on highly convex surfaces (i.e., in channels) it is better to take the 1D difference between one cell, and the cell that is immediately downstream from it. This all assumes that the system is always operating at Transport Capacity, or if it is not, then is still behaves as if it were (ie., that the actual differences in transported sediment between the cells would be proportional to the system operating at capacity). Thus, under this assumption, the divergence of capacity is equals to actual amount of sediment eroded/deposited. #This is the way we implemnt this: First calculate, we calculate the divergence/differnce for EACH of the different flow processes on the ENTIRE map (i.e., make one map per process, difference for streams, divergence for USPED and diffusion). Then, we cut out the pieces of each of these maps that correspond to the correct landforms from each specific process (based on the user-input cutoffs in flow accumulation), and patch them together into a single map (NOTE: see output unit conversions section below to see how we get all the units to line up during this process). This counters the "boundary effect" that happens when running the differential equations for divergence across the boundary of two different flow processes. Then we may still have to run a median smoother on the patched map to get rid of any latent spikes. qsxdx4 = '%sDelta_Qsx_diffusion%04d' % (p, o) qsydy4 = '%sDelta_Qsy_diffusion%04d' % (p, o) grass.run_command('r.slope.aspect', quiet=True, elevation=qsx4, dx=qsxdx4) grass.run_command('r.slope.aspect', quiet=True, elevation=qsy4, dy=qsydy4) if cutoff1 == cutoff2: qsxdx3 = qsxdx4 qsydy3 = qsydy4 else: qsxdx3 = '%sDelta_Qsx_sheetwash%04d' % (p, o) qsydy3 = '%sDelta_Qsy_sheetwash%04d' % (p, o) grass.run_command('r.slope.aspect', quiet=True, elevation=qsx3, dx=qsxdx3) grass.run_command('r.slope.aspect', quiet=True, elevation=qsy3, dy=qsydy3) if cutoff2 == cutoff3: qsxdx2 = qsxdx3 qsydy2 = qsydy3 else: qsxdx2 = '%sDelta_Qsx_rills%04d' % (p, o) qsydy2 = '%sDelta_Qsy_rills%04d' % (p, o) grass.run_command('r.slope.aspect', quiet=True, elevation=qsx2, dx=qsxdx2) grass.run_command('r.slope.aspect', quiet=True, elevation=qsy2, dy=qsydy2) if (os.getenv("GIS_FLAG_1") == "1"): #this is the 1D difference for this process qsd1 = '%sDelta_Qs_1D_streams%04d' % (p, o) grass.mapcalc( '${qsd1}=if(${flowdir} == 7, (${qs1}[-1,-1]-${qs1}), if (${flowdir} == 6, (${qs1}[-1,0]-${qs1}), if (${flowdir} == 5, (${qs1}[-1,1]-${qs1}), if (${flowdir} == 4, (${qs1}[0,1]-${qs1}), if (${flowdir} == 3, (${qs1}[1,1]-${qs1}), if (${flowdir} == 2, (${qs1}[1,0]-${qs1}), if (${flowdir} == 1, (${qs1}[1,-1]-${qs1}), if (${flowdir} == 8, (${qs1}[0,-1]-${qs1}), ${qs1}))))))))', qsd1=qsd1, flowdir=flowdir, qs1=qs1) else: #this is the 2D version qsxdx1 = '%sDelta_Qsx_streams%04d' % (p, o) qsydy1 = '%sDelta_Qsy_streams%04d' % (p, o) grass.run_command('r.slope.aspect', quiet=True, elevation=qsx1, dx=qsxdx1) grass.run_command('r.slope.aspect', quiet=True, elevation=qsy1, dy=qsydy1) #This is the smoothing routine. First we calculate the rate of Erosion and Deposition by converting the Delta QS of the different processes to vertical meters by dividing by the soil denisity (with apropriate constants to get into the correct units, see UNIT CONVERSION note below), and for streams, also expand from the storm to the year level. All units of this initial (temporary) ED_rate map will be in m/cell/year. #OUTPUT UNIT CONVERSIONS: In the case of the diffusion equation, the output units are in verticle meters of sediment per cell per year, so these will be left alone. In the case of stream flow, the output units are kg/m2/storm, so need to multiply by 1000 to get T/m2/storm, and then divide by the soil density (T/m3) to get verticle meters of sediment/cell/storm, and will be multiplied by the number of storms/year in order to get vertical meters of sediment/cell/year. In the case of USPED, the output is in T/Ha/year, so first multiply by 0.1 to get T/m2/year and then divide by soil density (T/m3) to get verticle meters of sediment/cell/year. tempnetchange1 = '%sTEMPORARY_UNSMOOTHED_ED_rate%04d' % (p, o) if (os.getenv("GIS_FLAG_1") == "1"): grass.mapcalc( '${tempnetchange1}=if(${flowacc} >= ${cutoff3}, ((${qsd1})/(${sdensity}*1000))*(${storms}*0.25*${stormtimet}), if(${flowacc} >= ${cutoff2} && ${flowacc} < ${cutoff3}, ((${qsxdx2}+${qsydy2})*0.1)/${sdensity}, if(${flowacc} >= ${cutoff1} && ${flowacc} < ${cutoff2}, ((${qsxdx3}+${qsydy3})*0.1)/${sdensity}, ${qsxdx4}+${qsydy4})))', tempnetchange1=tempnetchange1, qsd1=qsd1, qsxdx2=qsxdx2, qsydy2=qsydy2, qsxdx3=qsxdx3, qsydy3=qsydy3, qsxdx4=qsxdx4, qsydy4=qsydy4, flowacc=flowacc, cutoff1=cutoff1, cutoff2=cutoff2, cutoff3=cutoff3, sdensity=sdensity, storms=storms, stormtimet=stormtimet) else: grass.mapcalc( '${tempnetchange1}=if(${flowacc} >= ${cutoff3}, ((${qsxdx1} + ${qsydy1})/(${sdensity}*1000))*(${storms}*0.25*${stormtimet}), if(${flowacc} >= ${cutoff2} && ${flowacc} < ${cutoff3}, ((${qsxdx2}+${qsydy2})*0.1)/${sdensity}, if(${flowacc} >= ${cutoff1} && ${flowacc} < ${cutoff2}, ((${qsxdx3}+${qsydy3})*0.1)/${sdensity}, ${qsxdx4}+${qsydy4})))', tempnetchange1=tempnetchange1, qsxdx1=qsxdx1, qsydy1=qsydy1, qsxdx2=qsxdx2, qsydy2=qsydy2, qsxdx3=qsxdx3, qsydy3=qsydy3, qsxdx4=qsxdx4, qsydy4=qsydy4, flowacc=flowacc, cutoff1=cutoff1, cutoff2=cutoff2, cutoff3=cutoff3, sdensity=sdensity, storms=storms, stormtimet=stormtimet) #Make some temp maps of just erosion rate and just deposition rate so we can grab some stats from them (If Smoothing is 'no', then we'll also use these stats later in the stats file) grass.message('Running soft-knee smoothing filter...') tmperosion = p + 'tmperosion%04d' % o tmpdep = p + 'tmpdep%04d' % o grass.mapcalc( '${tmperosion}=if(${tempnetchange1} < -0, ${tempnetchange1}, null())', tmperosion=tmperosion, tempnetchange1=tempnetchange1) grass.mapcalc( '${tmpdep}=if(${tempnetchange1} > 0, ${tempnetchange1}, null())', tmpdep=tmpdep, tempnetchange1=tempnetchange1) #Grab the stats from these temp files and save them to dictionaries erosstats = grass.parse_command('r.univar', flags='ge', percentile='1', map=tmperosion) depostats = grass.parse_command('r.univar', flags='ge', percentile='99', map=tmpdep) maximum = depostats['max'] minimum = erosstats['min'] erosbreak = float(erosstats['first_quartile']) deposbreak = float(depostats['third_quartile']) scalemin = float(erosstats['percentile_1']) scalemax = float(depostats['percentile_99']) #Use the stats we gathered to do some smoothing with a hi-cut and lo-cut filter (with soft-knee limiting) of the unsmoothed ED_rate map. Values from the 1st quartile of erosion to the minimum (i.e., the very large negative numbers) will be rescaled linearly from the 1st quartile to the 1st percentile value, and values from the 3rd quartile of deposition to the maximum (i.e., the very large positiive numbers) will be rescaled linearly from the 3rd quartile to the 99th percentile value. This brings any values that were really unreasonnable as originally calculated (spikes) into the range of what the maximum values should be on a normally distrubuted dataset, but does so with out a "brick wall" style of limiting, which would make all values above some cutoff equal to a theoretical maximum. By setting both maximum cutoff point AND a "soft" scaling point, this "soft-knee" style of limiting sill retains some of the original scaling at the high ends, which allows for the smoothed value of very high cells to still be relatively higher than values in other cells that were also above the scaling cutoff, but were not originally as high as those very high cells. tempnetchange2 = '%stempry_softknee_smth_ED_rate%04d' % (p, o) grass.mapcalc( '${tempnetchange2}=graph(${tempnetchange1}, ${minimum},${scalemin}, ${erosbreak},${erosbreak}, ${deposbreak},${deposbreak}, ${maximum},${scalemax})', tempnetchange2=tempnetchange2, tempnetchange1=tempnetchange1, minimum=minimum, scalemin=scalemin, erosbreak=erosbreak, deposbreak=deposbreak, maximum=maximum, scalemax=scalemax) #Check if additional smoothing is requested. if len(os.getenv("GIS_OPT_smoothing")) is 2: grass.message('No additional modal smoothing was requested...') grass.run_command('g.rename', quiet=True, rast=tempnetchange2 + ',' + netchange) elif len(os.getenv("GIS_OPT_smoothing")) is 3: grass.message( 'Enacting additional "low" smoothing: one pass of a 3x3 modal smoothing window.' ) grass.run_command('r.neighbors', quiet=True, input=tempnetchange2, output=netchange, method='mode', size='3') grass.run_command('g.remove', quiet='True', rast=tempnetchange2) elif len(os.getenv("GIS_OPT_smoothing")) is 4: grass.message( 'Enacting additional "high" smoothing: one pass of a 5x5 modal smoothing window.' ) grass.run_command('r.neighbors', quiet=True, input=tempnetchange2, output=netchange, method='mode', size='5') grass.run_command('g.remove', quiet='True', rast=tempnetchange2) else: grass.message( 'There was a problem reading the median-smoothing variable, so maps will not be median-smoothed.' ) grass.run_command('g.rename', quiet=True, rast=tempnetchange2 + ',' + netchange) #Set the netchange map colors to the rules we've provided above grass.run_command('r.colors', quiet=True, map=netchange, rules=nccolors.name) #Grab the stats from these new smoothed netchange maps and save them to dictionaries (Note that the temporary erosiona nd deposition maps made in this step are overwriting the two temporary maps made for gathering the stats for the soft-knee limiting filter) grass.mapcalc('${tmperosion}=if(${netchange} < -0, ${netchange}, null())', tmperosion=tmperosion, netchange=netchange) grass.mapcalc('${tmpdep}=if(${netchange} > 0, ${netchange}, null())', tmpdep=tmpdep, netchange=netchange) erosstats1 = grass.parse_command('r.univar', flags='ge', map=tmperosion) depostats1 = grass.parse_command('r.univar', flags='ge', map=tmpdep) #Clean up temp maps grass.run_command('g.remove', quiet=True, rast=tmperosion + ',' + tmpdep + ',' + tempnetchange1) grass.message( '\n*************************\n Year %s -- ' % o + 'step 5: calculating terrain evolution and new soil depths\n *************************\n\n' ) #Set up a temp dem, and then do initial addition of ED change to old DEM. This mapcalc statement first checks the amount of erodable soil in a given cell against the amount of erosion calculated, and keeps the cell from eroding past this amount (if there is soil, then if the amount of erosion is more than the amount of soil, just remove all the soil and stop, else remove the amount of caclulated erosion. It also runs an error catch that checks to make sure that soil depth is not negative (could happen, I suppose), and if it is, corrects it). temp_dem = '%stemp_dem%04d' % (p, o) grass.mapcalc( '${temp_dem}=eval(x=if(${old_soil} > 0.0 && (-1*${netchange}) <= ${old_soil}, ${netchange}, if((-1*${netchange}) > ${old_soil}, (-1*${old_soil}), 0)), ${old_dem} + x)', temp_dem=temp_dem, old_soil=old_soil, old_dem=old_dem, netchange=netchange) #Do patch-job to catch the shrinking edge problem (the edge cells have no upstream cell, so get turned null in the calculations in step 4) grass.run_command('r.patch', quiet=True, input=temp_dem + ',' + old_dem, output=new_dem) #Set colors for elevation map to match other dems and then get rid of the temp dem grass.run_command('r.colors', quiet=True, map=new_dem, rast=os.getenv("GIS_OPT_elev")) grass.run_command('g.remove', quiet=True, rast=temp_dem) #calculate the new soildepth map and set colors grass.mapcalc( '${new_soil}=if ((${new_dem} - ${initbdrk}) < 0, 0, (${new_dem} - ${initbdrk}))', new_soil=new_soil, new_dem=new_dem, initbdrk=initbdrk) grass.run_command('r.colors', quiet=True, map=new_soil, rules=sdcolors.name) grass.message( '\n*************************\n Year %s -- ' % o + 'step 6: writing stats to output file\n *************************\n\n') #Finish gathering stats (just need the soil depth stats now) soilstats = {} soilstats = grass.parse_command('r.univar', flags='ge', map=new_soil, percentile='99') #Write stats to a new line in the stats file #HEADER of the file should be: "Year,,Mean Erosion,Standard Deviation Erosion,Minimum Erosion,First Quartile Erosion,Median Erosion,Third Quartile Erosion,Maximum Erosion,Original Un-smoothed Maximum Erosion,,Mean Deposition,Standard Deviation Deposition,Minimum Deposition,First Quartile Deposition,Median Deposition,Third Quartile Deposition,Maximum Deposition,Original Un-smoothed Maximum Deposition,,Mean Soil Depth,Standard Deviation Soil Depth,Minimum Soil Depth,First Quartile Soil Depth,Median Soil Depth,Third Quartile Soil Depth,Maximum Soil Depth' grass.message('Outputing stats to textfile: ' + q) f.write('\n%s' % o + ',,' + erosstats1['mean'] + ',' + erosstats1['stddev'] + ',' + erosstats1['max'] + ',' + erosstats1['third_quartile'] + ',' + erosstats1['median'] + ',' + erosstats1['first_quartile'] + ',' + erosstats1['min'] + ',' + minimum + ',,' + depostats1['mean'] + ',' + depostats1['stddev'] + ',' + depostats1['min'] + ',' + depostats1['first_quartile'] + ',' + depostats1['median'] + ',' + depostats1['third_quartile'] + ',' + depostats1['max'] + ',' + maximum + ',,' + soilstats['mean'] + ',' + soilstats['stddev'] + ',' + soilstats['min'] + ',' + soilstats['first_quartile'] + ',' + soilstats['median'] + ',' + soilstats['third_quartile'] + ',' + soilstats['max']) #Clean up temporary maps if os.getenv("GIS_FLAG_k") == "1": grass.message('\nTemporary maps will NOT be deleted!!!!\n') else: grass.message('\nCleaning up temporary maps...\n\n') if os.getenv("GIS_FLAG_s") == "1": grass.message('Keeping Slope map.') else: grass.run_command('g.remove', quiet=True, rast=slope) if os.getenv("GIS_FLAG_d") == "1": grass.message('Not keeping Soil Depth map.') grass.run_command('g.remove', quiet=True, rast=old_soil) #check if this is the last year and remove the "new-soil" map too if (o == int(os.getenv("GIS_OPT_number"))): grass.run_command('g.remove', quiet=True, rast=new_soil) else: #check if this is the first year, and if so, remove the temporary "soildepths_init" map if (o == 1): grass.run_command('g.remove', quiet=True, rast=old_soil) if (os.getenv("GIS_FLAG_e") == "1"): grass.message( 'Keeping Excess Transport Capacity (divergence) maps for all processes.' ) else: if (os.getenv("GIS_FLAG_1") == "1"): grass.run_command('g.remove', quiet=True, rast=qsxdx4 + ',' + qsydy4 + ',' + qsxdx2 + ',' + qsydy2 + ',' + qsxdx3 + ',' + qsydy3 + ',' + qsd1) else: grass.run_command('g.remove', quiet=True, rast=qsxdx4 + ',' + qsydy4 + ',' + qsxdx2 + ',' + qsydy2 + ',' + qsxdx3 + ',' + qsydy3 + ',' + qsxdx1 + ',' + qsydy1) if (os.getenv("GIS_FLAG_t") == "1"): grass.message('Keeping Transport Capacity maps for all processes.') else: if (os.getenv("GIS_FLAG_1") == "1"): grass.run_command('g.remove', quiet=True, rast=qsx4 + ',' + qsy4 + ',' + qsx2 + ',' + qsy2 + ',' + qsx3 + ',' + qsy3 + ',' + qs1) else: grass.run_command('g.remove', quiet=True, rast=qsx4 + ',' + qsy4 + ',' + qsx2 + ',' + qsy2 + ',' + qsx3 + ',' + qsy3 + ',' + qsx1 + ',' + qsy1) if (os.getenv("GIS_FLAG_r") == "1"): grass.message('Not keeping an Erosion and Deposition rate map.') grass.run_command('g.remove', quiet=True, rast=netchange) grass.run_command('g.remove', quiet=True, rast=flowdir + ',' + flowacc + ',' + aspect) sdcolors.close() nccolors.close() grass.message('\n*************************\nDone with Year %s ' % o + '\n*************************\n')
# Cortar todos os rasters mundiais só para região neotropical # 2. Slope # Import folder_path = r'H:\_neojaguardatabase\Envdatabase\1km\World\Earthenv_topography\Slope' os.chdir(folder_path) # Change to this folder grass.run_command('r.import', input = 'slope_1KMmn_SRTM.tif', output = 'Slope_mn_SRTM_1km_tif_exp', overwrite = True) grass.run_command('r.import', input = 'slope_1KMmd_SRTM.tif', output = 'Slope_md_SRTM_1km_tif_exp', overwrite = True) # Region of study grass.run_command('g.region', rast = map_for_define_region, res = '0:00:30', flags = 'ap') # res = 1km # Cut grass.mapcalc('Slope_mn_SRTM_1km_neotropic_tif_exp = Slope_mn_SRTM_1km_tif_exp', overwrite = True) grass.mapcalc('Slope_md_SRTM_1km_neotropic_tif_exp = Slope_md_SRTM_1km_tif_exp', overwrite = True) #3. Human footprint # Import folder_path = r'H:\_neojaguardatabase\Envdatabase\1km\World\WCS_Humanfootprint\HumanFootprintv2\Dryadv3\Maps' os.chdir(folder_path) # Change to this folder grass.run_command('r.import', input = 'HFP2009_wgs84.tif', output = 'HFP2009_wgs84_1km_tif_exp', overwrite = True) grass.run_command('r.import', input = 'HFP1993_wgs84.tif', output = 'HFP1993_wgs84_1km_tif_exp', overwrite = True) # Region of study grass.run_command('g.region', rast = map_for_define_region, res = '0:00:30', flags = 'ap') # Cut grass.mapcalc('HFP2009_wgs84_1km_neotropic_tif_exp = HFP2009_wgs84_1km_tif_exp', overwrite = True) grass.mapcalc('HFP1993_wgs84_1km_neotropic_tif_exp = HFP1993_wgs84_1km_tif_exp', overwrite = True)
def run_trails(real_elev, scanned_elev, eventHandler, env, **kwargs): resulting = "trails1_slopedir" before = 'scan_saved' #env_crop = get_environment(raster=real_elev, n='n-100', s='s+100', e='e-100', w='w+100') analyses.change_detection(before=before, after=scanned_elev, change='change', height_threshold=[60, 335], cells_threshold=[3, 100], add=True, max_detected=10, debug=True, env=env) points = {} # start and end data = gscript.read_command('v.out.ascii', input='trails1_points', type='point', format='point', env=env).strip() c1, c2 = data.splitlines() c1 = c1.split('|') c2 = c2.split('|') points[0] = (float(c1[0]), float(c1[1])) points[1] = (float(c2[0]), float(c2[1])) # detected points points_raw = gscript.read_command('v.out.ascii', input='change', type='point', format='point').strip().split() i = 2 for point in points_raw: point = point.split('|') point = (float(point[0]), float(point[1])) points[i] = point i += 1 length = len(points) if length == 2: gscript.mapcalc("{} = null()".format(resulting), env=env) event = updateProfile(points=[]) eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event) return # distance matrix D = [] for i in range(length): D.append([0] * length) for p1 in range(0, length - 1): for p2 in range(p1 + 1, length): d = dist(points, p1, p2) D[p1][p2] = d D[p2][p1] = d # 0 distance for start and end to make sure it's always connected D[0][1] = 0 D[1][0] = 0 # solve solution = solve_tsp_numpy(D, optim_steps=10) # rearange solutions to start in start point ind1 = solution.index(0) ind2 = solution.index(1) if ind2 > ind1: solution = solution[::-1] ind = solution.index(0) solution = solution[ind:] + solution[:ind] # export line profile_points = [] line = 'L {} 1\n'.format(len(solution)) for i in solution: line += '{} {}\n'.format(points[i][0], points[i][1]) profile_points.append(points[i]) line += '1 1' gscript.write_command('v.in.ascii', input='-', stdin=line, output='line', format='standard', flags='n', env=env) env2 = get_environment(raster=before) # slope along line gscript.run_command('v.to.rast', input='line', type='line', output='line_dir', use='dir', env=env2) gscript.run_command('r.slope.aspect', elevation=before, slope='saved_slope', aspect='saved_aspect', env=env2) gscript.mapcalc( "slope_dir = abs(atan(tan({slope}) * cos({aspect} - {line_dir})))". format(slope='saved_slope', aspect='saved_aspect', line_dir='line_dir'), env=env2) # set new color table colors = [ '0 green', '5 green', '5 yellow', '12 yellow', '12 red', '90 red' ] gscript.write_command('r.colors', map='slope_dir', rules='-', stdin='\n'.join(colors), env=env2) # increase thickness gscript.run_command('r.grow', input='slope_dir', radius=2.1, output=resulting, env=env2) # update profile event = updateProfile(points=profile_points) eventHandler.postEvent(receiver=eventHandler.activities_panel, event=event) # copy results postfix = datetime.now().strftime('%H_%M_%S') prefix = 'trails1' gscript.run_command( 'g.copy', raster=['slope_dir', '{}_slope_dir_{}'.format(prefix, postfix)], vector=['line', '{}_line_{}'.format(prefix, postfix)], env=env)
def main(): """ Main program: get names for input, output suffix, options and flags """ input_list = options["image"].split(",") outputsuffix = options["suffix"] # Select model based on author author_year = options["model"] if "elvidge" in author_year: version = author_year[7:] author_year = "elvidge" else: version = None Model = MODELS[author_year] # ---------------------------- # flags citation = flags["c"] info = flags["i"] extend_region = flags["x"] timestamps = not (flags["t"]) zero = flags["z"] null = flags["n"] # either zero or null, not both --- FixMe! ### evaluation = flags["e"] shell = flags["g"] global temporary_maps temporary_maps = [] msg = "|i Inter-satellite calibration of DMSP-OLS Nighttime Stable " "Lights" g.message(msg) del msg """Temporary Region and Files""" if extend_region: grass.use_temp_region() # to safely modify the region tmpfile = grass.basename(grass.tempfile()) tmp = "tmp." + tmpfile """Loop over list of input images""" for image in input_list: satellite = image[0:3] year = image[3:7] """If requested, match region to input image""" if extend_region: run("g.region", rast=image) # ## FixMe? msg = "\n|! Matching region extent to map {name}" msg = msg.format(name=image) g.message(msg) del msg elif not extend_region: grass.warning(_("Operating on current region")) """Retrieve coefficients""" msg = "\n|> Calibrating average visible Digital Number values " g.message(msg) del msg # if "version" == True use Elvidge, else use Liu2012 or Wu2013 args = (satellite, year, version) if version else (satellite, year) model_parameters = retrieve_model_parameters(Model, *args) # # print model's generic equation? # if info: # print this # print that # split parameters in usable variables citation_string, coefficients, r2, mapcalc_formula = model_parameters msg = "|>>> Regression coefficients: " + str(coefficients) msg += "\n" + "|>>> " + r2 g.message(msg) del msg # Temporary Map tmp_cdn = "{prefix}.Calibrated".format(prefix=tmp) temporary_maps.append(tmp_cdn) """Formula for mapcalc""" equation = "{out} = {inputs}" calibration_formula = equation.format(out=tmp_cdn, inputs=mapcalc_formula) # alternatives if zero: zcf = "{out} = if(Input == 0, 0, {formula})" calibration_formula = zcf.format(out=tmp_cdn, formula=mapcalc_formula) msg = "\n|i Excluding zero cells from the analysis" g.message(msg) del msg elif null: ncf = "{out} = if(Input == 0, null(), {formula})" calibration_formula = ncf.format(out=tmp_cdn, formula=mapcalc_formula) msg = "\n|i Setting zero cells to NULL" g.message(msg) del msg # Compress even more? ----------------------------------------------- # if zero or null: # zero = 0 if zero else ('null()') # equation = "{out} = if(Input == 0, {zn}, {formula})" # calibration_formula = equation.format(out=tmp_cdn, zero, formula=mapcalc_formula) # ----------------------------------------------- Compress even more? # replace the "dummy" string... calibration_formula = calibration_formula.replace("Input", image) """Calibrate""" if info: msg = "\n|i Mapcalc formula: {formula}" g.message(msg.format(formula=mapcalc_formula)) del msg grass.mapcalc(calibration_formula, overwrite=True) """Transfer timestamps, if any""" if timestamps: try: datetime = grass.read_command("r.timestamp", map=image) run("r.timestamp", map=tmp_cdn, date=datetime) msg = "\n|i Timestamping: {stamp}".format(stamp=datetime) g.message(msg) except CalledModuleError: grass.fatal( _("\n|* Timestamp is missing! " "Please add one to the input map if further times series " "analysis is important. " "If you don't need it, you may use the -t flag.")) else: grass.warning( _("As requested, timestamp transferring not attempted.")) # ------------------------------------------------------------------------- # add timestamps and register to spatio-temporal raster data set # ------------------------------------------------------------------------- # ToDo -- borrowed from r.sun.daily # - change flag for "don't timestamp", see above # - use '-t' for temporal, makes more sense # - adapt following # temporal = flags['t'] # if temporal: # core.info(_("Registering created maps into temporal dataset...")) # import grass.temporal as tgis # def registerToTemporal(basename, suffixes, mapset, start_day, day_step, # title, desc): # """ # Register daily output maps in spatio-temporal raster data set # """ # maps = ','.join([basename + suf + '@' + mapset for suf in suffixes]) # tgis.open_new_stds(basename, type='strds', temporaltype='relative', # title=title, descr=desc, semantic='sum', # dbif=None, overwrite=grass.overwrite()) # tgis.register_maps_in_space_time_dataset(type='rast', # name=basename, maps=maps, # start=start_day, end=None, # unit='days', # increment=day_step, # dbif=None, interval=False) """Normalised Difference Index (NDI), if requested""" ndi = float() if evaluation: # total light indices for input, tmp_cdn images tli_image = total_light_index(image) tli_tmp_cdn = total_light_index(tmp_cdn) # build ndi = normalised_difference_index(tli_image, tli_tmp_cdn) # report if -g if shell: msg = "ndi={index}".format(index=round(ndi, 3)) g.message(msg) del msg # else, report else: msg = "\n|i Normalised Difference Index for {dn}: {index}" msg = msg.format(dn=image, index=round(ndi, 3)) g.message(msg) del msg """Strings for metadata""" history_calibration = "Regression model: " history_calibration += mapcalc_formula history_calibration += "\n\n" if ndi: history_calibration += "NDI: {ndi}".format(ndi=round(ndi, 10)) title_calibration = "Calibrated DMSP-OLS Stable Lights" description_calibration = ("Inter-satellite calibrated average " "Digital Number values") units_calibration = "Digital Numbers (Calibrated)" source1_calibration = citation_string source2_calibration = "" # history entry run( "r.support", map=tmp_cdn, title=title_calibration, units=units_calibration, description=description_calibration, source1=source1_calibration, source2=source2_calibration, history=history_calibration, ) """Add suffix to basename & rename end product""" name = "{prefix}.{suffix}" name = name.format(prefix=image.split("@")[0], suffix=outputsuffix) calibrated_name = name run("g.rename", rast=(tmp_cdn, calibrated_name)) temporary_maps.remove(tmp_cdn) """Restore previous computational region""" if extend_region: grass.del_temp_region() g.message("\n|! Original Region restored") """Things left to do...""" if citation: msg = "\n|i Citation: {string}".format(string=citation_string) g.message(msg) del msg
def test__mapcalc__add(): core.mapcalc("test_c = test_a + test_b", quite=True, overwrite=True)
def main (): #import bands atmospherically corrected using arcsi (scale factor 1000 instead of 10000) ############################################# # INPUT ############################################# #temporary map names global tmp, t tmp = {} t = True mapset = gscript.gisenv()['MAPSET'] # prepare temporary map raster names processid = "%.2f" % time.time() processid = processid.replace(".", "_") tmp["base_M"] = "base_M_" + processid tmp["cloud_v"] = "cloud_v_" + processid tmp["shadow_temp_v"] = "shadow_temp_v_" + processid tmp["shadow_temp_mask"] = "shadow_temp_mask_" + processid tmp["centroid"] = "centroid_" + processid tmp["dissolve"] = "dissolve_" + processid tmp["delcat"] = "delcat_" + processid tmp["addcat"] = "addcat_" + processid tmp["cl_shift"] = "cl_shift_" + processid tmp["overlay"] = "overlay_" + processid #check temporary map names are not existing maps for key, value in tmp.items(): if gscript.find_file(value, element = 'vector', mapset = mapset)['file']: gscript.fatal(_("Temporary vector map <%s> already exists.") % value) if gscript.find_file(value, element = 'cell', mapset = mapset)['file']: gscript.fatal(_("Temporary raster map <%s> already exists.") % value) #input file mtd_file = '/home/roberta/remote/Progetti_convegni/ricerca/2015_2018_PhD_roberta/sentinel2/MTD_TL.xml' ####change MTD_TL file path!!!#### b1 = 'blu' b2 = 'green' b3 = 'red' b4 = 'nir' b5 = 'nir8a' b7 = 'swir11' b8 = 'swir12' f = 'float' bands = [b1, b2, b3, b4, b5, b7, b8] f_bands = [] cloud_def = 'cloud_def' shadow_temp = 'shadow_temp' scale_fac = 1000 cloud_clean_T = 50000 shadow_clean_T = 10000 raster_max = [] cloud_mask = 'cloud_mask' shadow_mask = 'shadow_mask' gscript.run_command('g.region', rast=b1, flags='pa') for b in bands: gscript.mapcalc('{r} = 1.0 * ({a})/{c}'.format(r="%s_%s" % (b, f), a=b, c=scale_fac), overwrite=True) f_bands.append ("%s_%s" % (b, f)) gscript.message('--- All bands are converted to float and the quantification value has been applied ---') #print f_bands for fb in f_bands: stats = gscript.parse_command('r.univar', flags='g', map=fb) raster_max.append (float(stats['max'])) #print raster_max gscript.message('--- Statistics have been computed! ---') #### start of Clouds detection (some rules from litterature)### first_rule = '((%s > (0.08*%s)) && (%s > (0.08*%s)) && (%s > (0.08*%s)))' % (f_bands[0], raster_max[0], f_bands[1], raster_max[1], f_bands[2], raster_max[2]) second_rule = '((%s < ((0.08*%s)*1.5)) && (%s > %s*1.3))' % (f_bands[2], raster_max[2], f_bands[2], f_bands[6]) third_rule = '((%s < (0.1*%s)) && (%s < (0.1*%s)))' % (f_bands[5], raster_max[5], f_bands[6], raster_max[6]) fourth_rule = '(if(%s == max(%s, 2 * %s, 2 * %s, 2 * %s)))' % (f_bands[4], f_bands[4], f_bands[0], f_bands[1], f_bands[2]) fifth_rule = '(%s > 0.2)' % (f_bands[0]) cloud_rules = '(%s == 1) && (%s == 0) && (%s == 0) && (%s == 0) && (%s == 1)' % (first_rule, second_rule, third_rule, fourth_rule, fifth_rule) expr_c = '%s = if( %s, 0, null( ) )' % (cloud_def, cloud_rules) gscript.mapcalc( expr_c, overwrite=True) #print expr gscript.run_command('r.to.vect', input=cloud_def, output=tmp["cloud_v"], type='area', flags='s', overwrite=True) gscript.run_command('v.clean', input=tmp["cloud_v"], output=cloud_mask, tool='rmarea', threshold=cloud_clean_T, overwrite=True) ### end of Clouds detection #### ### start of shadows detection ### sixth_rule = '(((%s > %s) && (%s < %s) && (%s < 0.1) && (%s < 0.1)) || ((%s < %s) && (%s < %s) && (%s < 0.1) && (%s < 0.1) && (%s < 0.1)))' % (f_bands[0], f_bands[6], f_bands[0], f_bands[3], f_bands[0], f_bands[6], f_bands[0], f_bands[6], f_bands[0], f_bands[3], f_bands[0], f_bands[6], f_bands[3]) seventh_rule = '(%s - %s)' % (f_bands[1], f_bands[0]) shadow_rules = '((%s == 1) && (%s < 0.007))' % (sixth_rule, seventh_rule) expr_s = '%s = if( %s, 0, null( ) )' % (shadow_temp, shadow_rules) gscript.mapcalc( expr_s, overwrite=True) gscript.run_command('r.to.vect', input=shadow_temp, output=tmp["shadow_temp_v"], type='area', flags='s', overwrite=True) gscript.run_command('v.clean', input=tmp["shadow_temp_v"], output=tmp["shadow_temp_mask"], tool='rmarea', threshold=shadow_clean_T, overwrite=True) ### end of shadows detection ### ##################################################################### # START shadows cleaning Procedure (remove shadows misclassification) ##################################################################### ### start shadow mask preparation ### gscript.message('--- start working! ---') gscript.run_command('v.centroids', input=tmp["shadow_temp_mask"], output=tmp["centroid"], overwrite=True, quiet=True) gscript.run_command('v.db.droptable', map=tmp["centroid"], flags='f') gscript.run_command('v.db.addtable', map=tmp["centroid"], columns='value') gscript.run_command('v.db.update', map=tmp["centroid"], layer=1, column='value', value=1) gscript.run_command('v.dissolve', input=tmp["centroid"], column='value', output=tmp["dissolve"], overwrite=True, quiet=True) gscript.run_command('v.category', input=tmp["dissolve"], type='point,line,boundary,centroid,area,face,kernel', output=tmp["delcat"], option='del', cat=-1, overwrite=True, quiet=True) gscript.run_command('v.category', input=tmp["delcat"], type='centroid,area', output=tmp["addcat"], option='add', overwrite=True, quiet=True) gscript.run_command('v.db.droptable', map=tmp["addcat"], flags='f') gscript.run_command('v.db.addtable', map=tmp["addcat"], columns='value') ### end shadow mask preparation ### ### start cloud mask preparation ### gscript.run_command('v.db.droptable', map=cloud_mask, flags='f') gscript.run_command('v.db.addtable', map=cloud_mask, columns='value') ### end cloud mask preparation ### ### shift cloud mask using dE e dN ### # start reading mean sun zenith and azimuth from xml file to compute dE and dN automatically # xml_tree = et.parse(mtd_file) root = xml_tree.getroot() ZA = [] for elem in root[1]: for subelem in elem[1]: ZA.append (subelem.text) #print ZA z = float(ZA[0]) a = float(ZA[1]) gscript.message('--- the mean sun Zenith is: %.3f deg ---'% z) gscript.message('--- the mean sun Azimuth is: %.3f deg ---'% a) #print Ze #print Az #print z #print a # stop reading mean sun zenith and azimuth from xml file to compute dE and dN automatically # H = 1000 dH = 100 HH = [] dE = [] dN = [] AA = [] while H <= 4000: z_deg_to_rad = math.radians(z) tan_Z = math.tan(z_deg_to_rad) #print tan_Z a_deg_to_rad = math.radians(a) cos_A = math.cos(a_deg_to_rad) sin_A = math.sin(a_deg_to_rad) #print cos_A #print sin_A E_shift = (-H * tan_Z * sin_A) N_shift = (-H * tan_Z * cos_A) dE.append (E_shift) #print dE dN.append (N_shift) #print dN HH.append(H) H = H + dH gscript.run_command('v.transform', input=cloud_mask, output=tmp["cl_shift"], xshift=E_shift, yshift=N_shift, overwrite=True, quiet=True) gscript.run_command('v.overlay', ainput=tmp["addcat"], binput=tmp["cl_shift"], operator='and', output=tmp["overlay"], overwrite=True, quiet=True) gscript.run_command('v.db.addcolumn', map=tmp["overlay"], columns='area double') area = gscript.read_command('v.to.db', map=tmp["overlay"], option='area', columns='area', flags='c') area2 = gscript.parse_key_val(area, sep='|') AA.append (float(area2['total area'])) #print AA #print HH #print dE #print dN index_maxAA = numpy.argmax(AA) gscript.run_command('v.transform', input=cloud_mask, output=tmp["cl_shift"], xshift=dE[index_maxAA], yshift=dN[index_maxAA], overwrite=True, quiet=True) gscript.run_command('v.select', ainput=tmp["addcat"], atype='point,line,boundary,centroid,area', binput=tmp["cl_shift"], btype='point,line,boundary,centroid,area', output=shadow_mask, operator='intersects', overwrite=True, quiet=True) gscript.message('--- the estimated clouds height is: %d m ---'% HH[index_maxAA]) gscript.message('--- the estimated east shift is: %.2f m ---'% dE[index_maxAA]) gscript.message('--- the estimated north shift is: %.2f m ---'% dN[index_maxAA])
def main(): options, flags = g.parser() Blue = options['blue_band'] Green = options['green_band'] Red = options['red_band'] NIR = options['nir_band'] SWIR = options['band_for_correction'] Calibration_points = options['calibration_points'] Area_of_interest = options['area_of_interest'] Additional_band1 = options['additional_band1'] Additional_band2 = options['additional_band2'] Additional_band3 = options['additional_band3'] Additional_band4 = options['additional_band4'] bathymetry = options['depth_estimate'] tide_height = options['tide_height'] calibration_column = options['calibration_column'] bisquare = flags['b'] fixed_GWR = flags['f'] res = g.parse_command('g.region', raster=Green, flags='g') g.run_command('v.to.rast', input=Calibration_points, type='point', use='attr', attribute_column=calibration_column, output='tmp_Calibration_points') # hull generation from calibration depth points g.run_command('v.hull', input=Calibration_points, output='tmp_hull', overwrite=True) # buffer the hull to ceate a region for including all calibration points g.run_command('v.buffer', input='tmp_hull', output='tmp_buffer', distance=float(res['nsres']), overwrite=True) if tide_height: cal = g.parse_command('r.univar', map='tmp_Calibration_points', flags='g') if float(cal['min']) >= 0: t = float(tide_height) g.mapcalc(exp="{d}=({d}+float({t}))".format(d='tmp_Calibration_points', t=t), overwrite=True) if float(cal['min']) < 0: t = float(tide_height) * -1 g.mapcalc(exp="{d}=({d}+float({t}))".format(d='tmp_Calibration_points', t=t), overwrite=True) g.mapcalc(exp="{tmp_ratio}=({Green}/{SWIR})".format(tmp_ratio='tmp_ratio', Green=Green, SWIR=SWIR)) g.mapcalc(exp="{tmp_NDVI}=float({NIR}-{Red})/float({NIR}+{Red})" .format(tmp_NDVI='tmp_NDVI', NIR=NIR, Red=Red)) g.mapcalc(exp="{tmp_water}=if({tmp_ratio} < 1, null(), if({tmp_NDVI} <" "0, {tmp_ratio}, null()))".format(tmp_NDVI='tmp_NDVI', tmp_water='tmp_water', tmp_ratio='tmp_ratio')) g.run_command('r.mask', raster='tmp_water', overwrite=True) li = [Green, Additional_band1, Additional_band2, Additional_band3, Additional_band4, Blue, Red] for i in li: j, sep, tail = i.partition('@') tmp_ = RasterRow(str(i)) if tmp_.exist() is False: continue g.message("Ditermining minimum value for %s" % i) g.run_command('g.region', vector=Calibration_points) # To ignore zero values g.mapcalc(exp="{tmp_b}=if({x}>1, {x},null())".format(tmp_b='tmp_b', x=str(i)), overwrite=True) tmp_AOI = g.parse_command('r.univar', map='tmp_b', flags='g') tmp_AOI_min = float(tmp_AOI['min']) g.run_command('g.region', raster=Green) try: g.mapcalc(exp="{tmp_deep}=if({tmp_band}<{band_min}, {tmp_band}," "null())".format(tmp_deep='tmp_deep', band_min=tmp_AOI_min, tmp_band=str(i)), overwrite=True) g.run_command('r.mask', raster='tmp_deep', overwrite=True) tmp_coe = g.parse_command('r.regression.line', mapx=SWIR, mapy=str(i), flags='g') g.message("Deep water ditermination for %s" % i) if Area_of_interest: g.run_command('r.mask', vector=Area_of_interest, overwrite=True) g.run_command('g.region', vector=Area_of_interest) else: g.run_command('r.mask', vector='tmp_buffer', overwrite=True) g.run_command('g.region', vector=Calibration_points) g.mapcalc(exp="{tmp_crct}=log({tmp_band}-{a}-{b}*{SWIR})" .format(tmp_crct='tmp_crct' + str(j), tmp_band=str(i), a=float(tmp_coe['a']), b=float(tmp_coe['b']), SWIR=SWIR), overwrite=True) g.run_command('r.mask', raster='tmp_water', overwrite=True) g.mapcalc("{tmp_crctd} = ({tmp_crct} * 1)" .format(tmp_crct='tmp_crct'+str(j), tmp_crctd='tmp_crctd' + str(j))) except: g.message("Cannot find deep water pixels") if Area_of_interest: g.run_command('r.mask', vector=Area_of_interest, overwrite=True) g.run_command('g.region', vector=Area_of_interest) else: g.run_command('r.mask', vector='tmp_buffer', overwrite=True) g.run_command('g.region', vector=Calibration_points) g.mapcalc(exp="{tmp_crct}=log({tmp_band}-{a}-{b}*{SWIR})" .format(tmp_crct='tmp_crct' + str(j), tmp_band=str(i), a=float(tmp_coe['a']), b=float(tmp_coe['b']), SWIR=SWIR), overwrite=True) g.run_command('r.mask', raster='tmp_water', overwrite=True) g.mapcalc("{tmp_crctd} = ({tmp_crct} * 1)" .format(tmp_crct='tmp_crct'+str(j), tmp_crctd='tmp_crctd' + str(j))) crctd_lst.append('tmp_crctd' + str(j)) if fixed_GWR: if not g.find_program('r.gwr', '--help'): g.run_command('g.extension', extension='r.gwr') if bisquare: g.message("Calculating optimal bandwidth using bisqare kernel...") bw = g.parse_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', kernel='bisquare', flags='ge') g.message("Running Fixed-GWR using bisqare kernel...") g.run_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', estimates='tmp_bathymetry', kernel='bisquare', bandwidth=int(bw['estimate'])) else: g.message("Calculating optimal bandwidth using gaussian kernel...") bw = g.parse_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', flags='ge') g.message("Running Fixed-GWR using gaussian kernel...") g.run_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', estimates='tmp_bathymetry', bandwidth=int(bw['estimate'])) else: global r global predict try: # For GWmodel in R r = g.tempfile() r_file = open(r, 'w') libs = ['GWmodel', 'data.table', 'rgrass7', 'rgdal', 'raster'] for i in libs: install = 'if(!is.element("%s", installed.packages()[,1])){\n' % i install += "cat('\\n\\nInstalling %s package from CRAN\n')\n" % i install += "if(!file.exists(Sys.getenv('R_LIBS_USER'))){\n" install += "dir.create(Sys.getenv('R_LIBS_USER'), recursive=TRUE)\n" install += ".libPaths(Sys.getenv('R_LIBS_USER'))}\n" install += 'install.packages("%s", repos="http://cran.us.r-' \ 'project.org")}\n' % i r_file.write(install) libraries = 'library(%s)\n' % i r_file.write(libraries) Green_new, sep, tail = Green.partition('@') r_file.write('grass_file = readRAST("tmp_crctd%s")\n' % Green_new) r_file.write('raster_file = raster(grass_file)\n') frame_file = 'pred = as.data.frame(raster_file,na.rm = TRUE,xy = TRUE)\n' r_file.write(frame_file) for i in li: j, sep, tail = i.partition('@') Green_new, sep, tail = Green.partition('@') tmp_ = RasterRow(str(i)) if tmp_.exist() is False: continue r_file.write('grass_file = readRAST("tmp_crctd%s")\n' % j) r_file.write('raster_file = raster(grass_file)\n') r_file.write('frame_pred%s = as.data.frame(raster_file, na.rm = TRUE,' 'xy = TRUE)\n' % j) pred_file = 'frame_pred_green=data.frame(frame_pred%s)\n' % Green_new pred_file += 'pred=merge(pred, frame_pred%s)\n' % j r_file.write(pred_file) # For reference_file repeat with MASK g.run_command('r.mask', raster='tmp_Calibration_points', overwrite=True) r_file.write('grass_file=readRAST("%s")\n' % 'tmp_Calibration_points') r_file.write('raster_file = raster(grass_file)\n') frame_file = 'calib = as.data.frame(raster_file,na.rm = TRUE ,' \ 'xy = TRUE)\n' r_file.write(frame_file) for i in li: j, sep, tail = i.partition('@') tmp_ = RasterRow(str(i)) if tmp_.exist() is False: continue r_file.write('grass_file = readRAST("tmp_crctd%s")\n' % j) r_file.write('raster_file = raster(grass_file)\n') r_file.write('frame_ref%s = as.data.frame(raster_file,na.rm = TRUE,' \ 'xy = TRUE)\n' % j) ref_file = 'calib = merge(calib, frame_ref%s)\n' % j r_file.write(ref_file) g.run_command('g.remove', type='raster', pattern='MASK', flags='f') ref_file = 'Rapid_ref.sdf=SpatialPointsDataFrame(calib[,1:2],calib)\n' ref_file += 'Rapid_pred.sdf=SpatialPointsDataFrame(pred[,1:2],' \ 'pred)\n' ref_file += 'DM_Rapid_ref.sdf=gw.dist(dp.locat=coordinates' \ '(Rapid_ref.sdf))\n' r_file.write(ref_file) l = [] predict = g.read_command("g.tempfile", pid=os.getpid()).strip() + '.txt' # Join the corrected bands in to a string le = len(crctd_lst) for i in crctd_lst: l.append(i) k = '+'.join(l) if bisquare: ref_flag = "cat('\nCalculating optimal bandwidth using " \ "bisquare kernel..\n')\n" ref_flag += 'BW_Rapid_ref.sdf=bw.gwr(tmp_Calibration_points~%s,' \ 'data=Rapid_ref.sdf, kernel="bisquare",' \ 'adaptive=TRUE, dMat=DM_Rapid_ref.sdf)\n' % k ref_flag += "cat('\nCalculating euclidean distance\n')\n" ref_flag += 'DM_Rapid_pred.sdf=gw.dist(dp.locat=coordinates' \ '(Rapid_ref.sdf), rp.locat=coordinates' \ '(Rapid_pred.sdf))\n' ref_flag += "cat('\nRunning A-GWR using bisquare kernel\n')\n" ref_flag += 'GWR_Rapid_pred.sdf=gwr.predict(tmp_Calibration_poi' \ 'nts~%s,data=Rapid_ref.sdf, bw = BW_Rapid_ref.sdf,' \ 'predictdata = Rapid_pred.sdf, kernel = "bisquare",' \ 'adaptive = TRUE, dMat1 = DM_Rapid_pred.sdf,' \ 'dMat2 = DM_Rapid_ref.sdf)\n' % k r_file.write(ref_flag) if not bisquare: ref_fla = "cat('\nCalculating optimal bandwidth using " \ "gaussian kernel..\n')\n" ref_fla += 'BW_Rapid_ref.sdf=bw.gwr(tmp_Calibration_points~%s,' \ 'data=Rapid_ref.sdf, kernel="gaussian",' \ 'adaptive=TRUE, dMat= DM_Rapid_ref.sdf)\n' % k ref_fla += "cat('\nCalculating euclidean distance\n')\n" ref_fla += 'DM_Rapid_pred.sdf=gw.dist(dp.locat=coordinates' \ '(Rapid_ref.sdf), rp.locat=coordinates' \ '(Rapid_pred.sdf))\n' ref_fla += "cat('\nRunning A-GWR using gaussian kernel\n')\n" ref_fla += 'GWR_Rapid_pred.sdf = gwr.predict(tmp_Calibration_poi' \ 'nts~%s,data=Rapid_ref.sdf, bw=BW_Rapid_ref.sdf,' \ 'predictdata = Rapid_pred.sdf, kernel = "gaussian",' \ 'adaptive = TRUE, dMat1 = DM_Rapid_pred.sdf,' \ 'dMat2 = DM_Rapid_ref.sdf)\n' % k r_file.write(ref_fla) ref_fil = 'Sp_frame = as.data.frame(GWR_Rapid_pred.sdf$SDF)\n' r_file.write(ref_fil) export = 'write.table(Sp_frame, quote=FALSE, sep=",",' \ '"%s")\n' % predict r_file.write(export) r_file.close() subprocess.check_call(['Rscript', r], shell=False) g.run_command('r.in.xyz', input=predict, output='tmp_bathymetry', skip=1, separator=",", x=(int(le) + 5), y=(int(le) + 6), z=(int(le) + 3), overwrite=True) except subprocess.CalledProcessError: g.message("Integer outflow... ") if not g.find_program('r.gwr', '--help'): g.run_command('g.extension', extension='r.gwr') if bisquare: g.message("Running Fixed-GWR using bisqare kernel...") bw = g.parse_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', kernel='bisquare', flags='ge') g.run_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', estimates='tmp_bathymetry', kernel='bisquare', bandwidth=int(bw['estimate'])) else: g.message("Running Fixed-GWR using gaussian kernel...") bw = g.parse_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', flags='ge') g.run_command('r.gwr', mapx=crctd_lst, mapy='tmp_Calibration_points', estimates='tmp_bathymetry', bandwidth=int(bw['estimate'])) tmp_rslt_ext = g.parse_command('r.univar', map='tmp_Calibration_points', flags='g') g.mapcalc(exp="{bathymetry}=if({tmp_SDB}>{max_}, null()," "if({tmp_SDB}<{min_}, null(), {tmp_SDB}))".format (tmp_SDB='tmp_bathymetry', bathymetry=bathymetry, max_=float(tmp_rslt_ext['max']), min_=float(tmp_rslt_ext['min'])))
def main(): global usermask, mapset, tmp_rmaps, tmp_vmaps input = options["input"] output = options["output"] tension = options["tension"] smooth = options["smooth"] method = options["method"] edge = int(options["edge"]) segmax = int(options["segmax"]) npmin = int(options["npmin"]) lambda_ = float(options["lambda"]) memory = options["memory"] quiet = True # FIXME mapset = grass.gisenv()["MAPSET"] unique = str(os.getpid()) # Shouldn't we use temp name? prefix = "r_fillnulls_%s_" % unique failed_list = ( list() ) # a list of failed holes. Caused by issues with v.surf.rst. Connected with #1813 # check if input file exists if not grass.find_file(input)["file"]: grass.fatal(_("Raster map <%s> not found") % input) # save original region reg_org = grass.region() # check if a MASK is already present # and remove it to not interfere with NULL lookup part # as we don't fill MASKed parts! if grass.find_file("MASK", mapset=mapset)["file"]: usermask = "usermask_mask." + unique grass.message(_("A user raster mask (MASK) is present. Saving it...")) grass.run_command("g.rename", quiet=quiet, raster=("MASK", usermask)) # check if method is rst to use v.surf.rst if method == "rst": # idea: filter all NULLS and grow that area(s) by 3 pixel, then # interpolate from these surrounding 3 pixel edge filling = prefix + "filled" grass.use_temp_region() grass.run_command("g.region", align=input, quiet=quiet) region = grass.region() ns_res = region["nsres"] ew_res = region["ewres"] grass.message(_("Using RST interpolation...")) grass.message(_("Locating and isolating NULL areas...")) # creating binary (0/1) map if usermask: grass.message(_("Skipping masked raster parts")) grass.mapcalc( '$tmp1 = if(isnull("$input") && !($mask == 0 || isnull($mask)),1,null())', tmp1=prefix + "nulls", input=input, mask=usermask, ) else: grass.mapcalc( '$tmp1 = if(isnull("$input"),1,null())', tmp1=prefix + "nulls", input=input, ) tmp_rmaps.append(prefix + "nulls") # restoring user's mask, if present # to ignore MASKed original values if usermask: grass.message(_("Restoring user mask (MASK)...")) try: grass.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) except CalledModuleError: grass.warning(_("Failed to restore user MASK!")) usermask = None # grow identified holes by X pixels grass.message(_("Growing NULL areas")) tmp_rmaps.append(prefix + "grown") try: grass.run_command( "r.grow", input=prefix + "nulls", radius=edge + 0.01, old=1, new=1, out=prefix + "grown", quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary map, restoring " "user mask if needed:")) # assign unique IDs to each hole or hole system (holes closer than edge distance) grass.message(_("Assigning IDs to NULL areas")) tmp_rmaps.append(prefix + "clumped") try: grass.run_command( "r.clump", input=prefix + "grown", output=prefix + "clumped", quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary map, restoring " "user mask if needed:")) # get a list of unique hole cat's grass.mapcalc( "$out = if(isnull($inp), null(), $clumped)", out=prefix + "holes", inp=prefix + "nulls", clumped=prefix + "clumped", ) tmp_rmaps.append(prefix + "holes") # use new IDs to identify holes try: grass.run_command( "r.to.vect", flags="v", input=prefix + "holes", output=prefix + "holes", type="area", quiet=quiet, ) except: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) tmp_vmaps.append(prefix + "holes") # get a list of unique hole cat's cats_file_name = grass.tempfile(False) grass.run_command( "v.db.select", flags="c", map=prefix + "holes", columns="cat", file=cats_file_name, quiet=quiet, ) cat_list = list() cats_file = open(cats_file_name) for line in cats_file: cat_list.append(line.rstrip("\n")) cats_file.close() os.remove(cats_file_name) if len(cat_list) < 1: grass.fatal(_("Input map has no holes. Check region settings.")) # GTC Hole is NULL area in a raster map grass.message(_("Processing %d map holes") % len(cat_list)) first = True hole_n = 1 for cat in cat_list: holename = prefix + "hole_" + cat # GTC Hole is a NULL area in a raster map grass.message(_("Filling hole %s of %s") % (hole_n, len(cat_list))) hole_n = hole_n + 1 # cut out only CAT hole for processing try: grass.run_command( "v.extract", input=prefix + "holes", output=holename + "_pol", cats=cat, quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) tmp_vmaps.append(holename + "_pol") # zoom to specific hole with a buffer of two cells around the hole to # remove rest of data try: grass.run_command( "g.region", vector=holename + "_pol", align=input, w="w-%d" % (edge * 2 * ew_res), e="e+%d" % (edge * 2 * ew_res), n="n+%d" % (edge * 2 * ns_res), s="s-%d" % (edge * 2 * ns_res), quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) # remove temporary map to not overfill disk try: grass.run_command( "g.remove", flags="fb", type="vector", name=holename + "_pol", quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) tmp_vmaps.remove(holename + "_pol") # copy only data around hole grass.mapcalc( "$out = if($inp == $catn, $inp, null())", out=holename, inp=prefix + "holes", catn=cat, ) tmp_rmaps.append(holename) # If here loop is split into two, next part of loop can be run in parallel # (except final result patching) # Downside - on large maps such approach causes large disk usage # grow hole border to get it's edge area tmp_rmaps.append(holename + "_grown") try: grass.run_command( "r.grow", input=holename, radius=edge + 0.01, old=-1, out=holename + "_grown", quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary map, restoring " "user mask if needed:")) # no idea why r.grow old=-1 doesn't replace existing values with NULL grass.mapcalc( '$out = if($inp == -1, null(), "$dem")', out=holename + "_edges", inp=holename + "_grown", dem=input, ) tmp_rmaps.append(holename + "_edges") # convert to points for interpolation tmp_vmaps.append(holename) try: grass.run_command( "r.to.vect", input=holename + "_edges", output=holename, type="point", flags="z", quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) # count number of points to control segmax parameter for interpolation: pointsnumber = grass.vector_info_topo(map=holename)["points"] grass.verbose(_("Interpolating %d points") % pointsnumber) if pointsnumber < 2: grass.verbose(_("No points to interpolate")) failed_list.append(holename) continue # Avoid v.surf.rst warnings if pointsnumber < segmax: use_npmin = pointsnumber use_segmax = pointsnumber * 2 else: use_npmin = npmin use_segmax = segmax # launch v.surf.rst tmp_rmaps.append(holename + "_dem") try: grass.run_command( "v.surf.rst", quiet=quiet, input=holename, elev=holename + "_dem", tension=tension, smooth=smooth, segmax=use_segmax, npmin=use_npmin, ) except CalledModuleError: # GTC Hole is NULL area in a raster map grass.fatal(_("Failed to fill hole %s") % cat) # v.surf.rst sometimes fails with exit code 0 # related bug #1813 if not grass.find_file(holename + "_dem")["file"]: try: tmp_rmaps.remove(holename) tmp_rmaps.remove(holename + "_grown") tmp_rmaps.remove(holename + "_edges") tmp_rmaps.remove(holename + "_dem") tmp_vmaps.remove(holename) except: pass grass.warning( _("Filling has failed silently. Leaving temporary maps " "with prefix <%s> for debugging.") % holename) failed_list.append(holename) continue # append hole result to interpolated version later used to patch into original DEM if first: tmp_rmaps.append(filling) grass.run_command("g.region", align=input, raster=holename + "_dem", quiet=quiet) grass.mapcalc( "$out = if(isnull($inp), null(), $dem)", out=filling, inp=holename, dem=holename + "_dem", ) first = False else: tmp_rmaps.append(filling + "_tmp") grass.run_command( "g.region", align=input, raster=(filling, holename + "_dem"), quiet=quiet, ) grass.mapcalc( "$out = if(isnull($inp), if(isnull($fill), null(), $fill), $dem)", out=filling + "_tmp", inp=holename, dem=holename + "_dem", fill=filling, ) try: grass.run_command( "g.rename", raster=(filling + "_tmp", filling), overwrite=True, quiet=quiet, ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring user " "mask if needed:")) # this map has been removed. No need for later cleanup. tmp_rmaps.remove(filling + "_tmp") # remove temporary maps to not overfill disk try: tmp_rmaps.remove(holename) tmp_rmaps.remove(holename + "_grown") tmp_rmaps.remove(holename + "_edges") tmp_rmaps.remove(holename + "_dem") except: pass try: grass.run_command( "g.remove", quiet=quiet, flags="fb", type="raster", name=( holename, holename + "_grown", holename + "_edges", holename + "_dem", ), ) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring " "user mask if needed:")) try: tmp_vmaps.remove(holename) except: pass try: grass.run_command("g.remove", quiet=quiet, flags="fb", type="vector", name=holename) except CalledModuleError: grass.fatal( _("abandoned. Removing temporary maps, restoring user mask if needed:" )) # check if method is different from rst to use r.resamp.bspline if method != "rst": grass.message(_("Using %s bspline interpolation") % method) # clone current region grass.use_temp_region() grass.run_command("g.region", align=input) reg = grass.region() # launch r.resamp.bspline tmp_rmaps.append(prefix + "filled") # If there are no NULL cells, r.resamp.bslpine call # will end with an error although for our needs it's fine # Only problem - this state must be read from stderr new_env = dict(os.environ) new_env["LC_ALL"] = "C" if usermask: try: p = grass.core.start_command( "r.resamp.bspline", input=input, mask=usermask, output=prefix + "filled", method=method, ew_step=3 * reg["ewres"], ns_step=3 * reg["nsres"], lambda_=lambda_, memory=memory, flags="n", stderr=subprocess.PIPE, env=new_env, ) stderr = grass.decode(p.communicate()[1]) if "No NULL cells found" in stderr: grass.run_command("g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True) p.returncode = 0 grass.warning( _("Input map <%s> has no holes. Copying to output without modification." ) % (input, )) except CalledModuleError: grass.fatal( _("Failure during bspline interpolation. Error message: %s" ) % stderr) else: try: p = grass.core.start_command( "r.resamp.bspline", input=input, output=prefix + "filled", method=method, ew_step=3 * reg["ewres"], ns_step=3 * reg["nsres"], lambda_=lambda_, memory=memory, flags="n", stderr=subprocess.PIPE, env=new_env, ) stderr = grass.decode(p.communicate()[1]) if "No NULL cells found" in stderr: grass.run_command("g.copy", raster="%s,%sfilled" % (input, prefix), overwrite=True) p.returncode = 0 grass.warning( _("Input map <%s> has no holes. Copying to output without modification." ) % (input, )) except CalledModuleError: grass.fatal( _("Failure during bspline interpolation. Error message: %s" ) % stderr) # restoring user's mask, if present: if usermask: grass.message(_("Restoring user mask (MASK)...")) try: grass.run_command("g.rename", quiet=quiet, raster=(usermask, "MASK")) except CalledModuleError: grass.warning(_("Failed to restore user MASK!")) usermask = None # set region to original extents, align to input grass.run_command( "g.region", n=reg_org["n"], s=reg_org["s"], e=reg_org["e"], w=reg_org["w"], align=input, ) # patch orig and fill map grass.message(_("Patching fill data into NULL areas...")) # we can use --o here as g.parser already checks on startup grass.run_command("r.patch", input=(input, prefix + "filled"), output=output, overwrite=True) # restore the real region grass.del_temp_region() grass.message(_("Filled raster map is: %s") % output) # write cmd history: grass.raster_history(output) if len(failed_list) > 0: grass.warning( _("Following holes where not filled. Temporary maps with are left " "in place to allow examination of unfilled holes")) outlist = failed_list[0] for hole in failed_list[1:]: outlist = ", " + outlist grass.message(outlist) grass.message(_("Done."))
def _getBarrier(self, fieldblock, barrier): formula = "$barrier = if(isnull($fieldblock),1,0)" g.mapcalc(formula, barrier=barrier, fieldblock=fieldblock, quiet=quiet) g.verbose('Raster map barrier is in "%s"' % barrier) return barrier